Python爬虫进阶之爬取篮球赛数据
相信很多人都喜歡打籃球, 并且對自己喜歡的球星的比賽數據都很關注,于是我就想著去爬取籃球網站的數據。但是相對來說爬取一個數據也沒啥挑戰性,于是我又趕著學習了xlsxwriter模塊,將爬取的的數據放入表格并制作折線圖。
第一步 robots協議
對于學習爬蟲的小白來說一定要注意robots協議,也稱為爬蟲協議,機器人協議等,一般網站都會通過該協議告訴搜索引擎哪些頁面可以爬取或不可以爬取。
首先我們在要爬取網站url后面加上robots.txt,
雖然對于robots協議還不太懂,但大概知道我要爬取的內容是可以的。
第二步 分析網站
可以看到,這就是一個單純的靜態網頁,那要爬取東西就簡單多了。
接著我們通過f12點擊頁面去查看源代碼,發現每個球隊的鏈接就嵌在代碼中
進入球隊的網址后就可以看到每個球員的信息,并且球員的URL也嵌在代碼中。
并且所有比賽數據和球員介紹也都在源代碼中獲得,無論是用Beautifulsoup,Xpath,還是正則表達式都可以輕松獲取。廢話少說直接上代碼
第三步 寫代碼
導入相關模塊
#coding=utf-8 from bs4 import BeautifulSoup import requests import xlsxwriter import os import re #留作備用,beautifulsoup我才看了半天不太熟悉定義函數獲取球隊列表和URL,果不其然,當我用正則表達式的時候出現了嚴重的錯誤,本來我是想通過輸入球隊名字用作參數放進正則表達式中,應為我想匹配的字符前面的都是a href=,也就是當從頭到尾匹配的時候,他只從第一個開始把符合的字符串返回給我,我實在沒想到辦法解決(我的正則表達式也沒學好),最后想到了用列表的方式將URL給匹配出來。
#自定義函數獲取球隊列表和相應的URL def teamlists(url):name_list=[] #定義空列表放入所有球隊名稱teamurl_list=[] #定義空列表放入所有球隊對應的URLhtml=requests.get(url)soup=BeautifulSoup(html.content,'lxml')#找到特定標簽的元素links=soup.select('html body div div div ul li span a')for link in links:baskname=link.get_text()name_list.append(baskname)print(baskname)teamname=input("請輸入想查詢的球隊名:")c=name_list.index(teamname)for item in links:url1=item.get('href')teamurl_list.append(url1)TeamUrl=teamurl_list[c] # Team_pat=r'a href="(.*?)">'+teamname+'</a>,' # Team_url=re.findall(Team_pat,str(links)) # TeamUrl="".join(Team_url)return TeamUrl這個函數也是廢了很大的勁,剛開始是沒有后面那兩個for循環的,因為我需要的數據只是每個球員的職業生涯常規賽,當我寫完代碼運行的時候發現獲取的數據都有偏差,只能準確獲得哈登的數據(因為我剛開始一直照著哈登的數據堆代碼),后來才發現每個球員比賽的年份不一樣,于是乎才用了兩個for循環來刪掉指定的數據。
#自定義函數獲取指定隊員的比賽信息 def Competition(playersUrl):data=[]html3=requests.get(playersUrl)soup3=BeautifulSoup(html3.content,'lxml')links3=soup3.select('html body div div div div div div div div p')links4=soup3.select('div div table tbody tr td')for link3 in links3:introduction=link3.get_text() #輸入球員的名稱后返回球員的介紹print(introduction)for link4 in links4:match_one=link4.get_text()data.append(match_one) #將比賽的數據放入data # print(data)for i in range(len(data)):if data[i]=='職業生涯常規賽平均數據': # print(data.index('職業生涯常規賽平均數據'))a=data[i+31]a=data.index(a)del(data[:a]) #清除a之前的所有數據for x in range(len(data)):if data[x]=='職業生涯季后賽平均數據': # print(data.index('職業生涯季后賽平均數據'))b=data[x]b=data.index(b) # del(data[b:])del(data[b:]) #清除b之后的所有數據return data這個函數簡直是絞盡腦汁,剛開始寫入數據我是一個一個寫的,后來又發現每個人的數據都錯位(原諒我又是照著哈登來寫的),昨天想了一個下午才利用這個for循環來建立表格的數據。(太喜歡用for循環,萬能,對于我們這種小白來說)。
#自定義函數創建表格和表圖 def player_chart(name,data,cur_path):workbook=xlsxwriter.Workbook(cur_path+'\\'+name+'chart.xlsx') #在指定路徑創建表格文件worksheet=workbook.add_worksheet(name) #創建工作臺bold=workbook.add_format({'bold':1}) #自定義樣式,加粗headings=data[:18]worksheet.write_row('A1',headings,bold) #寫入表頭num=(len(data))//18a=0for i in range(num):a=a+18c=a+18i=i+1worksheet.write_row('A'+str(i+1),data[a:c]) #寫入數據chart_col = workbook.add_chart({'type': 'line'}) #創建一個折線圖#配置第一個系列數據 chart_col.add_series({'name': '='+name+'!$R$1', #設置折線描述名稱'categories':'='+name+'!$A$2:$A$'+str(num), #設置圖表類別標簽范圍'values': '='+name+'!$R$2:$R$'+str(num-1), #設置圖表數據范圍'line': {'color': 'red'}, }) #設置圖表線條屬性#設置圖標的標題和想x,y軸信息chart_col.set_title({'name': name+'生涯常規賽平均得分'}) chart_col.set_x_axis({'name': '年份 (年)'}) chart_col.set_y_axis({'name': '平均得分(分)'})chart_col.set_style(1) #設置圖表風格worksheet.insert_chart('A14', chart_col, {'x_offset':25, 'y_offset':3,}) #把圖標插入工作臺中并設置偏移workbook.close()以上都是幾個比較重要的結構,我直接上源代碼
#coding=utf-8 from bs4 import BeautifulSoup import requests import xlsxwriter import os import re#自定義函數獲取球隊列表和相應的URL def teamlists(url):name_list=[] #定義空列表放入所有球隊名稱teamurl_list=[] #定義空列表放入所有球隊對應的URLhtml=requests.get(url)soup=BeautifulSoup(html.content,'lxml')links=soup.select('html body div div div ul li span a') #找到特定標簽的元素for link in links:baskname=link.get_text()name_list.append(baskname)print(baskname)teamname=input("請輸入想查詢的球隊名:")c=name_list.index(teamname)for item in links:url1=item.get('href')teamurl_list.append(url1)TeamUrl=teamurl_list[c] # Team_pat=r'a href="(.*?)">'+teamname+'</a>,' # Team_url=re.findall(Team_pat,str(links)) # TeamUrl="".join(Team_url)return TeamUrl#自定義函數獲取隊員列表和對應的URL def playerlists(TeamUrl):playname_list=[] #定義空列表放入所有球員名稱playurl_list=[] #定義空列表放入所有球員對應的URLhtml2=requests.get(TeamUrl)soup2=BeautifulSoup(html2.content,'lxml')links2=soup2.select('html body div div table tbody tr td b a')for link2 in links2:playername=link2.get_text()playname_list.append(playername)print(playername)name=input("請輸入球員名:")d=playname_list.index(name)for item2 in links2:url2=item2.get('href')playurl_list.append(url2)playersUrl=playurl_list[d] # players_pat=r'a href="(.*?)" target="_blank">'+name # players_url=re.findall(players_pat,str(links2)) # playersUrl="".join(players_url)return playersUrl,name#自定義函數獲取指定隊員的比賽信息 def Competition(playersUrl):data=[]html3=requests.get(playersUrl)soup3=BeautifulSoup(html3.content,'lxml')links3=soup3.select('html body div div div div div div div div p')links4=soup3.select('div div table tbody tr td')for link3 in links3:introduction=link3.get_text() #輸入球員的名稱后返回球員的介紹print(introduction)for link4 in links4:match_one=link4.get_text()data.append(match_one) #將比賽的數據放入data # print(data)for i in range(len(data)):if data[i]=='職業生涯常規賽平均數據': # print(data.index('職業生涯常規賽平均數據'))a=data[i+31]a=data.index(a)del(data[:a]) #清除a之前的所有數據for x in range(len(data)):if data[x]=='職業生涯季后賽平均數據': # print(data.index('職業生涯季后賽平均數據'))b=data[x]b=data.index(b) # del(data[b:])del(data[b:]) #清除b之后的所有數據return data#自定義函數創建文件夾 def file_add(path):cur_path=path+'\\Basketball' #在指定路徑建立文件夾try:if not os.path.isdir(cur_path):#確認文件夾是否存在os.makedirs(cur_path) #不存在則新建except:print("文件夾存在")return cur_path #自定義函數創建表格和表圖 def player_chart(name,data,cur_path):workbook=xlsxwriter.Workbook(cur_path+'\\'+name+'chart.xlsx') #在指定路徑創建表格文件worksheet=workbook.add_worksheet(name) #創建工作臺bold=workbook.add_format({'bold':1}) #自定義樣式,加粗headings=data[:18]worksheet.write_row('A1',headings,bold) #寫入表頭num=(len(data))//18a=0for i in range(num):a=a+18c=a+18i=i+1worksheet.write_row('A'+str(i+1),data[a:c]) #寫入數據chart_col = workbook.add_chart({'type': 'line'}) #創建一個折線圖#配置第一個系列數據 chart_col.add_series({'name': '='+name+'!$R$1', #設置折線描述名稱'categories':'='+name+'!$A$2:$A$'+str(num), #設置圖表類別標簽范圍'values': '='+name+'!$R$2:$R$'+str(num-1), #設置圖表數據范圍'line': {'color': 'red'}, }) #設置圖表線條屬性#設置圖標的標題和想x,y軸信息chart_col.set_title({'name': name+'生涯常規賽平均得分'}) chart_col.set_x_axis({'name': '年份 (年)'}) chart_col.set_y_axis({'name': '平均得分(分)'})chart_col.set_style(1) #設置圖表風格worksheet.insert_chart('A14', chart_col, {'x_offset':25, 'y_offset':3,}) #把圖標插入工作臺中并設置偏移workbook.close()if __name__ == '__main__':url="http://nba.hupu.com/players/"path='E:'TeamUrl=teamlists(url)playersUrl,name=playerlists(TeamUrl)data=Competition(playersUrl)cur_path=file_add(path)player_chart(name,data,cur_path)效果展示:
第四步 總結問題
大家可以看到,對于beautifulsoup和正則表達式我不太熟悉,所以跟我一樣的小白一定要利用空閑時間多看看,但也告訴我們代碼是死的人是活的,要多利用其它的辦法去解決眼前的問題,唯一一項我沒有解決成功的問題就是我導入的折線圖沒辦法顯示出X軸的數據,我試過很多次,看了很多博客都沒找到解決辦法,也有可能是Xlsxwriter不夠熟,留給評論區的大神幫我解決。最后還是希望大家好好學習天天向上。
xlsxwriter模塊參考文獻:
python寫入excel(xlswriter)–生成圖表
總結
以上是生活随笔為你收集整理的Python爬虫进阶之爬取篮球赛数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gnuplot绘图程序中对线型(line
- 下一篇: python函数ppt_如何用 Pyth