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

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

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

定义一个全局变量,用于存储分类结果

categories = Counter()

定义一个函数,用于根据文本内容进行分类

def classify(text):

# 这里可以使用任何文本分类的方法,例如正则表达式、机器学习等
# 这里为了简单起见,只使用了简单的字符串匹配
if "Python" in text:
    return "Python"
elif "Java" in text:
    return "Java"
elif "C++" in text:
    return "C++"
else:
    return "Other"

async def fetch_page(url, proxy):

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

async def main():
urls = ["https://www.baidu.com/s?wd=" + str(i) for i in range(10)] # 生成十个百度搜索网址

# 假设有一个文件 16yun.txt,每行存储一个代理host和端口,例如 www.16yun.cn:3333
# 读取文件中的所有代理,并存储在一个列表中
with open("16yun.txt") as f:
    proxies = [line.strip() for line in f]

tasks = [] # 创建一个空列表,用于存储 task 对象

# 遍历 urls 和 proxies 列表,为每个 url 配对一个 proxy,并创建 task 对象
for url, proxy in zip(urls, proxies):
    task = asyncio.create_task(fetch_page(url, proxy))
    tasks.append(task)

results = await asyncio.gather(*tasks) # 同时运行所有 task 并获取结果

# 创建一个线程池,用于执行分类任务
pool = threading.ThreadPoolExecutor(max_workers=4)

for result in results:
    print(result[:100]) # 打印每个网页的前 100 个字符

    # 使用线程池提交一个分类任务,并更新全局变量 categories
    category = pool.submit(classify, result).result()
    categories[category] += 1

# 关闭线程池并等待所有任务完成
pool.shutdown(wait=True)

# 打印最终的分类结果
print(categories)

asyncio.run(main()) # 运行主协程
```

相关文章
|
6月前
|
Java 索引
多线程向设备发送数据
多线程向设备发送数据
104 0
|
6月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
消息中间件 监控 安全
服务Down机了,线程池中的数据如何保证不丢失?
在分布式系统与高并发应用开发中,服务的稳定性和数据的持久性是两个至关重要的考量点。当服务遭遇Down机时,如何确保线程池中处理的数据不丢失,是每一位开发者都需要深入思考的问题。以下,我将从几个关键方面分享如何在这种情况下保障数据的安全与完整性。
321 2
|
消息中间件 监控 Java
线程池关闭时未完成的任务如何保证数据的一致性?
保证线程池关闭时未完成任务的数据一致性需要综合运用多种方法和机制。通过备份与恢复、事务管理、任务状态记录与恢复、数据同步与协调、错误处理与补偿、监控与预警等手段的结合,以及结合具体业务场景进行分析和制定策略,能够最大程度地确保数据的一致性,保障系统的稳定运行和业务的顺利开展。同时,不断地优化和改进这些方法和机制,也是提高系统性能和可靠性的重要途径。
340 62
|
11月前
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
|
11月前
|
缓存 安全 Java
面试中的难题:线程异步执行后如何共享数据?
本文通过一个面试故事,详细讲解了Java中线程内部开启异步操作后如何安全地共享数据。介绍了异步操作的基本概念及常见实现方式(如CompletableFuture、ExecutorService),并重点探讨了volatile关键字、CountDownLatch和CompletableFuture等工具在线程间数据共享中的应用,帮助读者理解线程安全和内存可见性问题。通过这些方法,可以有效解决多线程环境下的数据共享挑战,提升编程效率和代码健壮性。
376 6
|
10月前
|
数据采集 存储 安全
Python爬虫实战:利用短效代理IP爬取京东母婴纸尿裤数据,多线程池并行处理方案详解
本文分享了一套结合青果网络短效代理IP和多线程池技术的电商数据爬取方案,针对京东母婴纸尿裤类目商品信息进行高效采集。通过动态代理IP规避访问限制,利用多线程提升抓取效率,同时确保数据采集的安全性和合法性。方案详细介绍了爬虫开发步骤、网页结构分析及代码实现,适用于大规模电商数据采集场景。
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
367 57
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
1049 0

热门文章

最新文章