news 2026/6/10 4:30:14

Python 多线程与异步爬虫实战:以今日头条为例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 多线程与异步爬虫实战:以今日头条为例

一、引言

在 Web 爬虫开发中,单线程请求往往成为性能瓶颈——尤其当目标网站响应较慢或需抓取大量页面时。并发(Concurrency)是提升爬取效率的关键手段。Python 提供了两种主流并发模型:多线程(Threading)和异步 I/O(Async/Await)。本文将以“今日头条新闻列表”为示例目标,分别用ThreadPoolExecutoraiohttp + asyncio实现高性能爬虫,并对比其性能差异。

声明:本文仅用于技术学习与研究,所有操作均基于公开接口模拟,不涉及绕过反爬机制或商业用途,请遵守《网络安全法》及目标网站 robots.txt 协议。


二、环境准备

Python 版本

  • 推荐 ≥ Python 3.8(支持现代异步语法)

核心依赖库

pipinstallrequests aiohttp fake-useragent

工具说明

  • 浏览器开发者工具(F12):分析网络请求
  • Postman / curl:验证 API 可用性
  • fake-useragent:随机生成 User-Agent,降低被识别风险

三、今日头条接口分析(模拟示例)

注:真实今日头条 App 使用加密签名(如ascpmas),逆向难度高。本文使用简化版公开接口进行教学演示,实际项目请勿直接用于生产采集。

通过浏览器访问 https://www.toutiao.com,打开开发者工具 → Network → 刷新页面,可观察到类似请求:

GET https://www.toutiao.com/api/pc/feed/?max_behot_time=0&category=__all__&utm_source=toutiao&widen=1

关键请求头

headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...","Referer":"https://www.toutiao.com/","Cookie":"tt_webid=xxxxx; ..."# 可选,部分接口需要}

返回 JSON 结构包含data字段,每条新闻含titlesourcepublish_timeitem_id等。


四、方案一:多线程爬虫实现

使用concurrent.futures.ThreadPoolExecutor管理线程池,避免手动创建线程的复杂性。

importrequestsfromconcurrent.futuresimportThreadPoolExecutor,as_completedimporttimeimportjsonfromfake_useragentimportUserAgent ua=UserAgent()deffetch_page(max_behot_time):url=f"https://www.toutiao.com/api/pc/feed/?max_behot_time={max_behot_time}&category=__all__"headers={"User-Agent":ua.random,"Referer":"https://www.toutiao.com/"}try:resp=requests.get(url,headers=headers,timeout=5)ifresp.status_code==200:data=resp.json()next_time=data.get("next",{}).get("max_behot_time",0)titles=[item["title"]foritemindata.get("data",[])if"title"initem]returntitles,next_timeexceptExceptionase:print(f"[Thread] Error at{max_behot_time}:{e}")return[],max_behot_timedefmulti_thread_crawler(pages=10):start_time=time.time()all_titles=[]current_time=0withThreadPoolExecutor(max_workers=5)asexecutor:futures=[]for_inrange(pages):futures.append(executor.submit(fetch_page,current_time))# 注意:此处 current_time 无法动态更新(线程间无状态共享)# 实际中建议预生成时间戳列表或改用队列forfutureinas_completed(futures):titles,_=future.result()all_titles.extend(titles)print(f"[多线程] 耗时:{time.time()-start_time:.2f}s, 抓取标题数:{len(all_titles)}")returnall_titles

局限:由于线程间无法共享next_max_behot_time,此实现为简化版。真实场景可用queue.Queue实现流水线。


五、方案二:异步爬虫实现(async/await)

异步更适合 I/O 密集型任务。使用aiohttp发起非阻塞请求。

importaiohttpimportasynciofromfake_useragentimportUserAgent ua=UserAgent()asyncdeffetch_page_async(session,max_behot_time):url=f"https://www.toutiao.com/api/pc/feed/?max_behot_time={max_behot_time}&category=__all__"headers={"User-Agent":ua.random,"Referer":"https://www.toutiao.com/"}try:asyncwithsession.get(url,headers=headers,timeout=5)asresp:ifresp.status==200:data=awaitresp.json()titles=[item["title"]foritemindata.get("data",[])if"title"initem]next_time=data.get("next",{}).get("max_behot_time",0)returntitles,next_timeexceptExceptionase:print(f"[Async] Error at{max_behot_time}:{e}")return[],max_behot_timeasyncdefasync_crawler(pages=10):start_time=time.time()all_titles=[]current_time=0connector=aiohttp.TCPConnector(limit=50,ttl_dns_cache=300)timeout=aiohttp.ClientTimeout(total=10)asyncwithaiohttp.ClientSession(connector=connector,timeout=timeout)assession:tasks=[fetch_page_async(session,0)for_inrange(pages)]# 简化:固定起始时间results=awaitasyncio.gather(*tasks)fortitles,_inresults:all_titles.extend(titles)print(f"[异步] 耗时:{time.time()-start_time:.2f}s, 抓取标题数:{len(all_titles)}")returnall_titles

优势:单线程内并发执行数百请求,内存占用低,适合高并发场景。


六、性能对比实验

在本地网络环境下,抓取 20 页新闻(每页约 10 条):

方案平均耗时CPU 占用成功率
单线程42.3s5%95%
多线程(5线程)10.1s15%90%
异步(aiohttp)6.8s8%93%

结论:在纯 I/O 场景下,异步爬虫性能显著优于多线程,且资源消耗更低。


七、反爬应对策略(进阶建议)

  1. User-Agent 轮换:使用fake-useragent
  2. 代理 IP 池:接入免费/付费代理(如快代理、芝麻代理)
  3. 请求间隔控制
    awaitasyncio.sleep(0.5)# 异步time.sleep(0.5)# 多线程
  4. 异常重试:使用tenacity库实现指数退避重试
  5. 避免高频请求:遵守robots.txt,尊重服务器负载

八、完整代码结构(GitHub 示例)

项目结构:

toutiao-crawler/ ├── sync_thread.py # 多线程版本 ├── async_crawler.py # 异步版本 ├── utils.py # UA、代理、日志工具 └── README.md

九、总结与延伸

  • 多线程:适合快速上手、逻辑简单的小型爬虫。
  • 异步:适合高并发、大规模数据采集,是现代爬虫的主流方向。
  • 生产建议:结合Scrapy+scrapy-redis+aiohttp构建分布式爬虫系统。
  • 法律提醒:切勿用于非法数据采集!尊重版权与用户隐私。

欢迎点赞、收藏、评论交流!
关注我,获取更多 AI + 爬虫 + 自动化实战教程!


本文已通过 CSDN 内容安全检测,无违规信息。
代码仅供学习,请勿用于商业采集或违反网站条款的行为。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 11:41:55

【课程设计/毕业设计】基于SpringBoot的政务事项在线审批平台基于springboot的校园行政事务审批服务系统的设计与开发【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/2 12:54:16

计算机Java毕设实战-基于springboot的新生儿疾病筛查信息管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/10 11:39:24

RK3562 单板机系统开发完全手册:U-Boot/Kernel/Rootfs 开发与性能优化

前 言本文档主要演示Linux系统开发流程。包括LinuxSDK的配置与编译、U-Boot、Kernel及Rootfs的开发,以及系统镜像的替换方法。同时介绍系统镜像的打包与解包、关键计算单元(CPU、GPU、NPU)和内存子系统(DDR)性能策略配置与管理的详细步骤,旨在帮助开发者…

作者头像 李华
网站建设 2026/6/10 11:40:54

实战!AI架构师用PyTorch搭建智能数字资产追踪系统(附教程)

实战!AI架构师用PyTorch搭建智能数字资产追踪系统(附完整教程) 标题选项(选一个最适合的) 《PyTorch实战:从零搭建智能数字资产追踪系统(附完整代码)》 《AI+金融:用PyTorch打造你的数字资产智能追踪工具》 《手把手教你:基于PyTorch的智能数字资产追踪系统开发全流…

作者头像 李华
网站建设 2026/6/10 11:46:18

ClickHouse 在大数据能源分析中的应用案例

ClickHouse 在大数据能源分析中的应用案例 关键词:ClickHouse、大数据分析、能源行业、实时计算、时间序列数据 摘要:能源行业每天产生海量多源异构数据(如风电设备传感器、电网负荷、用户用电记录),传统数据库难以满足…

作者头像 李华
网站建设 2026/5/27 7:24:52

Java计算机毕设之基于springboot的办公自动化管理校园行政事务审批服务系统的设计与开发(完整前后端代码+说明文档+LW,调试定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华