這篇主要是濃縮前面幾篇文章的內容,會用兩篇來帶過整個操作。
除了月份的數據,打者對左右投的數據也很重要,而左右投的數據也是在中職的官網可以查到,跟月份的url很像,月份是type=5,但是左右的數據是預設頁面,所以不用加type就可以用。
這邊有兩個選擇,可以跟月份的包在同一個function中,或是另外寫一個function,我選擇是寫在另一個function裡,主因是未來會將網站部屬到heroku中,heroku有一個動作不能超過30秒的限制,但就算用異步,在heroku上執行月份的爬蟲大概需要將近20秒,如果再包成同一個function可能會碰到30秒的限制。
crawl.py
async def send_habit_req(url, row):
res = await loop.run_in_executor(None, requests.get, url)
soup = BeautifulSoup(res.text, 'lxml')
info = soup.select('.display_a1')
vs_type = soup.select('.std_tb>tr>td')
if len(vs_type) < 30:
habit = {}
for i in range(10):
habit[info[i].text] = info[i+10].text
player = {'Name': row['Name'], 'Habit': {
vs_type[0].text.replace('.', '').replace('VS','vs'): habit}}
habit_result.append(player)
else:
right, left = {}, {}
for i in range(10):
right[info[i].text] = info[i+10].text
left[info[i].text] = info[i+20].text
player = {'Name':row['Name'],'Habit': {'vsRHP': right, 'vsLHP': left}}
habit_result.append(player)
def get_player_habit_stat():
player_habit_url = "http://www.cpbl.com.tw/players/apart.html?" # 左右打
with open('player_ID.csv', 'r', encoding='utf8') as csvfile:
rows = csv.DictReader(csvfile)
for row in rows:
player_habit_full_url = player_habit_url + 'player_id=' + \
str(row['ID']) + '&teamno=' + str(row['Team ID'])
task = loop.create_task(send_habit_req(player_habit_full_url, row))
tasks.append(task)
loop.run_until_complete(asyncio.wait(tasks))
store_habit(habit_result)
sotore_habit寫在
db_connect.py
裡面
這邊要注意的是某些選手可能會只有對到右投,所以在解析的時候要特別注意。
db_connect.py
def store_month(data):
db = firestore.client()
batch = db.batch()
for player in data:
doc_ref = db.collection(u'打者').document(player['Name'])
batch.update(doc_ref, {u'月份':player})
batch.commit()
儲存的方式也是一樣
存到firebase後的樣子
回到app.py
,我要設置一個API讓前端串接,負責取得打者習慣。
app.py
@app.route('/gethabit', methods=['POST'])
def gethabit():
player = str(request.form.getlist('p')[0])
stat = get_hitter_stat(player)
if stat:
chart_info = stat['習慣'].copy()
chart_info['name'] = player
return jsonify(chart_info)
else:
return redirect(url_for('index')) # 如果沒有就導回index.html
這個資料我也是要畫出一個圖的,而下一篇會介紹在前端的設置。