简单爬虫实现
import requests
from bs4 import BeautifulSoup
urls = [f"https://www.cnblogs.com/#p{i}" for i in range(1, 50 + 1)]
def craw(url):
这个函数接收一个网页的URL作为参数,使用requests库发送GET请求获取该网页的内容,并以文本形式返回。
r = requests.get(url)
return r.text
def parse(html):
"""
此函数接收从网页下载的HTML文本内容作为参数,使用BeautifulSoup库对其进行解析,
提取出所有class名为post-item-title的超链接a标签,然后遍历这些标签,将每个标签的href链接内容
和标签文字内容以元组的形式提取出来并返回
"""
soup = BeautifulSoup(html, "html.parser")
links = soup.find_all("a", class_="post-item-title")
return [(link["href"], link.get_text()) for link in links]
if __name__ == '__main__':
"""
在这里我们调用了craw函数去下载urls列表中第3个网址(索引为2)的网页内容,
然后将下载好的内容传递给parse函数进行解析,最后遍历parse函数返回的结果并打印出来。
"""
for result in parse(craw(urls[2])):
print(result)
生产者消费者函数
import threading
import time
import random
import queue
import blog_spider
def do_craw(url_queue: queue.Queue, html_queue: queue.Queue):
"""
这个函数是生产者线程要执行的函数。
不断从URL队列中获取URL,调用blog_spider.craw函数爬取网页的内容,
然后将爬取到的HTML内容放入HTML队列中,并打印相关的内容。
"""
while True:
url = url_queue.get()
html = blog_spider.craw(url)
html_queue.put(html)
print(threading.current_thread().name, f"craw {url}", "url_queue.size=", url_queue.qsize())
time.sleep(random.randint(1, 2))
def do_parse(html_queue: queue.Queue, fout):
"""
此函数是消费者线程要执行的任务函数。
它会不断从HTML队列中获取网页内容,调用blog_spider.parse函数对其进行解析,fout: 用于写入解
析结果的文件对象
将解析结果写入到指定的文件中,并打印相关的内容。
"""
while True:
html = html_queue.get()
results = blog_spider.parse(html)
for result in results:
fout.write(str(result) + "\n")
print(threading.current_thread().name, f"results.size", len(results), "html_queue_size=", html_queue.qsize())
time.sleep(random.randint(1, 2))
if __name__ == '__main__':
url_queue = queue.Queue()
html_queue = queue.Queue()
for url in blog_spider.urls:
url_queue.put(url)
for idx in range(3):
t = threading.Thread(target=do_craw, args=(url_queue, html_queue), name=f"craw{idx}")
t.start()
fout = open("spider_data.txt", "w")
for idx in range(2):
t = threading.Thread(target=do_parse, args=(html_queue, fout), name=f"parse{idx}")
t.start()