前言
上次我們通過glidedsky的第一關實現了獲取到單頁的數據,但是可能有些小伙伴會覺得只是獲取到一些數字並不能直觀的體現出Python爬蟲的方便之處。
所以今天我跟大家分享一個小小的案例,這不是在家空閑時間比較多,又不想太過於頹廢,於是我打算在豆瓣挑選一些評分比較高的書分享給大家。
當然手動篩選工作量太大了,所以我決定用python寫一個爬蟲,爬取豆瓣圖書TOP250的簡單數據,並整理成表格保存在本地。
網頁元素分析
因為上篇文章只講了獲取單頁數據,所以這次我們的目標也是先獲取一頁數據。
這個頁面本身比較干凈,數據也很清晰,獲取會比較方便一些。
還是先f12查看頁面元素,確定所要獲取的數據。
通過審查元素可以看出所有數據特點:
書名包含在a標簽中,
作者及出版社等信息保存在命名為pl的p標簽中,並通過斜杠分割不同數據,
評分保存在class=allster_rums的span標簽中,
評價人數在class='pl'的span標簽中,
發現了嗎?這些數據沒有做任何加密,同時每一個數據標識各不相同,非常容易分辨。
這也是為什么很多人在初學爬蟲時都會接觸到爬取豆瓣top250例子的原因,因為數據內容有用,爬取難度相對較小。
這里還需要注意一個問題,就是這部分圖書並不全是中文書籍,還有一部分是外文書,這就導致了他們之間有一個地方數據有差別:
外文書會多出一個譯者名字,所以之后在保存數據到表格文件中時,需要特別注意。
代碼實現
在開始之前還是先明確一下程序執行流程:
- 訪問網頁
- 獲取源代碼
- 提取數據
- 分別保存到excel文件中
首先解決訪問網頁和獲取源代碼的問題:
import requests
from bs4 import BeautifulSoup
url = 'http://book.douban.com/top250?start='
headers = {
'cookie':'你自己的cookie',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
response = requests.get(url,headers=headers).text
bs4 = BeautifulSoup(response,'html.parser')
print(bs4)
獲取到之后當然就是對數據進行提取
bookName = bs4.find_all('div',class_='pl2')
for book in bookName:
name = book.find('a')
name = name.text.strip()
name = name.replace(' ','')
print(name)
這段代碼首先在獲取到的html文本中尋找Class=pl2的div元素
這是沒有提取a標簽中書名時的原始數據
find_all()是BeautifulSoup模塊提供的一個用來快速查詢數據的方法,返回一個列表。
所以我們下面使用for循環遍歷出所有找到的數據。
從上面的圖片中可以看到,只匹配div元素的話會有很多干擾數據,我們此時只想要一個書名,也就是a標簽的文本信息。
所以我們還需要在列表中使用find()方法匹配到a標簽的內容,然后使用strip方法去除兩邊空格,使用replace方法將文本中多余的空格替換為空,最終可以得到:
獲取到數據之后,我們希望能夠把它存放到excel文件中的話需要用到一個外部庫xlwt
使用pip命令安裝xlwt(因為我的電腦中同時安裝了py2和py3,所以將pip的版本進行了區分,只有一個python的話直接用pip即可)
然后使用 import xlwt
在程序中引入該模塊。
wb = xlwt.Workbook()
ws = wb.add_sheet('test_sheet')
ws.write(0,0,'書名')
ws.write(0,1,'出版信息')
ws.write(0,2,'評價人數')
ws.write(0,3,'評級')
wb.save('doubanTest.xls')
首先實例化workbook()對象,然后調用了add_sheet()方法為這個excel文件新建一個表
關於這個add_sheet()方法,前面說過python調用的外部模塊保存在**Python安裝目錄\Lib\site-packages**下,所以我們可以在這個目錄下找到Workbook類文件,從這里面查看add_sheet()的具體實現方法以及主要參數。
注意這段代碼中引入Worksheet這個文件,本文中主要用到的是Worksheet中的write()方法,即將數據保存到表格文件中。
在Worksheet.py中找到write函數,注釋給的非常詳細,r和c分別是row和column的縮寫,表示從0開始的行和列。
label參數默認為空,表示數據。
這樣一來上述代碼就通了,表示在第一行從第一列開始分別添加標題。
所有東西都設置好了之后就是保存這個文件,使用Workbook中的save()方法
傳入一個文件名即可。
這塊啰嗦了一點,主要還是希望大家能夠養成多看引入模塊源文件的習慣。
其他數據的獲取其實和獲取書名類似
獲取作者及出版信息
i = 1
j = 1
k = 1
l = 1
authors = bs4.find_all('p',class_='pl')
for author in authors:
anthor = author.text
ws.write(j,1,author)
j+=1
print(author)
獲取評分及評價人數
rating_nums = bs4.find_all('div',class_='star clearfix')
for rating in rating_nums:
star = rating.find_all('span')
reg = '\d+'
vote = re.findall(reg,star[2].text)
ws.write(k,2,vote)
ws.write(l,3,star[1].text)
k+=1
l+=1
wb.save('doubanTest.xls')
ijkl分別代表的是不同的行數,作用在於換行時使用。
這里還有一點需要注意的地方,在獲取評分及評價人數時,因為兩個數據在同一個div下保存,而且是同級別的span標簽並列表示的。
所以使用find_all()方法獲取到全部span標簽內容后可以使用下標的方式查詢到不同的數據。
至此,我們的程序就大功告成了,運行后會在該目錄下生成一個douban.xls文件
如果出現這種錯誤
說明你之前已經生成了一個doubanTest.xls文件而且沒有關閉它。
解決辦法是更改生成的文件名或者將原文件關閉。