做爬虫踩过的坑,记一下

2026-06-12 19:07

做爬虫踩过的坑,记一下



前阵子接了个电商价格监控的活,需求不复杂:定时抓某平台商品价格和库存。但这家的反爬有点东西,踩了几个坑,记下来免得忘。



============================================================

一、别省请求头

============================================================



很多人觉得加个 UA 就完事了。这家会静默检查请求头完整性。



Resync 在《Bot Detection 101》里提过:现代反爬不只是看 UA,而是看整个 TLS 指纹和 HTTP 头的组合偏差。浏览器发出来的头是什么样,你就得是什么样。少一个 Sec-Ch-Ua,返回的就是空白页——不报错,不弹验证码,就是空。这种"什么都不说"的反爬反而最难定位。



session = requests.Session()

session.headers.update({

"User-Agent": "...",

"Accept": "text/html,application/xhtml+xml,"

"application/xml;q=0.9,*/*;q=0.8",

"Accept-Language": "zh-CN,zh;q=0.9",

"Accept-Encoding": "gzip, deflate, br",

"Sec-Ch-Ua": "\"Chromium\";v=\"124\"",

"Sec-Ch-Ua-Platform": "\"Windows\"",

})



============================================================

二、JS 生成的 Cookie

============================================================



首次访问页面会用 JS 在本地跑一段指纹逻辑,生成一个 cookie。不带这个 cookie 的话,后面所有请求都给你甩验证码。



思路:Playwright 开个 headless 浏览器,等 JS 跑完,把 cookie 倒出来给 requests 用。有效期两三个小时,定时刷新就行。



from playwright.sync_api import sync_playwright



with sync_playwright() as p:

browser = p.chromium.launch(headless=True)

page = browser.new_page()

page.goto("https://目标站.com",

wait_until="networkidle")

cookies = page.context.cookies()

browser.close()



============================================================

三、参数签名——卡最久的地方

============================================================



搜索接口有个 sign 参数,32 位小写 hex,一看就是 MD5。但原文是什么?



翻压缩 JS 找到加密那段:



var sign = md5(JSON.stringify(params)

+ "&key=" + _0x3f2a)



_0x3f2a 往回追,发现是从一个配置接口返回的。所以流程是:先调配置接口拿 key → 组装参数 → md5 → 带 sign 发请求。



Python 复现的时候有个细节卡了很久:



import hashlib

import json



def build_sign(params: dict, secret_key: str) -> str:

raw = (json.dumps(params, separators=(",", ":"))

+ "&key=" + secret_key)

return hashlib.md5(raw.encode()).hexdigest()



注意 separators=(",", ":")。JS 的 JSON.stringify 默认不带空格,Python 的 json.dumps 默认带。两边算出来的 sign 不一样,排查了好久。



Intoli 的《The State of Web Scraping》总结过:爬虫工程大部分时间花在逆向和对抗上,真正写采集逻辑的代码反而是少数。确实是这样。



============================================================

四、频率和假数据

============================================================



这家单 IP 每分钟大概 30 次请求到顶。超了不封你,给你假数据——价格全显示 0,库存全显示有货。比直接封更恶心,因为你不会立刻发现。



import time

import random



def safe_request(url, params):

time.sleep(2 + random.uniform(0, 1.5))

resp = session.get(url, params=params)

if all(item["price"] == 0

for item in resp.json()["items"]):

raise ValueError("疑似被风控,数据异常")

return resp.json()



Cloudflare 2024 年的 bot management 报告提到:越来越多的站点从"硬阻断"转向"软对抗"——给你假数据或者降级数据,而不是直接弹验证码。所以爬虫必须自己做数据校验。



============================================================

五、总结

============================================================



请求头校验 → 浏览器发什么你发什么

JS生成Cookie → Playwright 预热后导出

参数签名 → 逆向 JS 再用 Python 复现

频率限制 → 随机延时加代理池

假数据 → 自己加数据校验



写爬虫最大的感受:代码本身不难,难的是搞清楚对方到底用了什么手段。很多坑不在技术上,在你能不能对着 Network 面板,一笔一笔把完整请求链路还原出来。



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



目前接一些爬虫、数据采集的私活,有电商数据、价格监控、批量采集需求的可以聊聊。



引用:

Resync —— Bot Detection 101

Intoli —— The State of Web Scraping

Cloudflare —— 2024 Bot Management Report

浏览 10
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报