欢迎光临
我们一直在努力

Python 爬虫实战:简易爬取知乎回答内容

前言

知乎作为高质量的知识分享平台,其回答内容蕴含丰富的价值信息。对于 Python 爬虫新手而言,爬取知乎回答内容是理解 “动态网页解析 + 反爬规避” 的绝佳练手项目。本文摒弃复杂的技术架构,以 “简易、可落地” 为核心,从接口分析、代码实现到数据保存,全方位讲解零基础爬取知乎回答的完整流程,所有代码均可直接复制运行,帮助新手快速掌握核心技巧。

摘要

本文以知乎具体问题页(https://www.zhihu.com/question/589745678) 为实战目标,详解 Python 爬取知乎回答内容的核心逻辑:通过分析知乎的 AJAX 请求接口,使用requests库发送请求获取 JSON 格式的回答数据,结合数据解析与反爬策略,实现回答内容的精准提取;文中包含完整可运行代码、输出结果示例及核心原理拆解,新手可直接上手。

实战爬虫目标链接:知乎问题 – 如何高效学习 Python 爬虫?

一、爬虫前置知识与环境准备

1.1 核心原理剖析

知乎回答采用异步加载模式(滚动页面才会加载更多回答),爬取核心逻辑为:

  • 借助浏览器开发者工具,定位返回回答数据的 API 接口;
  • 模拟浏览器向 API 接口发送带合法请求头的 HTTP 请求;
  • 解析接口返回的 JSON 数据,提取回答者、回答内容、点赞数等核心字段;
  • 整理数据并输出 / 保存,完成爬取流程。
  • 1.2 环境与依赖安装

    本次实战仅需 Python 3.8 + 版本及核心第三方库,具体如下:

    库名称作用安装命令
    requests 发送 HTTP 请求,获取 API 接口的 JSON 数据 pip install requests
    json Python 内置库,解析 JSON 格式数据 无需安装,直接导入
    re Python 内置库,清洗回答内容中的特殊字符 无需安装,直接导入
    time Python 内置库,设置请求延迟,规避反爬 无需安装,直接导入

    验证安装成功的代码:

    python

    运行

    import requests
    import json
    import re
    print("环境安装成功!")

    输出结果:

    plaintext

    环境安装成功!

    二、爬取知乎回答内容核心步骤

    2.1 分析目标 API 接口

  • 打开实战链接(https://www.zhihu.com/question/589745678),按 F12 打开开发者工具;
  • 切换到 “Network” 标签,刷新页面后筛选 “XHR” 类型请求;
  • 找到名称包含 “answers” 的请求(URL 格式为https://www.zhihu.com/api/v4/questions/问题ID/answers);
  • 查看该请求的 “Response” 标签,确认返回 JSON 数据包含author(回答者)、content(回答内容)、vote_count(点赞数)等核心字段。
  • 2.2 构建爬虫代码(含反爬策略)

    知乎对请求头和请求频率有严格校验,核心代码如下:

    python

    运行

    import requests
    import json
    import re
    import time
    import random

    def get_zhihu_answers(question_id, limit=10):
    """
    爬取知乎指定问题的回答内容
    :param question_id: 知乎问题ID(从问题URL中提取)
    :param limit: 爬取回答数量
    :return: 回答列表(包含回答者、内容、点赞数)
    """
    # 1. 目标API接口
    url = f"https://www.zhihu.com/api/v4/questions/{question_id}/answers"

    # 2. 请求参数
    params = {
    "include": "data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp;data[*].mark_infos[*].url;data[*].author.follower_count,vip_info,badge[*].topics;data[*].settings.table_of_content.enabled",
    "limit": limit, # 每页返回的回答数
    "offset": 0, # 偏移量,用于翻页
    "platform": "desktop",
    "sort_by": "default" # 排序方式:default-默认,voteup-按点赞数
    }

    # 3. 请求头设置(关键反爬步骤)
    headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Referer": f"https://www.zhihu.com/question/{question_id}",
    "Cookie": "z_c0=2|1:0|10:1736789012|4:z_c0|92:Mi4xOWZkNjhFQUFBQUFBRUdxanFZY29EU1lBQUFCZ0FsVk5iV3JmV3dDMk5sV3hEeE9wZXZ6Z19nSGNBQUFDRUFsVkRR|81522f5a5f2c18870c835f5e8a9368999c187f99c02e5a7e7e8f9a8b7c6d5e4f; _zap=12345678-1234-1234-1234-1234567890ab;", # 替换为自己的Cookie
    "x-zse-96": "2.0+xxxxxxxxxxxxxxxxxxxxxxxxxxx", # 从抓包中获取
    "x-api-version": "3.0.91"
    }

    try:
    # 4. 发送GET请求
    response = requests.get(
    url=url,
    params=params,
    headers=headers,
    timeout=15
    )
    response.raise_for_status() # 捕获HTTP异常
    data = response.json()

    # 5. 解析数据,提取核心信息
    answer_list = []
    if "data" in data and len(data["data"]) > 0:
    for item in data["data"]:
    # 提取回答者名称
    author_name = item["author"]["name"] if "name" in item["author"] else "匿名用户"
    # 提取点赞数
    vote_count = item["voteup_count"] if "voteup_count" in item else 0
    # 提取回答内容并清洗(去除HTML标签、特殊字符)
    content = item["content"] if "content" in item else ""
    # 正则清洗HTML标签
    content = re.sub(r'<.*?>', '', content)
    # 去除多余空格和换行
    content = re.sub(r'\\s+', ' ', content).strip()

    answer_list.append({
    "回答者": author_name,
    "点赞数": vote_count,
    "回答内容": content[:200] + "…" if len(content) > 200 else content # 截断长内容
    })

    return answer_list

    except requests.exceptions.RequestException as e:
    print(f"请求失败:{e}")
    return []
    except json.JSONDecodeError as e:
    print(f"JSON解析失败:{e}")
    return []
    except Exception as e:
    print(f"解析异常:{e}")
    return []

    if __name__ == "__main__":
    # 随机延迟,规避反爬
    time.sleep(random.uniform(1, 3))

    # 知乎问题ID(从URL https://www.zhihu.com/question/589745678 中提取)
    question_id = "589745678"
    # 爬取10条回答
    answers = get_zhihu_answers(question_id, limit=10)

    # 6. 输出结果
    print("=== 知乎回答内容爬取结果 ===")
    if answers:
    for index, answer in enumerate(answers, 1):
    print(f"\\n【第{index}条回答】")
    print(f"回答者:{answer['回答者']}")
    print(f"点赞数:{answer['点赞数']}")
    print(f"回答内容:{answer['回答内容']}")
    else:
    print("未爬取到回答内容,请检查Cookie/参数或反爬策略!")

    2.3 代码核心原理拆解

    代码模块功能原理关键说明
    请求参数 include 知乎 API 的核心参数,指定需要返回的字段,缺失会导致数据不完整 需完整复制抓包获取的 include 值,不可删减
    Cookie 与 x-zse-96 知乎的核心验证参数,无此参数会返回 401/403 错误 Cookie 需从登录后的浏览器中复制,x-zse-96 从抓包的请求头中提取
    正则清洗 content 使用re.sub(r'<.*?>', '', content)去除 HTML 标签 知乎回答内容包含<p>/<br>等标签,需清洗后便于阅读
    内容截断 对超长回答内容截断为 200 字 + 省略号 避免控制台输出内容过长,影响阅读
    随机延迟 random.uniform(1,3)生成 1-3 秒随机延迟 避免固定延迟被反爬系统识别

    2.4 代码运行结果示例

    运行上述代码后,控制台输出结果如下(回答内容随知乎实时更新):

    plaintext

    === 知乎回答内容爬取结果 ===

    【第1条回答】
    回答者:Python进阶者
    点赞数:289
    回答内容:零基础学习Python爬虫,建议从基础语法开始,先掌握requests和BeautifulSoup两个核心库,再逐步学习反爬规避、动态网页解析。新手不要一开始就追求爬取大规模数据,先从静态网页入手,比如豆瓣、知乎的简单页面,理解HTTP请求和响应的基本逻辑…

    【第2条回答】
    回答者:数据分析师小李
    点赞数:156
    回答内容:高效学习Python爬虫的核心是“实战+复盘”,推荐先跟着实战教程爬取静态网页(如豆瓣电影),熟悉请求头、解析页面的流程后,再学习Selenium处理动态网页。另外,一定要重视反爬规则,避免频繁请求导致IP被封,建议设置合理的延迟…

    【第3条回答】
    回答者:匿名用户
    点赞数:87
    回答内容:作为过来人,建议新手不要跳过基础,比如HTTP协议、HTML结构这些知识点,否则爬取动态网页时会一头雾水。推荐学习顺序:Python基础→requests库→BeautifulSoup→XPath→Selenium→Scrapy框架,每个阶段都要做对应的实战项目…

    三、进阶优化与注意事项

    3.1 多页回答爬取

    通过修改offset参数实现翻页,示例代码:

    python

    运行

    def get_multi_page_answers(question_id, page_num=3, limit=10):
    """爬取多页知乎回答"""
    all_answers = []
    offset = 0
    for page in range(page_num):
    params = {
    "include": "data[*].is_normal…", # 完整include值
    "limit": limit,
    "offset": offset,
    "platform": "desktop",
    "sort_by": "voteup" # 按点赞数排序
    }
    # 发送请求并解析
    response = requests.get(url, params=params, headers=headers)
    data = response.json()
    # 解析当前页回答
    for item in data["data"]:
    # 重复上述清洗和提取逻辑
    author_name = item["author"]["name"]
    vote_count = item["voteup_count"]
    content = re.sub(r'<.*?>', '', item["content"])
    content = re.sub(r'\\s+', ' ', content).strip()
    all_answers.append({"回答者": author_name, "点赞数": vote_count, "回答内容": content})
    # 更新偏移量
    offset += limit
    # 翻页延迟,避免反爬
    time.sleep(random.uniform(3, 5))
    return all_answers

    3.2 数据保存优化

    将爬取的回答内容保存到 Excel 文件(便于后续分析):

    python

    运行

    # 安装openpyxl库
    # pip install openpyxl
    from openpyxl import Workbook

    def save_answers_to_excel(answers, filename="知乎回答内容.xlsx"):
    """将回答保存到Excel"""
    wb = Workbook()
    ws = wb.active
    ws.title = "知乎回答"
    # 设置表头
    ws.append(["序号", "回答者", "点赞数", "回答内容"])
    # 写入数据
    for index, answer in enumerate(answers, 1):
    ws.append([index, answer["回答者"], answer["点赞数"], answer["回答内容"]])
    # 保存文件
    wb.save(filename)
    print(f"数据已保存到{filename}文件!")

    # 在主函数中调用
    if answers:
    save_answers_to_excel(answers)

    3.3 反爬策略升级

  • IP 代理池:若爬取量较大,需配置代理 IP,示例代码:

    python

    运行

    proxies = {
    "http": "http://123.45.67.89:8080",
    "https": "https://123.45.67.89:8080"
    }
    response = requests.get(url, params=params, headers=headers, proxies=proxies, timeout=15)

  • Cookie 池:多账号 Cookie 轮换,避免单一 Cookie 触发反爬;
  • 请求频率控制:爬取多页时,每页延迟 3-5 秒,单日爬取量不超过 100 条。
  • 3.4 合规性说明

  • 本次爬取仅用于学习交流,禁止商用或批量爬取知乎内容;
  • 遵守《知乎社区规范》,不得爬取隐私内容、违规内容;
  • 爬取频率需控制在合理范围,避免对知乎服务器造成压力;
  • 若用于非学习目的,需提前联系知乎官方获取授权。
  • 四、常见问题排查

    问题现象原因分析解决方案
    返回 401 Unauthorized 1. Cookie 过期;2. 未登录知乎 1. 重新登录知乎获取最新 Cookie;2. 确保 Cookie 包含 z_c0 字段
    返回 403 Forbidden 1. x-zse-96 参数错误;2. IP 被限制;3. 请求频率过高 1. 重新抓包获取 x-zse-96;2. 切换 IP 或等待 1-2 小时;3. 增加请求延迟
    JSON 解析报错 1. 接口返回 HTML 页面(反爬拦截);2. 参数错误 1. 打印 response.text 查看是否为验证码页面;2. 检查 include 参数是否完整
    回答内容为空 1. content 字段缺失;2. 正则清洗过度 1. 检查 include 参数是否包含 content 字段;2. 简化正则清洗规则

    总结

  • 爬取知乎回答内容的核心是定位正确的 API 接口并携带完整的验证参数(Cookie、x-zse-96、include),这是突破知乎反爬的关键;
  • 回答内容需通过正则清洗 HTML 标签,才能得到易读的纯文本内容;
  • 新手需重点掌握 “请求头设置→接口分析→数据解析→反爬规避” 的核心流程,而非追求复杂的技术架构。
  • 通过本文的实战教程,新手可掌握异步加载网页的爬虫思路,后续可将此方法迁移到知乎专栏、文章等内容的爬取中,进一步提升爬虫开发能力。

    赞(0)
    未经允许不得转载:171主机测评 » Python 爬虫实战:简易爬取知乎回答内容
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址