在数据采集领域,**签名算法(sign)与时间戳校验(timestamp)**是最常见的反爬门槛。 本文以闲鱼(Goofish)为例,完整讲解一个真实可用的 签名级别爬虫实现,从参数逆向到稳定运行,并逐步升级为可扩展的工程化架构。
一、前言:从“抓不到数据”开始
最初,我的目标很简单:
想抓取闲鱼搜索结果,批量获取 “Python 爬虫” 相关的商品标题、价格与卖家信息。
我照着视频教程写了个爬虫,但结果一行数据都没有。 浏览器能搜到数据,代码却返回空。
排查后发现问题出在时间戳验证。闲鱼的搜索接口使用签名机制,每次请求必须带上:
-
token:来源于浏览器 Cookie 中的
_m_h5_tk - t:时间戳
- sign:由 token、时间戳、appKey、请求参数计算出的 MD5 值
签名算法看似简单,但其中的 时间戳偏差问题 是关键。
二、时间戳反推:16 小时的谜团
抓包时我发现,浏览器发出的请求中:
t = 1759801941772
对应的实际时间是 2025-10-06 17:52:21, 而我运行代码时系统时间是 2025-10-07 09:53。
时间差整整 16 小时。
当我强行把 time.time() 生成的时间戳往前拨 16 小时后,数据立即返回。 这说明签名算法与真实系统时区不同,闲鱼接口使用的时间戳不是本地时间,而更接近 UTC 时区。
于是我将时间戳修正:
current_timestamp = int(time.time() * 1000) sixteen_hours_ago = current_timestamp - (16 * 60 * 60 * 1000) j = str(sixteen_hours_ago)
成功拿到数据。
三、签名算法复现
浏览器请求中的签名计算方式如下:
sign = MD5(token + "&" + timestamp + "&" + appKey + "&" + data)
其中:
-
token:Cookie 中_m_h5_tk的前半段 -
timestamp:时间戳(毫秒) -
appKey:固定为34839810 -
data:请求体 JSON 字符串
Python 实现非常直接:
string = token + "&" + j + "&" + h + "&" + c_