[Python爬蟲]爬蟲例項:線上爬取噹噹網暢銷書Top500的圖書資訊
本例項還有另外的離線爬蟲實現,有興趣可點選離線爬取噹噹網暢銷書Top500的圖書資訊
爬蟲說明
1.使用requests和Lxml庫爬取,(用BS4也很簡單,這裡是為了練習Xpath的語法)
2.爬蟲分類為兩種,一種是離線爬蟲,即先將所爬取的網頁儲存到本地,再從本地網頁中爬取資訊;第二種是本例項使用的線上爬蟲,即在網站中一邊開啟網頁一邊進行爬取.
3.線上爬蟲的優點是:步驟少,不用儲存檔案和其他麻煩步驟;爬取速度快,程式碼短
4.離線爬蟲的缺點是:在程式碼編寫過程中,需要進行反覆的修改,每次執行都要重新爬取線上網頁,浪費資源,爬取速度受網路響應影響大,過快的爬取有可能收受到網站的限制等.
爬蟲介紹
本次爬蟲爬取的網頁為:
圖書暢銷榜-10月暢銷書排行榜-噹噹暢銷圖書排行榜
爬取的資訊包括圖書的排名,書名,作者,好評率,購買頁面以及ISBN
如圖:
其中,ISBN需要在購買頁面連結中繼續爬取,找到ISBN
爬取之後的結果整理好存放到csv檔案中.
最終成果如圖:
爬蟲程式碼
觀察需要爬取的第一頁和最後一頁:
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-month-2018-10-1-1
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-month-2018-10-1-25
發現只有最後一個數字改了,且每頁顯示20本圖書,所以25*20=500,搞定.
這裡自己了一個spider.py
get_encoding()
一個用於獲取網站的編碼格式
import requests
import re
def get_encoding(url, headers=None): # 一般每個網站自己的網頁編碼都是一致的,所以只需要搜尋一次主頁確定
'To get website\'s encoding from tag<meta content=\'charset=\'UTF-8\'>'#從<meta>標籤中獲取
res = requests.get(url, headers=headers)
charset = re. search("charset=(.*?)>", res.text)
if charset is not None:
blocked = ['\'', ' ', '\"', '/']
filter = [c for c in charset.group(1) if c not in blocked]
return ''.join(filter) # 修改res編碼格式為源網頁的格式,防止出現亂碼
else:
return res.encoding # 沒有找到編碼格式,返回res的預設編碼
在dangdang_best_selling_online.py
中,程式碼如下:
import spider
import csv
import requests
import time
from lxml import etree
# 2018-10 前500的暢銷書的書名 ,使用線上爬蟲,思路和離線做了些修改
# 爬取25頁書單頁面,對每個書單頁面儲存詳細頁的頁面(一一對應)
# 最後同時寫入書單頁的資訊,每個列表儲存一個資訊和詳細頁的資訊
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
} # 設定headers
encoding = spider.get_encoding('http://www.dangdang.com', headers) # 獲取主站編碼
urls = ['http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-month-2018-10-1-{}'.format(i) for i in
range(1, 26)]
# 線上爬蟲的準備
detail_url = []
rank = []
site = []
name = []
star = []
author = []
ISBN = []
if __name__ == '__main__':
for i in range(24): # 0~24 ->1~25
res = requests.get(urls[i], headers)
res.encoding = encoding
selector = etree.HTML(res.text)
booklist = selector.xpath('//ul[@class="bang_list clearfix bang_list_mode"]/li')
book = [book for book in booklist]
for i in range(len(book)):
rank.append(book[i].xpath('div[1]/text()')[0]) # 排名
site.append(book[i].xpath('div[2]/a/@href')[0]) # 購買/詳細頁面
name.append(book[i].xpath('div[3]/a/text()')[0]) # 名字
star.append(book[i].xpath('div[4]/span/span/@style')) # 以星星寬度決定好評
author.append(book[i].xpath('div[5]/a/text()')) # 作者名
time.sleep(0.5)
for url in site:
res = requests.get(url, headers)
res.encoding = encoding
pattern = '//ul[@class="bang_list clearfix bang_list_mode"]/li/div[2]/a/@href'
ISBN.append(etree.HTML(res.text).xpath('//ul[@class="key clearfix"]/li[5]/text()')[0]) # 獲取每一本書的詳細頁面
time.sleep(0.5)
執行的流程是:按迴圈順序依次獲取頁面中的排名,名字,詳細頁面等,存放到列表中
爬取完25個頁面後,在詳細頁面的列表中取出地址,繼續進行爬取ISBN.
格式化輸出和儲存:
將分別儲存有各個維度資訊的列表進行格式化處理(清洗),最後按相同的次序寫入到csv中
tmp = []
for s in star:
tmp.append(''.join([c for c in str(s) if c.isdigit() or c == '.']))
star = tmp
rank = [r.replace('.', '') for r in rank]
author = [' '.join(a) for a in author]
ISBN = [i.replace('國際標準書號ISBN:', '') + '\t' for i in ISBN]
output = open('d:/dangdang/result.csv', 'w', encoding=encoding, newline='') # 將資訊匯出到csv,設定newline=""去除寫一行空一行的影響
writer = csv.writer(output) # csv writer
writer.writerow(('排名', '書名', '作者', '好評率', '購買頁面', 'ISBN'))
for i in range(len(rank)):
writer.writerow((rank[i], name[i], author[i], star[i], site[i], ISBN[i])) # 儲存到csv
不多贅述,有興趣可以copy下來慢慢玩,最好就是開啟暢銷書的網頁,然後對照審查元素慢慢研究lxml. 另外要注意的細節都以註釋形式儲存了.
寫在最後
爬蟲挺好玩的,所有的原始碼和輸出的csv檔案都放在網盤裡面了,還提供了離線的網頁用於測試.
百度網盤
感興趣就下載多多支援吧~
最終感謝沒有限制我讓我爬這麼多網頁的噹噹網的大力支援.
感謝提出要爬這個榜單資料用於工作的朱老闆.