實(shí)戰(zhàn)|手把手教你用Python爬取存儲(chǔ)數(shù)據(jù),還能自動(dòng)在Excel中可視化!
回復(fù)“書(shū)籍”即可獲贈(zèng)Python從入門(mén)到進(jìn)階共10本電子書(shū)
大家好,在之前我們講過(guò)如何用Python構(gòu)建一個(gè)帶有GUI的爬蟲(chóng)小程序,很多本文將迎合熱點(diǎn),延續(xù)上次的NBA爬蟲(chóng)GUI,探討如何爬取虎撲N(xiāo)BA官網(wǎng)數(shù)據(jù)。 并且將數(shù)據(jù)寫(xiě)入Excel中同時(shí)自動(dòng)生成折線(xiàn)圖,主要有以下幾個(gè)步驟。

本文將分為以下兩個(gè)部分進(jìn)行講解
在虎撲N(xiāo)BA官網(wǎng)球員頁(yè)面中進(jìn)行爬蟲(chóng),獲取球員數(shù)據(jù)。 清洗整理爬取的球員數(shù)據(jù),對(duì)其進(jìn)行可視化。
項(xiàng)目主要涉及的Python模塊:
requestspandasbs4
爬蟲(chóng)部分
爬蟲(chóng)部分整理思路如下??
觀察URL1的源代碼找到球隊(duì)名稱(chēng)與對(duì)應(yīng)URL2觀察URL2的源代碼找到球員對(duì)應(yīng)的URL3觀察URL3源代碼找到對(duì)應(yīng)球員基本信息與比賽數(shù)據(jù)并進(jìn)行篩選存儲(chǔ)。
其實(shí)爬蟲(chóng)就是在html上操作,而html的結(jié)構(gòu)很簡(jiǎn)單就只有一個(gè),就是一個(gè)大框討一個(gè)小框,小框在套小框,這樣的一層層嵌套。
目標(biāo)URL如下:
URL1: http://nba.hupu.com/players/URL2(此處以湖人球隊(duì)為例): https://nba.hupu.com/players/lakersURL3(此處以詹姆斯為例): https://nba.hupu.com/players/lebronjames-650.html
先引用模塊
from bs4 import BeautifulSoup
import requests
import xlsxwriter
import os
查看URL1源代碼代碼,可以看到球隊(duì)名詞及其對(duì)應(yīng)的URL2在span標(biāo)簽中<span class><a href = “...">下,進(jìn)而找到它的父框與祖父框,下面的思路都是如此,圖如下:
此時(shí),可以通過(guò)requests模塊與bs4模塊進(jìn)行有目的性的索引,得到球隊(duì)的名稱(chēng)列表。
def Teamlists(url):
TeamName=[]
TeamURL=[]
GET=requests.get(URL1)
soup=BeautifulSoup(GET.content,'lxml')
lables=soup.select('html body div div div ul li span a')
for lable in lables:
ballname=lable.get_text()
TeamName.append(ballname)
print(ballname)
teamname=input("請(qǐng)輸入想查詢(xún)的球隊(duì)名:")#此處可變?yōu)镚UI界面中的按鍵值
c=TeamName.index(teamname)
for item in lables:
HREF=item.get('href')
TeamURL.append(HREF)
URL2=TeamURL[c]
return URL2就此得到了對(duì)應(yīng)球隊(duì)的URL2,接著觀察URL2網(wǎng)頁(yè)的內(nèi)容,可以看到球員名稱(chēng)在標(biāo)簽a中<a target = "_blank" href = ....>下,同時(shí)也存放著對(duì)應(yīng)球員的URL3,如下圖:
此時(shí),故依然通過(guò)requests模塊與bs4模塊進(jìn)行相對(duì)應(yīng)的索引,得到球員名稱(chēng)列表以及對(duì)應(yīng)的URL3。
#自定義函數(shù)獲取隊(duì)員列表和對(duì)應(yīng)的URL
def playerlists(URL2):
PlayerName=[]
PlayerURL=[]
GET2=requests.get(URL1)
soup2=BeautifulSoup(GET2.content,'lxml')
lables2=soup2.select('html body div div table tbody tr td b a')
for lable2 in lables2:
playername=lable2.get_text()
PlayerName.append(playername)
print(playername)
name=input("請(qǐng)輸入球員名:") #此處可變?yōu)镚UI界面中的按鍵值
d=PlayerName.index(name)
for item2 in lables2:
HREF2=item2.get('href')
PlayerURL.append(HREF2)
URL3=PlayerURL[d]
return URL3,name
現(xiàn)在就此得到了對(duì)應(yīng)球隊(duì)的URL3,接著觀察URL3網(wǎng)頁(yè)的內(nèi)容,可以看到球員基本信息在標(biāo)簽p下,球員常規(guī)賽生涯數(shù)據(jù)與季后賽生涯數(shù)據(jù)在標(biāo)簽td下,如下圖:
同樣,依然通過(guò)requests模塊與bs4模塊進(jìn)行相對(duì)應(yīng)的索引,得到球員基本信息與生涯數(shù)據(jù),而對(duì)于球員的常規(guī)賽與季候賽的生涯數(shù)據(jù)將進(jìn)行篩選與儲(chǔ)存,得到data列表。
def Competition(URL3):
data=[]
GET3=requests.get(URL3)
soup3=BeautifulSoup(GET3.content,'lxml')
lables3=soup3.select('html body div div div div div div div div p')
lables4=soup3.select('div div table tbody tr td')
for lable3 in lables3:
introduction=lable3.get_text()
print(introduction) #球員基本信息
for lable4 in lables4:
competition=lable4.get_text()
data.append(competition)
for i in range(len(data)):
if data[i]=='職業(yè)生涯常規(guī)賽平均數(shù)據(jù)':
a=data[i+31]
a=data.index(a)
del(data[:a])
for x in range(len(data)):
if data[x]=='職業(yè)生涯季后賽平均數(shù)據(jù)':
b=data[x]
b=data.index(b)
del(data[b:])
return data
通過(guò)上述網(wǎng)絡(luò)爬蟲(chóng)得到了以下的數(shù)據(jù),提供可視化數(shù)據(jù)的同時(shí)便于綁定之后的GUI界面按鍵事件:
獲取NBA中的所有球隊(duì)的標(biāo)準(zhǔn)名稱(chēng); 通過(guò)指定的一只球隊(duì)獲取球隊(duì)中所有球員的標(biāo)準(zhǔn)名稱(chēng); 通過(guò)指定的球員獲取到對(duì)應(yīng)的基本信息以及常規(guī)賽與季后賽數(shù)據(jù);
可視化部分
思路:創(chuàng)建文件夾 創(chuàng)建表格和折線(xiàn)圖
自定義函數(shù)創(chuàng)建表格,運(yùn)用os模塊進(jìn)行編寫(xiě),返回已創(chuàng)文件夾的路徑,代碼如下:
def file_add(path): #此時(shí)的內(nèi)函數(shù)path可與GUI界面的Statictext綁定
creatpath=path+'\\Basketball'
try:
if not os.path.isdir(creatpath):
os.makedirs(creatpath)
except:
print("文件夾存在")
return creatpath
運(yùn)用xlsxwriter模塊在creatpath路徑下自定義函數(shù)創(chuàng)建excel表格同時(shí)放入數(shù)據(jù)與構(gòu)造折線(xiàn)圖,代碼如下:
def player_chart(name,data,creatpath):
#此為表格名稱(chēng)——球員名稱(chēng)+chart
EXCEL=xlsxwriter.Workbook(creatpath+'\\'+name+'chart.xlsx')
worksheet=EXCEL.add_worksheet(name)
bold=EXCEL.add_format({'bold':1})
headings=data[:18]
worksheet.write_row('A1',headings,bold) #寫(xiě)入表頭
num=(len(data))//18
a=0
for i in range(num):
a=a+18
c=a+18
i=i+1
worksheet.write_row('A'+str(i+1),data[a:c]) #寫(xiě)入數(shù)據(jù)
chart_col = EXCEL.add_chart({'type': 'line'}) #創(chuàng)建一個(gè)折線(xiàn)圖
chart_col.add_series({
'name': '='+name+'!$R$1', #設(shè)置折線(xiàn)描述名稱(chēng)
'categories':'='+name+'!$A$2:$A$'+str(num), #設(shè)置圖表類(lèi)別標(biāo)簽范圍
'values': '='+name+'!$R$2:$R$'+str(num-1), #設(shè)置圖表數(shù)據(jù)范圍
'line': {'color': 'red'}, }) #設(shè)置圖表線(xiàn)條屬性
#設(shè)置圖標(biāo)的標(biāo)題和想x,y軸信息
chart_col.set_title({'name': name+'生涯常規(guī)賽平均得分'})
chart_col.set_x_axis({'name': '年份 (年)'})
chart_col.set_y_axis({'name': '平均得分(分)'})
chart_col.set_style(1) #設(shè)置圖表風(fēng)格
worksheet.insert_chart('A14', chart_col, {'x_offset':25, 'y_offset':3,}) #把圖標(biāo)插入工作臺(tái)中并設(shè)置偏移
EXCEL.close()
數(shù)據(jù)表格效果展現(xiàn),以詹姆斯為例如下
并且此時(shí)打開(kāi)自動(dòng)生成的Excel,對(duì)應(yīng)的折線(xiàn)圖就直接展現(xiàn)出來(lái),無(wú)需再次整理!
現(xiàn)在結(jié)合任務(wù)一的網(wǎng)絡(luò)爬蟲(chóng)與任務(wù)二的數(shù)據(jù)可視化,可以得到實(shí)時(shí)的球員常規(guī)賽數(shù)據(jù)與季后賽數(shù)據(jù)匯總,同時(shí)還有實(shí)時(shí)球員生涯折線(xiàn)圖。便可以與上次的GUI界面任務(wù)設(shè)計(jì)中的”可視化“按鈕事件綁定,感興趣的讀者可以自己進(jìn)一步研究!
------------------- End -------------------
往期精彩文章推薦:

歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入Python學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群】
萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行
/今日留言主題/
隨便說(shuō)一兩句吧~
