用100行Python爬蟲代碼抓取公開的足球數據玩(一)
在《用Python模擬2018世界盃奪冠之路》一文中,我選擇從公開的足球網站用爬蟲抓取數據,從而建模並模擬比賽,但是略過了爬蟲的實施細節。雖然爬蟲並不難做,但希望可以讓更多感興趣的朋友自己動手抓數據下來玩,提供便利,今天就把我抓取球探網的方法和Python源碼拿出來分享給大家,不超過100行代碼。希望球友們能快速get爬蟲的技能。
#-*- coding: utf-8 -*-from __future__ import print_function, divisionfrom selenium import webdriverimport pandas as pdclass Spider(object): def __init__(self): ## setup #self.base_url = base_url self.driver = webdriver.Chrome() self.driver.implicitly_wait(30) self.verificationErrors = [] self.accept_next_alert = True def get_all_team_data(self): # 先通過世界盃主頁獲取所有32隻隊的ID(構成球隊URL) self.get_team_ids() # 循環爬取每一支隊的比賽數據 data = [] for i, [team_id, team_name] in enumerate(self.team_list): #if i == 1: # break print(i, team_id, team_name) df = self.get_team_data(team_id, team_name) data.append(df) output = pd.concat(data) output.reset_index(drop=True, inplace=True) #print(output) output.to_csv(data_2018WorldCup.csv, index=False, encoding=utf-8) self.driver.close() def get_team_ids(self): main_url = http://zq.win007.com/cn/CupMatch/75.html self.driver.get(main_url) teams = self.driver.find_elements_by_xpath("//td[@stylex=background-color:#fff;text-align:left;]") data = [] for team in teams: team_id = int(team.find_element_by_xpath(".//a").get_attribute(href).split(/)[-1].split(.)[0]) team_name = team.find_element_by_xpath(".//a").text print(team_id, team_name) data.append([team_id, team_name]) self.team_list = data #self.team_list = pd.DataFrame(data, columns=[team_name, team_id]) #self.team_list.to_excel(國家隊ID.xlsx, index=False) def get_team_data(self, team_id, team_name): """獲取一個國家隊的比賽數據。TODO:沒有實現翻頁""" url = http://zq.win007.com/cn/team/CTeamSche/%d.html%team_id self.driver.get(url) table = self.driver.find_element_by_xpath("//div[@id=Tech_schedule and @class=data]") matches = table.find_elements_by_xpath(".//tr") print(len(matches)) # 抓取比賽數據,並保存成DataFrame data = [] for i, match in enumerate(matches): if i == 0: headers = match.find_elements_by_xpath(".//th") h1, h2, h3, h4, h5 = headers[0].text, headers[1].text, headers[2].text, headers[3].text, headers[4].text print(h1, h2, h3, h4, h5) continue try: info = match.find_elements_by_xpath(".//td") cup = str(info[0].text.encode(utf-8)) match_time = str(info[1].text.encode(utf-8)) home_team = str(info[2].text.encode(utf-8)) fts = info[3].text #print(-, cup, -) fs_A, fs_B = int(fts.split(-)[0]), int(fts.split(-)[1]) away_team = str(info[4].text.encode(utf-8)) print(cup, match_time, home_team, away_team, fs_A, fs_B) data.append([cup, match_time, home_team, away_team, fs_A, fs_B, team_name]) except: break df = pd.DataFrame(data, columns=[賽事, 時間, 主隊, 客隊, 主隊進球, 客隊進球, 國家隊名]) return dfif __name__ == "__main__": spider = Spider() # 第一步:抓2018世界盃球隊的ID。第二部:循環抓取每一支隊的比賽數據。 spider.get_all_team_data()
是的,上面就是全部的代碼,不到100行。首先,打開球探網2018世界盃球隊頁面,32個國家隊名都列在這個頁面里,每個國家點進去都是一頁比賽列表數據,我們要爬取的就是這32個頁面。那麼我們必須分兩部分完成:
第一步,找到32個國家隊各自的網頁鏈接;
第二步,分別進入32個鏈接,爬取各自的比賽記錄數據。
主程序定義了一個Spider類,你可以理解它就是負責完成爬蟲這件事的責任人。在它下面定義了一個方法叫get_team_ids,來完成第一步,它讀取這個主頁面地址main_url = http://zq.win007.com/cn/CupMatch/75.html,通過xpath的方式先找到所有32個國家隊名賦給teams變數,再進一步分解出各自的team_id和team_name,注意,球探網每一個球隊的url都由一個team_id構造成,換句話說只要知道team_id便可找到確切的球隊鏈接,這也是網站方便管理那麼多鏈接的一個辦法。(比如巴西隊的id是778,注意鏈接http://zq.win007.com/cn/team/CTeamSche/778.html)
隨後,Spider類下還定義了一個get_team_data方法,它需要傳入兩個參數team_id和team_name,就是球隊鏈接和球隊名。由它來負責進入一個給定的國家隊頁面,抓取這個隊所有歷史比賽數據。比如巴西隊,可以看到比賽數據是一條一條列出來,內容是很整齊的,包括賽事名稱、比賽時間、主隊、客隊、比分、還有一切讓球、大小球盤口數據等。就像一個excel表格的網頁版,實際上,我們真的可以把每一條數據整整齊齊地爬下來,存進一個excel格式里。而且這種整齊的html表單數據很容易爬取,因為格式是固定的。只要從html源碼中找到每一個數字對應的源碼就可以通過爬蟲語言定位到數據。
最後,為了方便,Spider類下的方法get_all_team_data只是把上面兩步整合在一起,完成整個數據抓取過程。在最後調用這個爬蟲程序時,先初始化爬蟲spider = Spider(),然後調用spider.get_all_team_data()即可開始自動爬取32個國家隊的歷史比賽數據咯。
由於採用了selenium的webdriver介面,它會讓python自動模擬人的行為去打開你的瀏覽器,所以程序一旦運行你會看到你電腦的瀏覽器將自動打開、自動地跳轉鏈接,跳轉32個國家隊的頁面。最終,它將爬取下來的比賽數據保存進一張csv存到你電腦本地。
此外,這個爬蟲程序稍作修改,可以爬取聯賽的數據,比如英超2017-2018賽季,所有的比賽記錄同樣可以抓下來。更牛逼的地方是我發現它其實有100多個國家,3-10個級別聯賽,近10年的比賽記錄,粗略一算也有小10萬場比賽。全部抓下來,比分、賽事、讓球等等都有,應該還是挺有趣的。
推薦閱讀:
※演算法,西瓜切十刀,最多是多少塊?
※python爬蟲實習?
※幾個凡是,與Python 學習者共享
※求一本 Python 3 的好書,入門級別或中等級別,求推薦?
※Python數據採集(爬蟲)淺談