1. 程式人生 > >[Python爬蟲]爬蟲例項:線上爬取噹噹網暢銷書Top500的圖書資訊

[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檔案都放在網盤裡面了,還提供了離線的網頁用於測試.

百度網盤

感興趣就下載多多支援吧~
最終感謝沒有限制我讓我爬這麼多網頁的噹噹網的大力支援.
感謝提出要爬這個榜單資料用於工作的朱老闆.