很多人在让大模型帮忙写爬虫时会发现一个尴尬现象:生成的代码看起来逻辑完整,运行起来却处处报错。要么是选择器匹配不到任何元素,要么被服务器识别为机器人直接拒绝,要么是编码问题导致中文乱码。这些问题并不是大模型不会写代码,而是你的提示词没有把爬虫运行环境的关键信息传递清楚。换句话说,写出一个高质量爬虫Prompt,比让模型"多想想"更重要。

一、为什么大模型生成的爬虫代码经常"看着对,跑不通"
大模型生成代码的能力源自海量训练数据,但训练数据中的爬虫示例大多来自教程和博客,这些示例通常以静态HTML页面为假设前提。真实网站往往包含JavaScript动态渲染、异步接口、登录校验、频率限制等机制,直接套用训练数据中的通用写法自然容易失败。另一个典型问题是选择器太脆弱,模型生成的XPath或CSS选择器通常针对页面初次加载时的结构,一旦页面元素顺序变化或属性更新,对应的解析逻辑就会失效。
此外,大模型默认生成的爬虫代码缺少工程化思维。它可能不会主动设置User-Agent模拟浏览器,不会处理请求超时,也不会设计重试机制。当目标网站返回301跳转、触发验证码或返回JSON错误信息时,代码无法识别这些异常,只会继续往下执行,最终抛出一个难以理解的异常堆栈。这给人一种"模型不会写爬虫"的错觉,其实只是提示词中缺少了对异常场景的约束。
最后,很多提示词把目标描述得太模糊。直接说"帮我爬取这个网站的数据",模型不知道你要哪些字段,不知道是爬取列表页还是详情页,更不知道输出格式应该是JSON还是CSV。模型只能用自己理解的"常见需求"去猜,猜不对自然跑不通。
二、写爬虫提示词的核心原则:把上下文交代清楚
要让大模型生成可执行的爬虫代码,提示词必须像一份技术需求文档一样清晰。第一步是说明目标页面的URL和需要提取的字段列表,字段名最好直接对应数据含义,比如标题、发布时间、价格、作者等。如果字段有嵌套关系,也要在提示词中说明清楚,模型在写解析代码时才能设计出合理的数据结构。
第二步是指定解析方式。建议在提示词中明确告知页面是纯静态HTML还是由JavaScript动态渲染。如果是静态页面,模型可以直接使用requests加BeautifulSoup或lxml配合XPath解析。如果是动态页面,模型就需要改用selenium、playwright或直接去分析后端接口。这一步非常关键,大多数生成结果跑不通,都是因为页面渲染方式与所选技术栈不匹配。
第三步是要求工程化处理。你可以在提示词中明确写出"请设置User-Agent和常见的请求头""请加入超时和重试机制""请对返回内容做编码识别"。这些看起来像"废话"的要求,实际上能极大提高代码在真实网络环境中的存活率。还有一个容易忽略的点,就是要约定输出的数据格式,比如统一的JSON结构,方便后续做数据清洗和入库。
# 一个对比示例:模糊提示词 vs 结构化提示词 # 模糊写法 # 帮我爬取这个网站的商品信息,最好用Python # 结构化写法 # 目标URL:https://ippipp.com/items # 页面类型:静态HTML # 需要字段:商品名称、价格、评价数、上架时间 # 解析要求:使用requests和BeautifulSoup,CSS选择器 # 输出格式:JSON数组,字段名为name, price, comments, publish_time # 安全要求:设置User-Agent为Chrome浏览器,超时10秒,失败重试3次
这一段示例虽然只是注释,但它说明了一个核心道理:你把约束条件写得越具体,大模型的搜索空间就越小,产出的代码就越贴近目标网站。很多开发者的真实需求往往只是"快速验证一下能不能爬到数据",此时一个结构化的Prompt反而比反复调试模型输出的零散代码更高效。
三、一个可复用的中文爬虫Prompt模板
下面给出的模板已经在多个实际项目中验证过,能够适配大多数静态页面的爬虫代码生成场景。你可以直接把尖括号内的内容替换成自己的目标信息,然后再交给大模型。模板中每个段落都有明确作用,不要为了省事而删除其中的安全要求部分。
请帮我编写一个Python爬虫代码,要求如下: 1. 目标URL:https://ippipp.com/news 2. 页面类型:静态HTML,数据直接包含在HTML源码中 3. 需要提取的字段: - 新闻标题 - 发布日期 - 新闻正文第一段 4. 技术栈:使用requests和BeautifulSoup 5. 解析方式:使用CSS选择器,请根据目标HTML结构给出具体选择器 6. 请求头:必须设置User-Agent为Mozilla/5.0,并携带Accept-Language: zh-CN 7. 异常处理:请求失败时打印错误并重试3次,每次间隔2秒 8. 输出格式:将结果保存为JSON文件,字段名为title, publish_date, content 请注意:页面中的正文在div.article-body内,标题位于h1.article-title中。
这个模板覆盖了目标定位、字段设计、技术选型、请求伪装、异常容错和结果持久化六个维度。当你把这样一个Prompt交给大模型时,它的输出会明显比一句"帮我爬新闻"要靠谱得多,因为每个模块都有明确的约束。实际使用时,你还可以根据目标网站增加Cookie、Referer等请求头信息,或者指定使用Session对象保持会话。
有一点需要特别提醒:模板中的CSS选择器部分需要你预先查看目标网页的HTML结构。很多开发者会跳过这一步,希望模型自己分析网页,但大模型并没有实时访问网页的能力,它只能根据你的描述来推测结构。如果你连"正文在div.article-body中"这种信息都不给,模型就只能写一个通用的解析逻辑,遇到结构复杂的页面就会失败。因此,花一分钟用浏览器开发者工具查看目标元素的选择器,能极大提高生成代码的可用性。
四、处理动态页面和反爬机制的提示词进阶
当目标网站使用Vue或React等前端框架渲染内容时,页面HTML中可能只有一堆JavaScript脚本,直接解析拿不到任何数据。此时提示词中要明确要求模型改用动态渲染方案,比如playwright或selenium,或者引导模型去分析接口。你可以在提示词里加上一句"页面内容由JavaScript动态加载,请先分析网络请求,找出返回数据的接口,再直接请求接口获得JSON数据"。这种方式比直接使用浏览器自动化更加高效,因为接口通常返回结构化数据,省去了解析HTML的麻烦。
对于带有反爬机制的目标站点,比如需要登录、有滑块验证码或存在IP频率限制,你要在提示词中明确说明这些限制。模型可以为你生成携带Cookie的请求代码,也可以帮你设计一个带随机延时和代理池的抓取框架。不过需要提醒的是,绕过登录和验证码的行为可能违反网站服务条款,本文仅仅讨论技术可行性,在实际项目中请务必遵守目标网站的robots协议和法律法规。
# 使用playwright处理动态渲染页面的代码框架
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://ippipp.com/products")
# 等待列表容器渲染完成
page.wait_for_selector("div.product-list", timeout=30000)
items = page.query_selector_all("div.product-item")
data = []
for item in items:
title = item.query_selector("h2.product-title").inner_text()
price = item.query_selector("span.price").inner_text()
data.append({"title": title, "price": price})
print(data)
browser.close()
写到这一步,你的提示词其实已经不是一个简单的"请求"了,而是一份微型技术方案。大模型在这类结构化提示词的引导下,能够生成更全面的代码,包括页面等待、反检测参数设置以及防重复爬取等细节。你还可以要求模型为代码添加注释,方便你后续接手维护。
五、总结:好的爬虫Prompt是调试出来的
大模型生成爬虫代码的本质,是把你描述的需求映射到训练数据中的代码模式。提示词给出的约束越充分,映射偏差就越小。与其抱怨模型生成的代码跑不通,不如花时间打磨自己的提示词,把目标URL、页面渲染方式、字段结构、解析策略、异常处理这些信息逐一交代清楚。这样一次生成出来的代码,可能只需要微小调整就能在真实环境中正常运行。
最后想说的是,不要试图让大模型替你"观察"网页。它无法亲自打开浏览器查看元素位置,也不会主动发现页面的反爬策略。你需要作为中间的观察者,把网页的关键结构塞进提示词里。掌握这个思路之后,你会发现自己写爬虫的效率会出现质的提升,大模型从"玩具"变成了真正可靠的编码助手。