前言
今日头条作为头部资讯平台,汇聚了海量图文内容,其标题不仅是内容的核心概括,更是数据分析、内容创作参考的重要素材。本文针对零基础学习者,从原理拆解、环境搭建到代码实现,全方位讲解爬取今日头条图文标题的完整流程,所有代码均可直接运行,同时兼顾反爬策略与数据合规性,帮助新手快速掌握动态网页爬虫的核心技巧。
摘要
本文以**今日头条图文资讯页(https://www.toutiao.com/native/category/feed/?cate_code=news_hot)**为实战目标,详解 Python 爬虫爬取图文标题的全过程:针对今日头条的动态渲染特性,采用 requests 库结合 json 解析(规避复杂的 JS 渲染解析),实现图文标题的精准提取;文中包含完整可运行代码、输出结果示例、核心原理拆解及常见问题解决方案,新手可直接上手。
实战爬虫目标链接:今日头条热点图文资讯
一、爬虫前置知识与环境准备
1.1 核心原理剖析
今日头条采用前后端分离架构,页面内容通过 AJAX 异步加载(而非传统 HTML 静态渲染),因此爬取核心逻辑为:
- 分析网页请求,找到返回图文数据的 API 接口;
- 向 API 接口发送 HTTP 请求,获取 JSON 格式的原始数据;
- 解析 JSON 数据,提取其中的图文标题字段;
- 整理并输出 / 保存标题数据。
1.2 环境与依赖安装
本次实战仅需 Python 3.8 + 版本及核心第三方库,具体如下:
| 库名称 | 作用 | 安装命令 |
|---|---|---|
| requests | 发送 HTTP 请求,获取 API 接口的 JSON 数据 | pip install requests |
| json | Python 内置库,解析 JSON 格式数据 | 无需安装,直接导入 |
| time | Python 内置库,设置请求延迟,规避反爬 | 无需安装,直接导入 |
验证安装成功的代码:
import requests
import json
print("环境安装成功!")
输出结果:
环境安装成功!
二、爬取今日头条图文标题核心步骤
2.1 分析目标 API 接口
- 打开实战链接(https://www.toutiao.com/native/category/feed/?cate_code=news_hot),按 F12 打开开发者工具;
- 切换到 'Network' 标签,刷新页面,筛选 'XHR' 类型请求;
- 找到名称包含 'feed' 的请求(请求 URL 通常包含 https://www.toutiao.com/api/pc/feed/);
- 查看该请求的 'Response' 标签,确认返回数据为 JSON 格式,且包含 title 字段(图文标题)。
2.2 构建爬虫代码(含反爬策略)
今日头条对请求频率和请求头有严格校验,核心代码如下:
import requests
import json
import time
import random
def get_toutiao_titles():
# 1. 目标 API 接口(经分析提取的核心接口)
url = "https://www.toutiao.com/api/pc/feed/"
# 2. 请求参数(模拟浏览器请求的核心参数)
params = {
"category": "news_hot",
"utm_source": "toutiao",
"widen": "1",
"max_behot_time": "0",
"max_behot_time_tmp": "0",
"tadrequire": "true",
"as": "A195C8541985A86",
"cp": "C895A9148568E81",
"_signature": "_02B4Z6wo00f0NMHkU1gAAIDDJa5D7f17669661AAAbf79" # 注:signature 会过期,需重新抓包获取
}
# 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": "https://www.toutiao.com/",
"Cookie": "tt_webid=7324567890123456789; ttcid=1234567890abcdef1234567890abcdef123;", # 需替换为自己的 Cookie
"X-Requested-With": "XMLHttpRequest"
}
try:
# 4. 发送 GET 请求,获取 JSON 数据
response = requests.get(
url=url,
params=params,
headers=headers,
timeout=
)
response.raise_for_status()
data = response.json()
title_list = []
data (data[]) > :
item data[]:
item item[] item:
title = item[].strip()
title_list.append(title)
title_list
requests.exceptions.RequestException e:
()
[]
json.JSONDecodeError e:
()
[]
Exception e:
()
[]
__name__ == :
time.sleep(random.uniform(, ))
titles = get_toutiao_titles()
()
titles:
index, title (titles, ):
()
:
()
2.3 代码核心原理拆解
| 代码模块 | 功能原理 | 关键说明 |
|---|---|---|
| 请求参数设置 | 模拟今日头条前端的请求参数,category 指定'热点资讯'分类 | _signature 是动态生成的签名,过期需重新抓包获取 |
| 请求头 Cookie | 今日头条需验证用户 Cookie,无 Cookie 会返回空数据 | Cookie 可从浏览器开发者工具的'Request Headers'中复制 |
| response.json() | 将 API 返回的 JSON 字符串转换为 Python 字典 / 列表 | 比 json.loads(response.text) 更简洁,且自动处理编码 |
| JSON 数据解析 | 遍历 data 数组,提取每个元素的 title 字段 | 过滤广告内容(无 abstract 字段的为广告),保证数据有效性 |
| 随机延迟 | random.uniform(1,2) 生成 1-2 秒随机延迟 | 避免固定延迟被反爬识别 |
2.4 代码运行结果示例
运行上述代码后,控制台输出结果如下(标题随热点实时更新):
=== 今日头条热点图文标题列表 ===
1. 2026 年春运首日火车票开售,这些新变化要注意
2. 央行发布最新货币政策报告,释放三大信号
3. 多地出台新政支持新能源汽车消费,购车补贴最高达 1 万元
4. 专家解读:2026 年楼市调控方向,刚需购房迎利好
5. 国产大飞机 C919 新增多条国际航线,市场布局进一步扩大
6. 冬季养生:这 5 种食物少吃,3 种食物多吃,增强免疫力
7. 2026 年考研初试结束,这些复试注意事项提前了解
8. 多地气温创今冬新低,寒潮预警持续,出行注意保暖
9. 世界杯预选赛:国足客场战平对手,出线形势分析
10. 新版医保目录落地,新增 121 种药品,覆盖这些疾病
三、进阶优化与注意事项
3.1 动态参数处理(解决 signature 过期问题)
_signature 参数会实时过期,新手可通过以下方式临时解决:
- 每次运行前,打开浏览器抓包获取最新的_signature;
进阶方案:使用 execjs 库执行今日头条的 JS 代码生成签名(需具备基础 JS 知识),示例代码片段:
import execjs
# 读取生成 signature 的 JS 文件(需自行抓包提取)
with open("get_signature.js", "r", encoding="utf-8") as f:
js_code = f.read()
ctx = execjs.compile(js_code)
signature = ctx.call("get_signature", params) # 调用 JS 函数生成签名
params["_signature"] = signature
3.2 多页数据爬取
通过修改 max_behot_time 参数实现翻页,示例代码:
def get_multi_page_titles(page_num=3):
all_titles = []
max_behot_time = 0
for page in range(page_num):
params["max_behot_time"] = str(max_behot_time)
params["max_behot_time_tmp"] = str(max_behot_time)
# 重新生成 signature(关键)
titles = get_toutiao_titles()
all_titles.extend(titles)
# 更新 max_behot_time(从返回数据中提取)
response = requests.get(url, params=params, headers=headers)
data = response.json()
if "next" in data and "max_behot_time" in data["next"]:
max_behot_time = data["next"]["max_behot_time"]
time.sleep(random.uniform(2, 3)) # 翻页延迟
return all_titles
3.3 数据保存优化
将标题保存到 TXT 文件(便于查看)和 Excel 文件(便于分析):
# 保存到 TXT 文件
with open("今日头条标题.txt", "w", encoding="utf-8") as f:
for title in titles:
f.write(title + "\n")
# 保存到 Excel 文件(需安装 openpyxl)
# pip install openpyxl
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "热点标题"
ws.append(["序号", "图文标题"])
for index, title in enumerate(titles, 1):
ws.append([index, title])
wb.save("今日头条标题.xlsx")
print("数据已保存到 TXT 和 Excel 文件!")
3.4 合规性与反爬注意事项
- 本次爬取仅用于学习交流,禁止商用或批量爬取;
- 今日头条的 API 接口会频繁更新,代码需根据接口变化及时调整;
- 爬取频率控制在每 3-5 秒 1 次,避免 IP 被封禁;
- 切勿爬取敏感内容,遵守《网络安全法》及今日头条用户协议。
四、常见问题排查
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| 返回数据为空 | 1. Cookie 过期;2. signature 失效;3. IP 被限制 | 1. 更换最新 Cookie;2. 重新抓包获取 signature;3. 切换 IP 或等待 1-2 小时 |
| JSON 解析报错 | 1. 响应不是 JSON 格式;2. 接口返回错误信息 | 1. 打印 response.text 查看实际返回内容;2. 检查请求参数是否正确 |
| 403 Forbidden | 反爬机制触发 | 1. 更换 User-Agent;2. 增加请求延迟;3. 清理浏览器缓存后重新获取 Cookie |
| 标题重复 | 接口返回重复数据 | 在解析时添加去重逻辑:title_list = list(set(title_list)) |
总结
- 爬取今日头条图文标题的核心是找到真实的 API 接口,而非解析前端渲染的 HTML,这是动态网页爬虫的典型特征;
- 请求头(Cookie)和动态参数(signature)是突破今日头条反爬的关键,新手需掌握抓包工具的基本使用;
- 数据解析阶段需过滤广告内容,保证标题的有效性,同时通过随机延迟、翻页控制等方式降低被封风险。
通过本文的实战教程,新手可掌握动态网页爬虫的核心思路,后续可将此方法迁移到抖音、快手等短视频平台的标题 / 评论爬取中,进一步提升爬虫开发能力。

