跳转至

14.3 爬虫:知乎话题精华(Ajax 数据接口)

内容梗概

本课是爬虫实战的第三例,讲解第三种页面形态——数据接口型。以知乎"美食"话题的"精华"页为例:页面初始只加载 5 个回答,下拉滚动条会不断加载新内容,这正是上节课讲的 Ajax 机制——浏览器向后台数据接口发 HTTP 请求,服务器返回 JSON 再渲染。老师演示了用开发者工具 Network 标签页的 XHR 过滤器定位 Ajax 请求,通过 Preview 确认返回的是规整 JSON(含 data 和 paging 分页信息),再分析接口 URL 的参数结构(include/offset/limit),最后用 Python requests + UA 伪装直接请求接口、用内置 json 库解析为字典,拿到精华回答数据。整节课强调的重点不是代码本身,而是"分析—猜测—验证"的完整工作流程。

知识点详解

Ajax 数据接口现象(约 00:00 - 02:30)

  • 知乎话题精华页:F12 检查可见 list div 里初始只有 5 个回答;下拉滚动条到一定位置会新增加载更多回答,可一直往下拉。
  • 原理:下拉时浏览器通过 Ajax 向服务器发新 HTTP 请求,服务器返回 JSON 数据,前端据此渲染新内容——这就是"数据接口"。

Network 面板与 XHR 过滤器(约 02:30 - 04:00)

  • 在开发者工具 Network 标签页观察实际请求流程。
  • Filter(过滤器):可按 URL 正则过滤,也可按请求类型分类过滤。
  • Ajax 请求单独分类为 XHR / Fetch(XHR 是老版 Ajax 的 JavaScript 方法,Fetch 是新版);观察 Ajax 过程要点开 XHR 过滤器(约 03:25)。

确认数据接口(约 04:00 - 08:20)

  • 过滤后看到规律出现的可疑请求,点开查看:
  • Header 标签页:请求/响应的头部参数;
  • Response 标签页:返回内容,一长串很像 JSON;
  • Preview 标签页:自动按格式解析(HTML 按 HTML 解析、JSON 按 JSON 解析),展开后 0~9 共 10 个元素,规整清晰——推断就是 10 个回答。
  • 刷新页面(Ctrl+R)验证该请求确实出现。
  • JSON 结构:除 data(10 个回答)外还有 paging 分页段——is_end 表示是否最后一页,并给出上一页/下一页的链接,由此完全确定这就是要找的数据接口(约 06:40)。
  • 逐条查看回答:target 里包含作者、内容、类型(answer)、链接等,且 URL 很规范(api、第 4 版、answers、答案编号)。
  • 验证接口可直接访问:把 paging 里的 next URL 复制到地址栏回车,直接看到 JSON;或对请求右键 Copy link address 粘贴访问(约 08:50)。返回中 \uXXXX 是中文的 Unicode 编码。

Python 环境准备(约 11:15 - 13:30)

  • exit 退出上一个虚拟环境;回上级目录 mkdir 知乎 并进入;Ctrl+R 搜索历史命令执行 pipenv install -i ... 初始化环境;pipenv shell 进入。
  • 本例只需装 requests——不需要 BeautifulSoup,因为直接解析 JSON 用 Python 内置的 json 库即可。
  • 老师重复环境流程是"强化记忆":仍有同学没搞清楚 pipenv 怎么用。

分析接口 URL 参数(约 13:30 - 18:40)

  • 回顾 URL 结构:https:// 协议 + 域名 + path(路径) + ? 后的参数,参数之间用 & 分隔。
  • 接口链接虽超长,但按 & 拆分后只有三个参数:
  • include:告诉服务器返回的 JSON 里要带哪些字段(是否含 content、comment_count 等);删掉它世界清静,返回内容会大幅减少(约 16:40)。
  • offset:偏移量,从第几个回答开始返回(如 =5 从第 5 个开始)。
  • limit:一次返回多少条(如 =10)。
  • 实验:offset=0&limit=20 可从开头返回 20 条;limit=100 会报错(约 18:00)。
  • 方法论:参数含义是**猜出来再试出来**的——"你得学会去猜,然后去试、去实验"。

Python 抓取与解析(约 18:40 - 24:30)

  • 示例代码使用 User-Agent 伪装(headers 参数把 UA 改成浏览器)。
  • 对比实验:不加 UA 直接 requests.get(url) 打印 .text → 返回 400 Bad Request(服务器识别出爬虫拒绝服务);加上 UA 伪装成浏览器 → 正常返回 JSON 串(含问题标题、点赞数等)(约 21:00 - 22:20)。
  • 解析:用内置 json 模块的 json.loads(...) 把 JSON 字符串转成 Python 字典(约 22:30);转成字典后 print 时 Unicode 编码的中文自动还原为可读中文。
  • 抓到的就是美食话题精华回答,可进一步提取正文关键词做分析。
  • 警告:请求频率太快马上会被封。

课程小结(约 24:26 - 25:37)

  • 三种朴素实例(静态页、动态页、数据接口)演示完毕,是对上节课理论的补充。
  • 老师希望学生关注的核心是**整个工作流程**:怎么思考、怎么分析、怎么查文档(他自己也要查,背不下来)——理解每一步在干什么,不要照着敲,否则必出各种 bug。

示例与演示

  • 演示目标:不登录状态下抓取知乎"美食"话题精华回答。
  • 演示步骤:
  • 浏览器观察精华页的滚动加载现象;
  • Network → XHR 过滤 → Preview 确认 JSON 数据接口;
  • 复制 next 链接在地址栏直接访问验证;
  • 分析 URL 三参数(include/offset/limit)并做删改实验;
  • Python:requests + UA 伪装请求接口 → json.loads 转字典 → 读取回答数据。
  • 关键对比:无 UA → 400 Bad Request;有 UA → 正常 JSON。

重点与难点

  • 数据接口型页面的抓取思路:不用解析 HTML,直接从 Network/XHR 里找到返回 JSON 的接口,向接口发请求即可——这是三种形态中最"干净"的一种。
  • Preview 标签页是确认 JSON 的利器;paging(is_end、next)是判断分页规律的钥匙。
  • URL 参数分析能力:按 ? 和 & 拆解,猜参数含义并做删改实验验证。
  • UA 伪装在接口抓取中同样必需(知乎无 UA 返回 400)。
  • 频率控制:接口抓取频率过高会被封。
  • 学习方法:重点是掌握分析流程与查文档的习惯,而不是背代码。

关联内容

  • 前置:上节课(13.x)讲的 Ajax/JSON 概念与滚动加载原理;14.1 的 requests + UA 伪装、pipenv 流程;Python 字典操作。
  • 三种页面形态对比:静态页(14.1 B 站)、动态渲染页(14.2 网易云)、数据接口页(本课知乎)——构成爬虫选型的完整决策链。
  • 后续:14.4 用 Scrapy 框架把本课的知乎接口做成可持续翻页抓取的工程化爬虫(start_urls、parse、分页、存 CSV)。