多线程能够帮助我们提升爬取爬虫爬取的速度,上一篇文章我们也讲到了如何简单的使用多线程来爬取自己想要要去的东西,今天我们来加强以下 (●ˇ∀ˇ●)
今天我们的目标是多线程爬取股票网站的信息,并保存成文件,本次保存文件的格式为txt(各位想保存别的格式也可以哦)话不多说,我们来开始盘它
本次要爬的股票网站
分析:点击进去可以看到该网站的响应数据内容为html格式,因此我们可以用xpath,正则来获取到我们想要的数据
以下为要爬取的数据及xpath提取的方式
#阅读数
reade_num = html_data.xpath("//ul[@class='newlist']/li/cite[1]/text()")
#print(len(reade_num))
#评论数
comment_num = html_data.xpath("//ul[@class='newlist']/li/cite[2]/text()")
#详情url
base_url = html_data.xpath("//a[@class='note']/@href")
#print(len(base_url))
#发布时间
time_list = html_data.xpath("//li/cite[@class='last']/text()")
#print(len(time_list))
#标题
re_list = re.findall('<a href="(.*?)" title="(.*?)" class="note">',response_data)
#print(re_list)
#作者
re_auto = re.findall('data-poptype="1" target="_blank"><font>(.*?)</font></a>',response_data)
#print(re_auto)
在我们分析完我们想要爬取的数据之后剩下的好办了
import queue
import random
import re
import threading
import time
import pymysql
import requests
from fake_useragent import FakeUserAgent
from lxml import etree
ua = FakeUserAgent().random
print(ua)
urls = [
f'http://guba.eastmoney.com/default,99_{i}.html'
for i in range(1, 10 + 1)
]
headers = {
'Host': 'guba.eastmoney.com',
'Cookie': '_adsame_fullscreen_18009=1; st_si=10138147436850; qgqp_b_id=0787d1a8bd2048401b9f128543ecaab9; st_pvi=89781367033016; st_sp=2022-02-22%2013%3A38%3A10; st_inirUrl=http%3A%2F%2Fguba.eastmoney.com%2F; st_sn=7; st_psi=20220222134006993-117001300541-0535043304; st_asi=delete',
'User-Agent': ua
}
def craw(urls):
response_data = requests.get(urls, headers=headers).text
return response_data
def parse(response_data):
html_data = etree.HTML(response_data)
# num_list = html_data.xpath("//ul[@class='newlist']/li")
"""
阅读数://ul[@class='newlist']/li/cite[1]/text()
评论数://ul[@class='newlist']/li/cite[2]/text()
标题:<span class="sub">[财富号评论吧] <em class="icon icon_list_himg"></em> <a href="//caifuhao.eastmoney.com/news/20220222074924245918080" title="全球金融巨震!普京承认乌东两地区独立,俄股暴跌17%,欧股受挫" class="note">全球金融巨震!普京承认乌东两地区独立,俄股暴</a></span>
详情页url://ul[@class='newlist']/li/span/a[2]/@href
作者://li/cite[@class='aut']/a/text()
发布时间://li/cite[@class='last']/text()
"""
#阅读数
reade_num = html_data.xpath("//ul[@class='newlist']/li/cite[1]/text()")
#print(len(reade_num))
#评论数
comment_num = html_data.xpath("//ul[@class='newlist']/li/cite[2]/text()")
#详情url
base_url = html_data.xpath("//a[@class='note']/@href")
#print(len(base_url))
#发布时间
time_list = html_data.xpath("//li/cite[@class='last']/text()")
#print(len(time_list))
#标题
re_list = re.findall('<a href="(.*?)" title="(.*?)" class="note">',response_data)
#print(re_list)
#作者
re_auto = re.findall('data-poptype="1" target="_blank"><font>(.*?)</font></a>',response_data)
#print(re_auto)
# return [(reade_num[r].strip(),comment_num[r].strip(),re_list[r][1],re_list[r][0])for r in range(len(reade_num))]
# for r in range(len(reade_num)):
# readenum = reade_num[r].strip()
# commentnum = comment_num[r].strip()
# title = re_list[r][1]
# detil_url = "https://"+base_url[r]
# auto = re_auto[r].strip()
# fabutime = time_list[r].strip()
# print("阅读数:",readenum,"评论数",commentnum,"标题:", title,"详情url:",detil_url,"作者:",auto,"发布时间:",fabutime)
return [(reade_num[r].strip(), comment_num[r].strip(), re_list[r][1], "https://"+base_url[r],re_auto[r].strip(),time_list[r].strip()) for r in range(len(reade_num))]
def do_craw(url_queue:queue.Queue,html_queue:queue.Queue):
while True:
url = url_queue.get()
html = 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,file):
while True:
# 获得html_queue这个队列中的内容
html = html_queue.get()
# 解析html中的响应内容
results = parse(html)
print(results)
for result in results:
#print(result)
file.write(str(result) + '\n')
print(threading.current_thread().name, "result.size", len(results), "html_queue", html_queue.qsize())
time.sleep(random.randint(1, 2))
if __name__ == '__main__':
# 创建一个生产者队列(获取url中的响应数据)
url_queue = queue.Queue()
# 创建一个消费者对列(将获取的数据保存)
html_queue = queue.Queue()
# 遍历url
for url in urls:
# url传入生产者队列中
url_queue.put(url)
# 创建相应的生产者线程来进行工作
for idx in range(4):
t = threading.Thread(target=do_craw, args=(url_queue, html_queue), name=f"craw{idx}")
t.start()
file = open("guba.txt", "w", encoding="utf-8")
# 创建相应的消费者线程来进行工作
for index in range(3):
t = threading.Thread(target=do_parse, args=(html_queue, file), name=f"parse{index}")
t.start()
**爬取完的效果就是这样咯 **