爬取當當網圖書銷售排行榜(Python)


說明:我在寫這篇博客時有點着急,前半部分的代碼都沒有行號,后半部分的代碼有行號,不要錯把行號看成是代碼(應該沒有人會犯這種錯誤)。后面大半部分都是數據的截圖,可以直接忽略。

把總結寫在前面:不得不說,爬蟲真的是一個抓取網頁信息的好手段,但是它的局限性很大,Web 信息的巨大容量使得爬蟲在給定時間內只能下載少量網頁,即使能夠提取全部頁面,也沒有足夠的空間來存儲。爬行效率低,無法在單位時間內盡可能多的獲取高質量頁面。

1.首先確定爬取數據的網址,這里我是在谷歌中打開當當網“圖書暢銷榜”,網址:http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-1

此時顯示的是第一頁,第二頁網址的最后一個數字為2,以此類推。所以,爬取所有頁碼只需使用for語句構造循環,按頁碼依次進行網址的拼接並發起請求即可

 

 

 

 

 

 演示代碼:

import requests
import pandas as pd
from bs4 import BeautifulSoup
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
#模擬瀏覽器的身份驗證信息
for i in range(1,26):
url = f'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-{i}'#循環生成的每一頁網址

2.經確認,數據是動態加載的,可以用響應對象的text屬性獲取網頁源代碼,再從源代碼中提取數據。在上述代碼的for語句構造的循環內部繼續添加如下代碼:

response=requests.get(url=url,headers=headers,timeout=10)#對25頁的不同網址循環發起請求,設置超時等待為10秒
html_content=response.text#獲取網頁源代碼
soup=BeautifulSoup(html_content,'lxml')#將網頁源代碼實比例轉化為BeautifulSoup對象
parse_html(soup)#調用自定義函數提取BeautifulSoup對象中的數據,具體代碼見后
print(f'第{i}頁爬取完畢')

3.分析要提取數據的標簽。要提取的排行榜數據位於class屬性值為bang_list的<ul>標簽下的多個<li>標簽中。

4.編寫提取數據的代碼。

創建字典data_info,編寫自定義函數parse_html(),從BeautifulSoup對象中提取數據並添加到字典中。

演示代碼:

data_info = {'圖書排名': [], '圖書名稱': [], '圖書作者': [], '圖書出版時間': [], '圖書出版社': [], '圖書價格': []}#新建一個空字典
def
parse_html(soup):#解析每一個BeautifulSoup對象 li_list = soup.select('.bang_list li') # 通過層級選擇器定位class屬性值為bang_list的標簽下的所有<li>標簽 for li in li_list:#將從每一個<li>標簽中解析到的數據添加到字典data_info相應鍵的對應列表中 data_info['圖書排名'].append(li.select('.list_num ')[0].text.replace('.', '')) data_info['圖書名稱'].append(li.select('.name a')[0].text) data_info['圖書作者'].append(li.select('.publisher_info ')[0].select('a')[0].text) data_info['圖書出版時間'].append(li.select('.publisher_info span')[0].text) data_info['圖書出版社'].append(li.select('.publisher_info ')[1].select('a')[0].text) data_info['圖書價格'].append(float(li.select('.price .price_n')[0].text.replace('¥', '')))

注意:在最終的代碼文件中,定義parse_html()函數的代碼需位於調用該函數的代碼之前。

5.缺失值和重復值的處理。

先用pandas模塊將字典轉換為DataFrame對象格式,再判斷缺失值和重復值。

演示代碼:

1 book_info=pd.DataFrame(data_info)
2 print(book_info.isnull())#缺失值判斷
3 print(book_info.duplicated())#重復值判斷

6.一異常值的處理。本文只研究價格在100元以下的圖書,所以需要將價格高於100元的圖書刪除。

演示代碼:

1 book_info['圖書價格'][book_info['圖書價格']>100]=None#將大於100的圖書價格替換為空值
2 book_info=book_info.dropna()#刪除有空值的一行數據

7.保存爬取的數據,儲存為csv文件。

演示代碼:

1 book_info.to_csv('當當網圖書銷售排行.csv',enco ding='utf-8',index=False)

 

 

完整代碼在這里:

 1 import requests
 2 import pandas as pd
 3 from bs4 import BeautifulSoup
 4 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
 5 
 6 data_info = {'圖書排名': [], '圖書名稱': [], '圖書作者': [], '圖書出版時間': [], '圖書出版社': [], '圖書價格': []}
 7 def parse_html(soup):
 8     li_list = soup.select('.bang_list li')
 9     for li in li_list:
10         data_info['圖書排名'].append(li.select('.list_num ')[0].text.replace('.', ''))
11         data_info['圖書名稱'].append(li.select('.name a')[0].text)
12         data_info['圖書作者'].append(li.select('.publisher_info ')[0].select('a')[0].text)
13         data_info['圖書出版時間'].append(li.select('.publisher_info span')[0].text)
14         data_info['圖書出版社'].append(li.select('.publisher_info ')[1].select('a')[0].text)
15         data_info['圖書價格'].append(float(li.select('.price  .price_n')[0].text.replace('¥', '')))
16 
17 for i in range(1, 26):
18     url = f'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-{i}'
19     response = requests.get(url = url, headers = headers, timeout = 10)
20     html_content = response.text
21     soup = BeautifulSoup(html_content, 'lxml')
22     parse_html(soup)
23     print(f'第{i}頁爬取完畢')
24 
25 book_info = pd.DataFrame(data_info)
26 print(book_info.isnull())
27 print(book_info.duplicated())
28 
29 book_info['圖書價格'][book_info['圖書價格'] > 100] = None
30 book_info = book_info.dropna()
31 
32 book_info.to_csv('當當網圖書銷售排行.csv', encoding = 'utf-8', index = False)

結果如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM