iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 1
0
自我挑戰組

從爬蟲到架站系列 第 10

Day 9: 從爬蟲到架站-增加新功能

  • 分享至 

  • xImage
  •  

這篇主要是濃縮前面幾篇文章的內容,會用兩篇來帶過整個操作。


除了月份的數據,打者對左右投的數據也很重要,而左右投的數據也是在中職的官網可以查到,跟月份的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

這個資料我也是要畫出一個圖的,而下一篇會介紹在前端的設置。


上一篇
Day 8: 從爬蟲到架站-js更改網頁
下一篇
Day 10: 從爬蟲到架站-增加新功能(前端)
系列文
從爬蟲到架站21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言