用LLM自动化生成解析器:从Prompt到Parser的工程化落地

爬虫代理

一、那些年,我们手写过的XPath

如果你做过网页爬虫,大概率都经历过这种心态崩溃的时刻:“昨天还能跑的代码,今天又解析不出来了。”

HTML结构像变魔术一样,每次网站改版都要从头开始。有时候只是一个多余的<div>,就能让你调一下午的XPath。

写解析器这件事,说白了就是在和混乱的DOM树搏斗。而且越是大站点,越喜欢在标签里加花样。每个开发者都想要一个“能自己看懂网页结构、自动提取内容”的工具。

直到大语言模型(LLM)出现,这个念头才突然有了点现实的味道。毕竟,这玩意能写代码、能理解上下文,那为什么不能让它写出“能解析网页的代码”呢?

二、灵感的萌芽:让模型“读网页”

传统解析器靠人写规则。而LLM给了我们一个全新的视角:

不如让机器自己理解网页结构,然后自动产出解析逻辑。

换句话说,我们不再告诉程序“从第几个div开始找标题”,而是告诉模型:“帮我提取新闻标题、作者、时间和正文。”

Prompt 就是指令,Parser 就是结果。这就像训练一个“结构化翻译机”——你说自然语言,它翻译成能运行的代码。

从这一刻开始,解析不再是规则问题,而是理解问题。LLM让我们第一次有机会,把“解析网页”变成一件语言层面的事。

三、从想法到落地:Prompt → Parser → Result

要让这件事真的跑起来,大致需要三层逻辑:

* Prompt层:你告诉模型要干什么,比如“提取新闻标题和正文”。

* LLM层:模型根据指令生成解析逻辑,比如XPath、CSS选择器或者BeautifulSoup代码。

* 执行层:把生成的代码跑一遍,输出结果。

听上去很抽象,但其实实现起来并不复杂。我们用Python写一个小实验:抓取新浪新闻首页,让模型帮我们生成解析代码。中间顺带加上代理IP,用爬虫代理解决封锁和频率问题。

四、实战:让模型自动写解析代码

下面是一个小实验,从Prompt到结果,全流程跑通。我在代码里加了中文注释,方便大家看懂思路。

import requests

from bs4 import BeautifulSoup

import openai  # 假设用OpenAI API调用LLM

import json

# ========== 代理IP配置 ==========

# 使用亿牛云爬虫代理,保证请求稳定和匿名 www.16yun.cn

proxy_host = "proxy.16yun.cn"

proxy_port = "31000"

proxy_user = "16YUN"

proxy_pass = "16IP"

proxies = {

    "http": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}",

    "https": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"

}

# ========== Step 1: 抓取目标网页 ==========

target_url = "https://news.sina.com.cn/china/"

response = requests.get(target_url, proxies=proxies, timeout=10)

html_content = response.text

# ========== Step 2: 构造Prompt ==========

prompt = f"""

你是一个网页解析专家,请为以下HTML生成Python解析代码,

目标是提取新闻标题、发布时间、作者和正文。

HTML内容如下:

{html_content[:3000]}  # 截取一部分防止太长

"""

# ========== Step 3: 调用LLM生成解析器 ==========

openai.api_key = "your_api_key"

resp = openai.ChatCompletion.create(

    model="gpt-4",

    messages=[

        {"role": "system", "content": "你是一个网页结构分析与解析代码生成专家"},

        {"role": "user", "content": prompt}

    ]

)

generated_code = resp["choices"][0]["message"]["content"]

print("=== LLM生成的解析器代码 ===")

print(generated_code)

# ========== Step 4: 执行解析代码(仅演示) ==========

# 实际项目中请用沙箱执行,避免安全风险

try:

    exec_locals = {}

    exec(generated_code, globals(), exec_locals)

    result = exec_locals.get("parsed_data", {})

    print("=== 解析结果 ===")

    print(json.dumps(result, ensure_ascii=False, indent=2))

except Exception as e:

    print("执行解析代码时出错:", e)

运行这段代码后,模型通常会生成一段类似:

soup = BeautifulSoup(html, "html.parser")

title = soup.find("h1").text

...

parsed_data = {...}

的内容,然后自动帮你提取出结构化数据。从Prompt到结果,全程几乎没手动写任何XPath。

五、背后的价值:让解析不再“手工化”

这种方式有几个很实用的价值点:

1. 开发速度暴涨:再也不用一个字段一个字段去试。

2. 解析逻辑可解释:LLM生成的代码往往带注释,你能看懂模型的思路。

3. 可自学习:解析错了?换个Prompt就能修正,甚至能让模型自己总结失败原因。

更有意思的是,如果你长期积累Prompt和解析结果,就能做一个“小型训练库”——下次遇到类似结构的网页,模型几乎能秒写解析器。

六、再往前一步:让系统会“自我进化”

想象未来的采集系统是这样的:

* 爬虫模块抓HTML;

* LLM模块理解页面结构;

* Prompt模板根据任务自动调整;

* 解析器生成后在沙箱里执行;

* 错误样本被自动收集,用来微调Prompt策略。

这样,一个“能自我成长的网页理解系统”就诞生了。它不是死板的规则机器,而是一个懂语义、能学习的结构化引擎。

七、写在最后

这几年我们见证了数据采集从“写死规则”到“模型辅助”的转变。也许未来,工程师的角色会变成“Prompt设计师”——我们不再写解析器,而是写指令,教机器去写解析器。

这不仅是效率提升,更是一种思维转变。我们终于能让“网页解析”这件原本枯燥的事,变得像训练一个聪明的小助手一样有趣。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容