🕸️ AI 联网搜不动自救手册
给 AI Agent 的使用说明:本 Skill 是纯流程 + 一个零依赖的搜索脚本。核心依赖
curl_cffi(可选,未安装时脚本自动回退到标准库urllib)。把你的"联网搜索"或"网页抓取"能力接到本文的工作流上即可。
什么时候用这个
出现下面任一情况,就按本文的三级绕行走一遍:
- 搜索返回 403 / 429 / 503,或提示"访问过于频繁"
- 弹出滑块验证码 / 人机验证
- 页面正常打开但正文是空的(内容靠 JS 异步渲染)
- 搜索结果和问题完全无关(引擎给的是"被过滤后的安全结果")
- 抓取工具报超时、空页面、需要登录
核心判断:先分清是"你被挡住了"还是"这个站本来就没这内容"。前者要绕行,后者换信源。不要在被挡住的通道上反复重试——同一通道失败 2 次就换。
三级绕行工作流
Layer 0:curl_cffi 模拟浏览器指纹(首选,最省事)
绝大多数中文站点的反爬检测的是 TLS 指纹和 HTTP/2 握手特征,不是你的 UA 字符串。普通 curl / requests 的 TLS 指纹一看就是机器人;curl_cffi 会伪装成真实 Chrome:
pip install curl_cffi
from curl_cffi import requests as creq
r = creq.get("https://目标网址",
impersonate="chrome", # 关键:模拟 Chrome 的 TLS 指纹
headers={"Accept-Language": "zh-CN,zh;q=0.9"},
timeout=20)
print(r.status_code, len(r.text))
要点
impersonate可换chrome/chrome110/safari/edge99等,某个不灵就换另一个- 比启动浏览器快一个数量级,且不需要显示器
- 能不用浏览器就不用——浏览器留给"必须执行 JS"或"需要登录态"的页面
若装不了 curl_cffi,用标准库兜底(成功率低一些,但聊胜于无):
import urllib.request
req = urllib.request.Request(url, headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
})
html = urllib.request.urlopen(req, timeout=20).read().decode("utf-8", "ignore")
Layer 1:多引擎轮换(不同引擎的"脾气"完全不同)
别在一个引擎上耗。同一个关键词,换引擎往往立刻出结果:
| 优先级 | 引擎 | 最擅长的场景 | 注意 |
|:--|:--|:--|:--|
| 🥇 | Bing(cn.bing.com) | 通用话题、英文资料、技术文档 | 敏感/行业类查询会被过滤到只剩几条,此时换搜狗 |
| 🥈 | 搜狗 | 中文行业资讯、公众号文章、公司信息 | 结果是跳转链,需要二次解析真实 URL |
| 🥉 | 360 搜索 | 服务商/企业官网、备案信息 | 广告位多,注意甄别 |
| 4 | 百度 | 中文全能,收录最广 | 反爬最狠:无显示器环境容易撞滑块,别死磕 |
| 5 | DuckDuckGo / Yahoo | 海外信息、需要中立视角时 | 中文覆盖弱,且部分地区不可达 |
决策口诀:通用话题走 Bing → 被过滤或要中文行业信息走搜狗 → 找具体公司/服务商走 360 → 前三都空才试百度。
多引擎并行(一次问 2-3 个引擎,交叉验证更可靠):
python scripts/multi_search.py "你的关键词" --engines bing,sogou,360
Layer 2:直连已知站点(搜索全挂时的保命招)
搜索通道全被挡时,别再搜了——直接去。中文内容的高价值信源高度集中在少数站点:
| 类型 | 站点 | 备注 | |:--|:--|:--| | 科技/创投 | 36氪、钛媒体、虎嗅 | 无 CAPTCHA,正文质量高 | | 行业研究 | 前瞻产业研究院、艾瑞、易观 | 报告摘要免费,全文多要付费 | | 工商/融资 | 企查查、天眼查、IT桔子 | 部分字段需登录 | | 专利 | Google Patents、智慧芽 | Google Patents 可用 |
直连也是抓正文,不是"让搜索帮你打开"——用 Layer 0 的方式请求目标 URL,再走下面的正文提取。
正文提取(拿到 HTML 之后)
标准管道:HTML → 去 script/style → 去标签 → 实体反转义 → 压缩空白
import re, html
def html_to_text(raw: str) -> str:
t = re.sub(r"<script.*?</script>", " ", raw, flags=re.S | re.I)
t = re.sub(r"<style.*?</style>", " ", t, flags=re.S | re.I)
t = re.sub(r"<(br|/p|/div|/h[1-6])[^>]*>", "\n", t, flags=re.I)
t = re.sub(r"<[^>]+>", " ", t)
t = html.unescape(t)
t = re.sub(r"[ \t\u3000]+", " ", t)
return re.sub(r"\n{3,}", "\n\n", t).strip()
几个实战坑
- JS 渲染的站(36氪、微博、多数 SPA):
urllib拿到的是空壳 → 必须换浏览器渲染(无头浏览器/Playwright/你环境自带的浏览器工具) - 数据其实藏在页面变量里:不少站点把首屏数据塞在
window.__INITIAL_STATE__/__NUXT__/<script type="application/json">里。先 grep 这些变量名再决定要不要上浏览器,常能省掉 90% 的功夫 - URL 里有关键参数:
?id=、/p/12345这类文章 ID 往往能从搜索结果或列表页拿到,拿到就能直连,不必过搜索 - 压缩空白别过度:中文正文的段落靠
\n分隔,把\n也压掉会让内容变成一坨
失败降级链(照着走,别乱试)
curl_cffi直取 → 失败 ↓- 换
impersonate目标(chrome → chrome110 → edge99)→ 失败 ↓ - 换搜索引擎(Bing → 搜狗 → 360)→ 失败 ↓
- 直连目标站点(跳过搜索)→ 失败 ↓
- 换信源:找转载/快照/同类站点(很多中文内容会被多处转载)→ 失败 ↓
- 如实告知用户"当前通道被限制,拿不到 X",并说明已试过哪些路径
⚠️ 最后一条是纪律,不是备选项:宁可如实说"拿不到",也不要编造数据或拿几年前的旧数据充数。调研类任务里,一个假数据比没有数据危险得多。
质量检查清单(交付前过一遍)
- [ ] 每条信息标了来源站点 + 时间(没时间的按不可信处理)
- [ ] 关键结论有第二个来源交叉验证(单一来源必须显式标注"未交叉验证")
- [ ] 数据的时效性说明了("2024 年的数据"和"今年的数据"结论可能相反)
- [ ] 区分了事实 / 推断 / 猜测三种成色
- [ ] 明确写出没查到什么(缺失信息比错误信息更该说清)
关于作者
九品锦锂e · 把团队一线实战沉淀成能直接装的 AI Skill。
- 微信:
ly5419495(AI 落地 / 自动化定制,备注「Skill」) - 公众号:初五Agent(搜一搜,更新 AI 实操方法与 Skill 拆解)
- 更多 Skill:https://skillpay.alipay.com/public/jiupinjinlie
本 Skill 为完整版本,无功能删减。可自由用于个人与商业场景。
进阶材料(references/)
| 文件 | 内容 |
|:--|:--|
| html-to-text-pipeline.md | HTML → 正文的标准提取管道与选择器写法 |
| search-engine-url-patterns.md | 中文搜索引擎结果链接的混淆规律与解析要点 |
| case-36kr-article-extraction.md | 实战案例:JS 渲染站点(36氪)正文批量提取 |
| case-chinese-fund-search.md | 实战案例:搜不到时的引擎轮换记录与结论 |
这些是踩坑后的实测记录,遇到硬骨头时翻一眼能省不少时间。
Scan to join WeChat group