当前位置: 首页 > news >正文

Python爬取知乎评论:多线程与异步爬虫的性能优化

1. 知乎评论爬取的技术挑战

知乎的评论数据通常采用动态加载(Ajax),这意味着直接使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests</font>**+**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">BeautifulSoup</font>**无法获取完整数据。此外,知乎还设置了反爬机制,包括:

  • 请求头(Headers)验证(如**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">User-Agent</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Referer</font>**
  • Cookie/Session 校验(未登录用户只能获取部分数据)
  • 频率限制(频繁请求可能导致IP被封)

因此,我们需要:

  1. 模拟浏览器请求(携带Headers和Cookies)
  2. 解析动态API接口(而非静态HTML)
  3. 优化爬取速度(多线程/异步)

2. 获取知乎评论API分析

(1)查找评论API

打开知乎任意一个问题(如 **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">https://www.zhihu.com/question/xxxxxx</font>**),按**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">F12</font>**进入开发者工具,切换到**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Network</font>**选项卡,筛选**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">XHR</font>**请求

(2)解析评论数据结构

评论通常嵌套在**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">data</font>**字段中,结构如下:

{"data": [{"content": "评论内容","author": { "name": "用户名" },"created_time": 1620000000}],"paging": { "is_end": false, "next": "下一页URL" }
}

我们需要递归翻页(**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">paging.next</font>**)爬取所有评论。

3. Python爬取知乎评论的三种方式

(1)单线程爬虫(基准测试)

使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests</font>**库直接请求API,逐页爬取:

import requests
import timedef fetch_comments(question_id, max_pages=5):base_url = f"https://www.zhihu.com/api/v4/questions/{question_id}/answers"headers = {"User-Agent": "Mozilla/5.0","Cookie": "你的Cookie"  # 登录后获取}comments = []for page in range(max_pages):url = f"{base_url}?offset={page * 10}&limit=10"resp = requests.get(url, headers=headers).json()for answer in resp["data"]:comments.append(answer["content"])time.sleep(1)  # 避免请求过快return commentsstart_time = time.time()
comments = fetch_comments("12345678")  # 替换为知乎问题ID
print(f"单线程爬取完成,耗时:{time.time() - start_time:.2f}秒")

缺点:逐页请求,速度慢(假设每页1秒,10页需10秒)。

(2)多线程爬虫(ThreadPoolExecutor)

使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">concurrent.futures</font>**实现多线程并发请求:

from concurrent.futures import ThreadPoolExecutordef fetch_page(page, question_id):url = f"https://www.zhihu.com/api/v4/questions/{question_id}/answers?offset={page * 10}&limit=10"headers = {"User-Agent": "Mozilla/5.0"}resp = requests.get(url, headers=headers).json()return [answer["content"] for answer in resp["data"]]def fetch_comments_multi(question_id, max_pages=5, threads=4):with ThreadPoolExecutor(max_workers=threads) as executor:futures = [executor.submit(fetch_page, page, question_id) for page in range(max_pages)]comments = []for future in futures:comments.extend(future.result())return commentsstart_time = time.time()
comments = fetch_comments_multi("12345678", threads=4)
print(f"多线程爬取完成,耗时:{time.time() - start_time:.2f}秒")

优化点

  • 线程池控制并发数(避免被封)
  • 比单线程快约3-4倍(4线程爬10页仅需2-3秒)

(3)异步爬虫(Asyncio + aiohttp)

使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">aiohttp</font>**实现异步HTTP请求,进一步提高效率:

import aiohttp
import asyncio
import time# 代理配置
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"async def fetch_page_async(session, page, question_id):url = f"https://www.zhihu.com/api/v4/questions/{question_id}/answers?offset={page * 10}&limit=10"headers = {"User-Agent": "Mozilla/5.0"}async with session.get(url, headers=headers) as resp:data = await resp.json()return [answer["content"] for answer in data["data"]]async def fetch_comments_async(question_id, max_pages=5):# 设置代理连接器proxy_auth = aiohttp.BasicAuth(proxyUser, proxyPass)connector = aiohttp.TCPConnector(limit=20,  # 并发连接数限制force_close=True,enable_cleanup_closed=True,proxy=f"http://{proxyHost}:{proxyPort}",proxy_auth=proxy_auth)async with aiohttp.ClientSession(connector=connector) as session:tasks = [fetch_page_async(session, page, question_id) for page in range(max_pages)]comments = await asyncio.gather(*tasks)return [item for sublist in comments for item in sublist]if __name__ == "__main__":start_time = time.time()comments = asyncio.run(fetch_comments_async("12345678"))  # 替换为知乎问题IDprint(f"异步爬取完成,耗时:{time.time() - start_time:.2f}秒")print(f"共获取 {len(comments)} 条评论")

优势

  • 无GIL限制,比多线程更高效
  • 适合高并发IO密集型任务(如爬虫)

4. 性能对比与优化建议

爬取方式10页耗时(秒)适用场景
单线程~10少量数据,简单爬取
多线程(4线程)~2.5中等规模,需控制并发
异步(Asyncio)~1.8大规模爬取,高并发需求

优化建议

  1. 控制并发数:避免触发反爬(建议10-20并发)。
  2. 随机延迟**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">time.sleep(random.uniform(0.5, 2))</font>** 模拟人类操作。
  3. 代理IP池:防止IP被封(如使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests</font>**+**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">ProxyPool</font>**)。
  4. 数据存储优化:异步写入数据库(如**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">MongoDB</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">MySQL</font>**)。
http://www.dtcms.com/a/269457.html

相关文章:

  • React18+TypeScript状态管理最佳实践
  • Jenkins 使用宿主机的Docker
  • 深入解析 structuredClone API:现代JS深拷贝的终极方案
  • Ubuntu 版本号与别名对照表(部分精选)
  • Java使用接口AES进行加密+微信小程序接收解密
  • Linux Ubuntu系统下载
  • Docker企业级应用:从入门到生产环境最佳实践
  • any实现(基于LLVM中libcxx实现分析)
  • 深入理解Java虚拟机(JVM):从内存管理到性能优化
  • 基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(1)搭建框架基本雏形
  • C++11标准库算法:深入理解std::find, std::find_if与std::find_if_not
  • iOS Widget 开发-3:Widget 的种类与尺寸(主屏、锁屏、灵动岛)
  • el-button传入icon用法可能会出现的问题
  • Unity开发如何解决iOS闪退问题
  • 数据分析-59-SPC统计过程控制XR图和XS图和IMR图和CPK分析图
  • 手机解压软件 7z:高效便捷的解压缩利器
  • 【机器学习笔记 Ⅲ】5 强化学习
  • C++异步编程入门
  • JVM 基础 - 类字节码详解
  • 编码器(Encoder)和解码器(Decoder)
  • 你好,你的小程序实际运营内容与名称简介不符,请上架符合小程序名称简介描述的正式内容/商品,或修改名称简介并保持服务内容与图文一致。
  • 【Linux】Redis 6.2.6 的二进制部署【适用于多版本】
  • Java 导出pdf 写出demo 1、需要设置自定义页眉和文字 2、可以插入表格 3、可以插入图片
  • MSPM0G3519-PA23 引脚无法使用
  • 小米YU7预售现象深度解析:智能电动汽车的下一个范式革命
  • Vue、Laravel 项目初始化命令对比 / curl 命令/ CORS 机制总结与案例
  • react的条件渲染【简约风5min】
  • Rust 仿射类型(Affine Types)
  • 在 Vue2 与 Vue3 中,面对 **大数据量交互体验优化** 和 **ECharts 大数据渲染性能优化**
  • 文风写作模仿各种公文范文快速生成初稿