找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1106|回复: 0

多线程+代理池如何爬取新闻数据

[复制链接]

93

主题

6

回帖

113

积分

初中生

热心值
2
IT币
595
贡献值
1
QQ
发表于 2023-6-26 16:25:28 | 显示全部楼层 |阅读模式
说到数据爬取,大部分人都会想到使用Scrapy工具,但是仅仅停留在会使用的阶段。但是要真正的成为技术大牛,需要学会更多的爬虫技术,对于爬虫来说突破各种网站的反爬机制也是需要技术能力的。所以今天为了增加对目标网站爬虫机制的理解,我们可以通过手动实现多线程的爬虫过程,同时,引入IP代理池进行基本的反爬操作。
本次使用腾讯新闻网进行爬虫,该网站具有反爬机制,同时数量足够大,多线程效果较为明显。
需要使用到的技术如下
  • IP代理池
  • 多线程
  • 爬虫与反爬
首先,开始分析新闻网的一些数据。经过抓包分析,可知:.[url]https://new.qq.com/d/cd/[/url]包含所有新闻数据同时,该地址具有反爬机制,多次访问将会失败的情况。
分析完目标网站的网的数据后,搭建IP代理池,用于反爬作用。由于使用的代理商提供了参考demo,所以本代码里面直接使用的是代理商提供的代码。搭建完IP代理池后,我们开始着手多线程爬取数据的工作。一旦使用多线程,则需要考虑到数据的读写顺序问题。这里使用python中的队列queue进行存储新闻代码,不同线程分别从这个queue中获取新闻代码,并访问指定新闻的数据。由于queue的读取和写入是阻塞的,所以可以确保该过程不会出现读取重复和读取丢失新闻代码的,实现过程如下:
  1. import asyncio
  2. import aiohttp
  3. import threading
  4. from collections import Counter

  5. # 定义一个全局变量,用于存储分类结果
  6. categories = Counter()

  7. # 定义一个函数,用于根据文本内容进行分类
  8. def classify(text):
  9.     # 这里可以使用任何文本分类的方法,例如正则表达式、机器学习等
  10.     # 这里为了简单起见,只使用了简单的字符串匹配
  11.     if "Python" in text:
  12.         return "Python"
  13.     elif "Java" in text:
  14.         return "Java"
  15.     elif "C++" in text:
  16.         return "C++"
  17.     else:
  18.         return "Other"

  19. async def fetch_page(url, proxy):
  20.     # 创建一个 aiohttp 的 ClientSession 对象,并指定代理IP和端口
  21.     async with aiohttp.ClientSession(proxy=proxy) as session:
  22.         # 使用 session.get 方法发送请求,并获取响应对象
  23.         async with session.get(url) as response:
  24.             # 返回响应的文本内容
  25.             return await response.text()

  26. async def main():
  27.     urls = ["https://www.baidu.com/s?wd=" + str(i) for i in range(10)] # 生成十个百度搜索网址
  28.    
  29.     # 假设有一个文件 16yun.txt,每行存储一个代理host和端口,例如 it帮论坛真好:3333
  30.     # 读取文件中的所有代理,并存储在一个列表中
  31.     with open("16yun.txt") as f:
  32.         proxies = [line.strip() for line in f]
  33.    
  34.     tasks = [] # 创建一个空列表,用于存储 task 对象
  35.    
  36.     # 遍历 urls 和 proxies 列表,为每个 url 配对一个 proxy,并创建 task 对象
  37.     for url, proxy in zip(urls, proxies):
  38.         task = asyncio.create_task(fetch_page(url, proxy))
  39.         tasks.append(task)
  40.    
  41.     results = await asyncio.gather(*tasks) # 同时运行所有 task 并获取结果
  42.    
  43.     # 创建一个线程池,用于执行分类任务
  44.     pool = threading.ThreadPoolExecutor(max_workers=4)
  45.    
  46.     for result in results:
  47.         print(result[:100]) # 打印每个网页的前 100 个字符
  48.         
  49.         # 使用线程池提交一个分类任务,并更新全局变量 categories
  50.         category = pool.submit(classify, result).result()
  51.         categories[category] += 1
  52.    
  53.     # 关闭线程池并等待所有任务完成
  54.     pool.shutdown(wait=True)
  55.    
  56.     # 打印最终的分类结果
  57.     print(categories)

  58. asyncio.run(main()) # 运行主协程
复制代码



ITbang.Net是一个IT教程分享社区!

寻找论坛资源请善用论坛搜索功能,这样会为你节约不少学习时间;

论坛资源如有过期链接失效等,请到教程反馈区发帖反馈,我们会为您良好的行为点赞加分!

回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

免责声明:
IT帮论坛所发布的一切视频资源、工具软件和网络技术相关的文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该资源,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:Service@ITbang.Net

QQ|Archiver|手机版|小黑屋|IT帮社区 ( 冀ICP备19002104号-2 )

GMT+8, 2025-5-4 01:19 , Processed in 0.207677 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表