
?python爬取?瓣某本書的前n條書評并計算評分(star)的平
均值
這個爬??項?是中國?學MOOC的“”課程的?個課后作業,由南京?學張莉?師主講,有興趣的同學可以看?看。
雖然?師已經給出了參考代碼,但由于?瓣讀書?站已經改版,參考代碼中的爬取?法已經不可?,所以我將源代碼稍作修改,并使之模塊
化,增強代碼的可復?性。
爬取思路如下:
?先我們打開的任何?本書的書評頁,這?以《Python編程從?門到實踐(第2版)》為例。
在頁?空?處右擊?標選擇“檢查”查看?頁的HTML代碼(我?的是Edge瀏覽器,其他瀏覽器的操作?法也應該相似),點擊左上?的
箭頭按鈕,可以查看頁?中模塊對應的代碼位置,如下圖所?:
我們可以看到,每?條書評都放在?個列表模塊
也放在模塊中,class屬性是“ur-starsallstar40rating”,其中的數字40即表?評分,?顆星表?10分,四顆星就是40分。
如下圖:
爬取思路是?Python的requests庫獲取?頁的HTML,再通過BeautifulSoup庫解析HTML獲取相應的書評和評分信息。
我們再來看看書評頁?的具體信息,發現每頁只能顯?20條書評,那如果我們想爬取多于20條的書評,是不是要通過爬取?個頁?換?個
URL的“笨?法”呢?其實也不?,通過觀察?頁的URL可以發現,每個頁?的URL只有"start="后?的數字不同,這個數字是控制頁?從
第?條書評開始顯?,第?頁就是從第0條書評開始,第?頁就是從第20條開始,我們可以把這個數字改成其他值,相應的頁?就會從那?
條書評開始顯?。
我們可以發現URL中還有?個參數limit,表?每?頁顯?的書評數,那我們可不可以把這個參數改成我們想要爬取的書評數?呢,這樣我
們就能在?個頁?中完成爬取,但很可惜,試了?下發現不?,?論怎么改還是只能顯?20條書評。
但既然每個頁?的URL只有start的參數不同,我們就可以通過?個while循環(python的for循環好像只能?來遍歷?個迭代器)來爬取多
個頁?。
為了代碼的可復?性,我把這個項?分成信息獲取和結果展?兩個模塊,分別定義兩個函數getInfo(url,n)和showRst(),函數getInfo中
的兩個參數表?要爬取的書評?頁的URL和書評的數量。
下?是具體的代碼:
#-*-coding:utf-8-*-
"""
CreatedonThuAug1217:43:452021
@discribe:douban_comments_spider
@author:86150
"""
#定義爬取信息的函數,其中參數url是爬取書評?頁的地址,n是爬取書評的數量
defgetInfo(url,n):
#導?要?到的第三?庫
importrequests
frombs4importBeautifulSoup
importre
importtime
count=0#?于記錄書評數量的計數器
i=0#?于控制翻頁的計數器
lis_comments=[]#?于存放書評內容的列表
lis_stars=[]#?于存放評分的列表
header={'Ur-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/91.0.4472.124Safari/537.36'}
#?于向服務器發送請求的頭部信息
whilecount
url_n=('?')[0]+'?start='+str(i)+('?')[1]#調?字符串的split()?法,以'?'為分隔符將URL分成兩個字符串,中間加?'?start='+str(i)字符串組成新的U
r=(url_n,headers=header)#調?requests的get()?法獲取頁?信息
soup=BeautifulSoup(,'lxml')#以'xml'格式解析
comments=_all('span','short')#調?soup對象的find_all?法獲取具有“short”屬性的所有span標簽
pattern=e('
p=l(pattern,)#調?re的findall?法匹配HTML中的所有評分分數(star)
foritemincomments:
lis_()#調?append?法將每?條書評添加到列表中
forstarinp:
lis_(int(star))#調?append?法將每?條評分添加到列表中
count=len(lis_comments)#獲取列表中的書評數?
i+=20#star數加上20,爬取下?個頁?
(3)#根據?瓣?的robot協議,每訪問?個頁?停留3秒鐘,以免被當作惡意爬?
returnlis_comments,lis_stars#返回書評和評分列表,便于被后?的函數調?
#定義顯?結果的函數,其中參數num是想要顯?的書評數量
defshowRst(num):
c,s=getInfo(url,n)#獲取getInfo函數的返回值
print("前%d條書評如下:"%n)
foriinrange(num):
print(i+1,c[i])#打印出每?條書評及其序號
print('--------------------------------------------------------------')
print("前%d條評分的平均值為:"%len(s),sum(s)/len(s))#調?python的內部函數len()和sum(),計算評分的平均值
if__name__=="__main__":#程序的??
url='/subject/35196328/comments/?&limit=20&status=P&sort=new_score'
n=100
num=80
getInfo(url,n)#調?getInfo函數獲取前n條書評和評分,因為有些書評可能沒有評分,所以評分數可能少于書評數
showRst(num)#showRst函數顯?前num條書評和評分的平均值
代碼中?到正則表達式來匹配字符串,下?是常?的正則表達式:
爬取結果如下:
Lifeisshort,IuPython.
本文發布于:2023-02-27 22:15:51,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/1677507351121.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:書評網.doc
本文 PDF 下載地址:書評網.pdf
| 留言與評論(共有 0 條評論) |