# !/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()
運行結果: