爬取全網小說(1)

python爬取全網小說

前言:想必大家都有過看小說時突然彈出來廣告的煩惱吧,今天我就來教大家怎麼去下載用戶指定的小說。

1. 分析頁面
a) 我們首先找到小說的章節地址,分析發現每個小說都有一個唯一的編號。那我們只需要找到小說的編號即可下載所有的小說了。而正好我們可以使用字典將數據保存到本地,以小說名作爲鍵,以小說的唯一編號作爲值即可實現下載用戶指定的小說了。
在這裏插入圖片描述
b) 我們知道了每個小說都有一個唯一的編號,找到編號即可下載對應的小說,那麼編號到哪裏找到呢。我們到小說的總排行榜的索引頁中可以直接獲取小說的唯一編號,我們只需要向索引頁發送請求,提取其中的地址,然後再提取地址中的編號後進行拼接,這樣我們就獲取到小說章節的下載地址了。
在這裏插入圖片描述
2. 明確爬取目標
a) 我們分析網頁得知在小說總排行榜中可以獲取小說對應的唯一編號,拼接後就是小說章節的詳情地址了。所以我們要爬取的目標就是總排行榜中所有小說的url。
在這裏插入圖片描述
b) 索引頁的url變化。根據頁數改變url即可獲取所有小說的索引頁url
在這裏插入圖片描述
3. 代碼實現
a) 寫爬蟲的代碼不重要,重要的思路,我只是給大家提供一種方法,更詳情的講解我會全放在代碼中。

b) 完整代碼

import json
import time
import requests
from os import path
from queue import Queue
from lxml import etree
from threading import Thread
from fake_useragent import UserAgent
from retrying import retry

class XiaoSshuoSpider(object):
    def __init__(self):
        self.url = 'http://www.55shuba.com/top/allvisit_{}.htm'
        self.headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                        "Accept-Encoding": "gzip, deflate",
                        "Accept-Language": "zh-CN,zh;q=0.9",
                        "Connection": "keep-alive",
                        "Cookie": "bdshare_firstime=1590149393888; UM_distinctid=1724548cc5b35-0819686bf4beda-58143718-144000-1724548cc5c2a7; CNZZDATA1254488625=180465324-1590297470-http%253A%252F%252Fwww.55shuba.com%252F%7C1590302884",
                        "Host": "www.55shuba.com",
                        "Referer": "http://www.55shuba.com/top/allvisit_1.htm",
                        "Upgrade-Insecure-Requests": "1",
                        "User-Agent": ua.random   # 使用random獲取隨機的用戶代理
                        }
        self.queue = Queue()   # 創建先進先出隊列
        self.info = {}         # 用來保存爬取後的數據
        self.count = 0         # 用來計數

    @retry(stop_max_attempt_number=3)   # retry的使用,當我們設置timeout三次都超時報錯
    def get_url_title(self):
        while not self.queue.empty():      # 如果隊列不爲空就一直從隊列中取出url並進行爬取
            res = requests.get(self.queue.get(), headers=self.headers, timeout=5).content.decode('gbk', errors='ignore')
            self.count += 1       # 計數
            print('正在爬取第{}頁'.format(self.count))
            time.sleep(1)  # 爬取1個頁面就睡眠1秒
            # 使用xpath提取小說名和小說的唯一編號
            html = etree.HTML(res)
            # 基準xpath提取數據
            dls = html.xpath('//div[@class="listtab"]//dl')
            for dl in dls:
                novel_name = dl.xpath('.//a/@title')[0]  # 提取小說名
                url_index = dl.xpath('.//a/@href')[0]    # 提取小說的url地址
                url_index = path.split(url_index)[-1][:-4]    # 從小說url地址提取出小說的編號
                '''例如:url = 'http://www.55shuba.com/txt/20394.htm
                        url_list = path.split(url_index)[-1]   # 得到的是一個元組,默認是以/爲分隔符,而且是以最後面的/進行分割
                   分割後結果:('http://www.55shuba.com/txt', '20394.htm')
                '''
                self.info[novel_name] = url_index

    # 保存爲json數據
    def save_data(self):
        with open('F:/文本/novel.json', 'w', encoding='utf-8')as f:
            f.write(json.dumps(self.info, ensure_ascii=False))
            print('保存完畢')


    def main(self):
        thread_list = []
        for i in range(1, 1863):   # 使用for循環創建將所有索引頁的url放入隊列中。
            self.queue.put(self.url.format(i))

        for i in range(10):        # 創建10個線程
            t1 = Thread(target=self.get_url_title)
            thread_list.append(t1)
            t1.start()

        for thread in thread_list:
            thread.join()


if __name__ == '__main__':
    start_time = time.time()
    try:
        ua = UserAgent()   # 實例化對象,調用其中的random即可獲取隨機的user-agent
        spider = XiaoSshuoSpider()
        spider.main()
        spider.save_data()
        print('花費{}s'.format(time.time()-start_time))
    except Exception as e:
        print('下載出錯 {}'.format(e))

4. 注意事項

  1. 關於代碼中使用的fake_useragent模塊,你們第一次運行時可以會沒有結果,過一會就會報這個錯,如果大家有報這個錯的可以參照我們的這一篇博客。–>報錯點我<–
 fake_useragent.errors.FakeUserAgentError: Maximum amount of retries reached
  1. 這1862頁的數據我是分了好幾次進行下載的,然後再進行整理得到完整的數據,如果有小夥伴需要的話我這裏提供了完整的json數據。大家可以依據自己的情況進行下載。
    鏈接:小說json數據
    提取碼:2ktf

結語:我們實現了獲取小說所對應的唯一編號,下一次我們就可以根據小說的編號下載全網的小說了。到這裏可以說我們已經成功了一半了。大家可以根據我講的自己去嘗試一下下載小說。下篇文章我就會教大家怎麼去下載小說。
第二篇地址:點我進入 爬取全網小說(2)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章