爬虫学习
以爬取 Binance Research 为例的 Python 爬虫系统学习
一、学习目标与背景
本文以爬取
https://www.binance.com/zh-CN/research
为例,系统学习一个真实可运行的 Python 爬虫项目,目标包括:
- 正确分析接口而非盲目爬 HTML
- 自动判断分页数量,彻底摆脱
range(1,6) - 正确处理 JSON / 非 JSON 响应
- 理解并应对 403 反爬
- 构建健壮、可扩展的爬虫结构
二、为什么不能直接爬 HTML 页面
1. 问题本质
Binance Research 页面是前端渲染页面:
- HTML 中几乎没有文章数据
- 真实数据来自 后端 API 接口
- 浏览器通过 JavaScript 请求接口并渲染
2. 正确做法
- 打开浏览器开发者工具(F12)
- 切换到 Network → Fetch/XHR
- 翻页观察请求变化
- 定位返回 JSON 的接口
三、接口分析与分页机制
1. 核心接口示例
1 | https://www.binance.com/bapi/composite/v1/public/cms/article/list/query |
2. 常见请求参数
1 | { |
pageNo:页码(从 1 开始)pageSize:每页数量catalogId:Research 分类 ID
四、基础爬虫代码结构
1. 最小可运行请求
1 | import requests |
教学要点:
- 永远不要第一时间
.json() - 先确认:状态码 + Content-Type + 原始内容
五、自动判断总页数
1. 接口返回结构(简化)
1 | { |
2. 自动计算页数逻辑
1 | page_size = 20 |
至此:完全摆脱 range(1,6)
六、分页爬取示例
1 | import requests |
七、为什么会出现 JSONDecodeError
1. 本质原因
1 | resp.json() |
并不是:
“把任何响应转成 JSON”
而是:
“假设服务器返回的是 JSON”
一旦返回 HTML(403 页面),就会直接崩溃。
八、反爬与 403 的正确理解
1. 403 不是 Python 错误
- 是 服务器拒绝你
- 常见触发条件:
- 无 User-Agent
- 请求频率过快
- 地区 / IP / 风控策略
2. 应对原则
- 必须设置 headers
- 降低请求频率
- 永远检测 Content-Type
- 不要假设接口“永远正常”
九、错误与问题总结
问题 1
报错: JSONDecodeError: Expecting value
原因: 实际返回的是 HTML(403 页面),而非 JSON
解决: 调用 .json() 前先检查 status_code 和 Content-Type
问题 2
报错: status: 403 Forbidden
原因: 请求未携带浏览器特征,被反爬识别
解决: 添加 User-Agent,模拟正常浏览器请求
问题 3
问题: 只能写死 range(1,6)
原因: 未利用接口返回的 total 字段
解决: 使用 (total + pageSize - 1) // pageSize 自动计算页数
问题 4
问题: 第一页能爬,后面失败
原因: 请求过快触发风控
解决: 添加 time.sleep(),控制抓取节奏
问题5
问题:TypeError: 'NoneType' object is not subscriptable
原因:接口返回 data: null,却直接使用 data["data"]["articles"]。
解决:在访问前判断:
1 | if not data.get("data"): |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 EIGHTJIU!
评论
