多線程爬取糗事百科

# !/usr/bin/python3
# -*- coding: utf-8 -*-

# 1. 導入線程池模塊
# 線程池
import gevent.monkey

gevent.monkey.patch_all()
from gevent.pool import Pool
from queue import Queue
import requests
from lxml import etree


class QiushiSpider():

    def __init__(self, max_page):
        self.max_page = max_page
        # 2. 創建線程池,初始化線程數量
        self.pool = Pool(5)

        self.base_url = "http://www.qiushibaike.com/8hr/page/{}/"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
        }

        # 專門存放 url 容器
        self.url_queue = Queue()
        pass

    def get_url_list(self):
        '''
        獲取 url 列表放入到 url 容器中
        :return:
        '''
        for page in range(1, self.max_page, 1):
            url = self.base_url.format(page)
            self.url_queue.put(url)

    # 3. 實現執行任務
    def exec_task(self):
        # 1> 獲取url
        url = self.url_queue.get()

        # 2> 發送請求獲取 html
        response = requests.get(url, headers=self.headers)
        html = response.text

        # 3> 解析 html 提取數據
        # 可以用來解析字符串格式的HTML文檔對象,
        # 將傳進去的字符串轉變成_Element對象。
        # 作爲_Element對象,可以方便的使用getparent()、remove()、xpath()
        # 等方法。
        # etree.HTML()

        eroot = etree.HTML(html)
        # xpath獲取html源碼中的內容
        titles = eroot.xpath('//a[@class="recmd-content"]/text()')
        for title in titles:
            item = {}
            item["title"] = title

            # 4> 保存數據
            print(item)
        self.url_queue.task_done()

    # 4. 實現執行任務完成後的操作,必須至少有一個參數
    # result 任務執行的最終結果的返回值
    def exec_task_finished(self, result):
        print("result:", result)
        print("執行任務完成")
        self.pool.apply_async(self.exec_task, callback=self.exec_task_finished)

    def run(self):

        self.get_url_list()

        # 5. 讓任務使用線程池中的線程執行並且設置執行後的回調操作
        # callback 表示執行完成後的回調
        for i in range(5):
            self.pool.apply_async(self.exec_task, callback=self.exec_task_finished)
        self.url_queue.join()
        pass


if __name__ == '__main__':
    max_page = input("請輸入您需要多少頁內容:")
    spider = QiushiSpider(int(max_page))
    spider.run()

 

運行結果:

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