iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
0
自我挑戰組

從爬蟲到架站系列 第 5

Day 4: 從爬蟲到架站-傳送資料(1)

  • 分享至 

  • xImage
  •  

從Firebase取得資料

前面有介紹到如何連接Firebase,而連接的程式碼就放在app.py裡面

import flask
from flask import render_template, url_for, redirect, request, jsonify, Response 

app = flask.Flask(__name__)
app.config["DEBUG"] = True

cred = credentials.Certificate('path/to/serviceAccount.json')
firebase_admin.initialize_app(cred)

...

if __name__ == '__main__':
    app.run()

為了不讓app.py太過雜亂,所以我把取資料的程式碼獨立為db_connect.py,並且連同之前儲存資料的程式碼一起放進來。

取得資料的方法非常簡單,指定好collection和document後,使用get()就能取得,取出來的資料可以用to_dict()轉成dict,讓Python好處理。

db_connect.py

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

def get_hitter_stat(player_name):
    db = firestore.client()
    doc_ref = db.collection(u'打者').document(str(player_name))
    doc = doc_ref.get()
    if doc.exists:
        return doc.to_dict()
    else:
        return False
        
def store_month(data):
    db = firestore.client()
    batch = db.batch()
    for player in data:
        doc_ref = db.collection(u'打者').document(player['Name'])
        del player['Name']
        batch.update(doc_ref, {u'月份':player})
    batch.commit()

接著把db_connect.pyimport進app.py

前端設置

接著要先把index.html切出我要顯示出來的位置,首先選擇球員需要用兩個下拉式選單<select>,並用bootstrap稍微美化一下表單。

<form>
    <div class="row">
        <div class="form-group col-6">
            <select name="team" id="team" class="form-control">
                <option value="中信兄弟">中信兄弟</option>
                <option value="統一獅">統一獅</option>
                <option value="富邦悍將">富邦悍將</option>
                <option value="樂天桃猿">樂天桃猿</option>
            </select>
        </div>
        <div class="form-group col-6">
            <select name="player" id="player" class="form-control">
            </select>
        </div>
     </div>
</form>

並且我想要將這兩個下拉式選單連動,也就是當我選擇中信兄弟時,player的選單會顯示出中信兄弟的球員,這邊我需要用到select的onchange觸發ajax讓Flask傳球員名單過來,先寫一個js function。

function select_team(){
    let team = $('#team').val();
    $.ajax({
        type: 'POST',
        url:  "/select_team",
        data: {"team":team},
        success: function(result){
            $('#player').empty();
            $('#player').append($("<option/>", {
                value: '選擇球員',
                text: '選擇球員'
            }));
            for(let i = 0; i < result.length ;i++){
                $('#player').append($("<option/>",{
                    value: result[i],
                    text: result[i]
                }));
            }
        }
    });
}

這邊我用POST的方式,而data是前端必須傳給後端的資料,讓後端能判斷,empty很重要(de很久才想到),而for迴圈則是加入球員,前端的程式碼寫好了,接著回到app.py,我需要設置一個/select_team才能接起來。

app.py

from select_player import getplayer
@app.route('/select_team', methods=['POST'])
def select_team():
    team = request.form.getlist('team')
    player_list = getplayer(team[0])
    return jsonify(player_list)

getlist進來會是list

select_player.py

# coding: utf-8
import csv

def getplayer(team):
    with open('player_ID.csv', 'r',encoding='utf8') as csvfile:
        rows = csv.DictReader(csvfile)
        player_list = []
        if team == '中信兄弟':
            for row in rows:
                if row['Team ID'] == 'E02':
                    player_list.append(row['Name'])
        elif team == '統一獅':
            for row in rows:
                if row['Team ID'] == 'L01':
                    player_list.append(row['Name'])
        elif team == '富邦悍將':
            for row in rows:
                if row['Team ID'] == 'B04':
                    player_list.append(row['Name'])
        elif team == '樂天桃猿':
            for row in rows:
                if row['Team ID'] == 'AJL011':
                    player_list.append(row['Name'])

        return player_list

希望未來可以改進更好的寫法...

但是現在在第一次進網頁時,第二欄會是空的,我希望在載入好時能先執行一遍,這邊我用了ready來達成

$(document).ready(select_team());

現在已經將兩個下拉式選單連動,下一篇將會利用js取得選到的球員,並且傳相應的資料到前端。


上一篇
Day 3: 從爬蟲到架站-建置網站
下一篇
Day 5: 從爬蟲到架站-傳送資料(2)
系列文
從爬蟲到架站21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言