Python中关于头条_signature参数的问题如何解决?

我自己生成的_signature 很快失效,但是我在 控制台输出的 var signature=TAC.sign("6347006294" + "0") signature "Gd-RphAWRZtUi2lUOcc8FBnfkL"

然后放到网站 很久都可以返回数据,我通过复制 js 代码生成的_signature 只用一次就不能用了,但是控制台这个_signature 能用很久,求指教,这是为啥?

抓取的网站 https://www.toutiao.com/c/user/6347006294/#mid=6350075797


Python中关于头条_signature参数的问题如何解决?

1 回复

这个问题我遇到过。头条的_signature参数主要是用来反爬的,核心是前端生成一个加密字符串,我们得在Python里模拟这个计算过程。

通常,这个签名是由页面的一些固定参数(比如ascpmas)加上当前时间戳,经过一个特定的JavaScript函数(可能是MD5、SHA或者自定义算法)计算出来的。你不能直接硬编码,因为算法可能会变。

解决思路和步骤:

  1. 抓包定位:用浏览器开发者工具(F12 -> Network),找到一个包含_signature参数的请求(比如列表页请求)。重点看它的Query String ParametersPayload
  2. 搜索关键代码:在Sources里全局搜索_signaturesignsignature或者byted.acrawler这些关键词。头条常用一个叫acrawler.js的库。
  3. 分析JS函数:找到生成签名的函数。它通常会接收一个URL或参数字符串作为输入。你需要理清它的逻辑。
  4. Python模拟
    • 简单情况:如果算法是标准的(如MD5),直接用Python的hashlib库实现。
    • 复杂情况:如果算法混淆严重,有两种主流方法:
      • 方法A:PyExecJS。用这个库在Python环境中直接执行你找到的那段关键JS代码。优点是快,但环境依赖可能麻烦。
      • 方法B:Selenium/Playwright。直接用无头浏览器加载页面,让浏览器执行JS生成签名,然后你再提取。这种方法最省事,能应对算法更新,但速度慢、资源占用高。

这里给你一个使用PyExecJS的通用代码框架:

import execjs
import time
import requests

# 1. 读取你从网页上抠下来的、包含签名函数的JS文件
with open('signature.js', 'r', encoding='utf-8') as f:
    js_code = f.read()

# 2. 编译JS代码
ctx = execjs.compile(js_code)

# 3. 准备参数(这些参数需要你根据实际抓包分析得到)
# 例如,可能需要完整的URL,或者参数字符串
params = {
    'user_id': '123456',
    'max_behot_time': int(time.time()),
    'category': '__all__',
    # ... 其他必要参数
}
# 假设你的JS函数名叫`get_signature`,它接受参数字符串
param_str = '&'.join([f'{k}={v}' for k, v in params.items()])
signature = ctx.call('get_signature', param_str) # 调用JS函数

# 4. 将计算得到的_signature加入请求参数
params['_signature'] = signature

# 5. 发送请求
url = 'https://www.toutiao.com/api/pc/list/feed'
headers = {
    'User-Agent': '你的浏览器User-Agent'
}
resp = requests.get(url, params=params, headers=headers)
print(resp.json())

关键点:你需要把找到的JS签名函数(以及它可能依赖的其他函数/变量)完整地保存到本地的signature.js文件中。有时候需要补上一些浏览器环境下的全局对象(比如windowdocument)的简单模拟。

如果JS混淆得太厉害,搞不定,那就直接用Selenium吧,虽然慢点,但能确保拿到可用的签名。

总结:核心是逆向JS算法并用Python执行。

回到顶部