python隊列Queue
Queue是python標準庫中的線程安全的隊列(FIFO)實現,提供了一個使用於多線程編程的先進先出的數據結構,即隊列,用來在生產者和消費者線程之間的信息傳遞。
基本FIFO隊列
class Queue.Queue(maxsize=0)。FIFO即first in first out,先進先出。queue提供了一個基本的FIFO容器,使用方法很簡單,maxsize是個整數,指明瞭隊列中能存放的數據個數的上限。一旦達到上限,插入會導致阻塞,直到隊列中的數據被消費掉。如果maxsize小於或者等於0,隊列大小沒有限制。它是進行廣度遍歷。
import queue
test = queue.Queue()
test.put("123")
print(test.get())
test.get()
然後python會一直運行。
LIFO隊列
LIFO即Last in First Out,後進先出。與棧的類似,使用同FIFO用法類似。
如果要實現增量式爬蟲,要使用FIFO隊列
以爬百度貼吧爲例:
import requests
import lxml.html
from queue import Queue
class TiebaSpider(object):
"""
實現下載某個貼吧指定頁碼前的內容,存儲下載內容
"""
def __init__(self, name, pages):
"""
初始化方法
"""
self.tieba_name = name
self.pages_download = pages
self.base_url = "https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}"
self.header = {"User-Agent": "Python"}
self.crawl_queue = Queue()
self.crawl_queue.put(UrlType(0, "https://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0"))
def make_url_list(self):
"""
獲取待下載的url列表
:return:返回生成的url列表
"""
url_lists = []
for i in range(self.pages_download):
download_url = self.base_url.format(self.tieba_name, i * 50)
url_lists.append(download_url)
return url_lists
# 注意maybe static 警告,怎麼消除警告?
def save_url(self, content, file_name):
"""
將指定內容進行存儲
:param content:要存儲的內容,這裏傳入的參數要求是二進制
:param file_name:文件名
:return:無
"""
with open(file_name, 'wb') as f:
f.write(content)
def download_url(self, url_str):
"""
下載指定url處的內容
:param url_str: 要下載的地址
:return: 返回下載的結果
"""
response = requests.get(url_str, headers=self.header)
return response.text # content是二進制數據
def run(self):
"""
主業務邏輯,使用run後期可以改造成多線程爬蟲
:return:
"""
while not self.crawl_queue.empty():
url_type = self.crawl_queue.get()
# 廣度優先遍歷的訪問自身
print("正在下載", url_type.compelete_url())
result_text = self.download_url(url_type.compelete_url())
parse_result = lxml.html.fromstring(result_text)
# 廣度優先遍歷的訪問鄰居
if url_type.url_type == 1 or url_type.url_type == 0:
result_elements = parse_result.cssselect("ul#thread_list > li.j_thread_list")
next_element = parse_result.cssselect("div.thread_list_bottom a.next")[0]
url_str_next = next_element.xpath(".//@href")[0]
self.crawl_queue.put(UrlType(1, url_str_next))
# print("next page is :",url_str_next)
# print("*" * 50)
for result_element in result_elements:
result_thread = result_element.cssselect("div.threadlist_title > a.j_th_tit")[0]
print(result_thread.text)
url_str_detail = result_thread.xpath(".//@href")[0]
self.crawl_queue.put(UrlType(2, url_str_detail))
print(url_str_detail)
else:
pass
class UrlType(object):
"""
URL類型對象,用來存放網址類型
"""
def __init__(self, url_type, url_str):
"""
初始化函數
:param url_type: url類型 1:下一頁 2:詳情頁
:param url_str: url字符串
"""
self.url_type = url_type
self.url_str = url_str
def compelete_url(self):
"""
根據url_type類型返回完整的url
:return:
"""
if self.url_type == 1:
return "https:" + self.url_str
if self.url_type == 2:
return "https://tieba.baidu.com" + self.url_str
return self.url_str
tieba_spider = TiebaSpider('lol', 2)
tieba_spider.run()
然後就會一直進行爬取。