news 2026/5/2 17:10:26

基于ChatGPT的智能数据提取:从非结构化文本到结构化数据的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于ChatGPT的智能数据提取:从非结构化文本到结构化数据的实战指南

1. 项目概述:当ChatGPT遇上法国“闲鱼”

如果你在法国生活过,或者对欧洲的二手市场有所了解,那你一定听说过Leboncoin。它就像是法国的“闲鱼”或“Craigslist”,是当地人买卖二手物品、租房、找工作甚至交友的国民级平台。每天,上面都有海量的信息在流动,从一辆老旧的自行车到一套巴黎市中心的公寓,信息庞杂且非结构化。

作为一名数据爱好者或市场分析师,你可能会想:如果能把这些零散的、文本描述为主的商品信息,自动提取成结构化的数据(比如价格、地点、品牌、型号、关键特征),那该多好?有了这些数据,你可以分析某个品类的价格趋势、监控竞争对手的定价、甚至训练一个自动估价模型。

这就是anisayari/leboncoin-chatgpt-data-extract这个项目要解决的核心问题。它不是一个简单的爬虫,而是一个智能数据提取管道。其核心思路是:先用传统方法(如requestsBeautifulSoup)从 Leboncoin 网页上抓取原始的 HTML 内容,然后利用OpenAI 的 ChatGPT API(特别是 GPT-3.5-turbo 或 GPT-4)强大的自然语言理解能力,从这些非结构化的文本描述中,精准地“读懂”并抽取出我们关心的结构化字段。

简单来说,它把枯燥、易错、规则复杂的手写解析逻辑,交给了更擅长理解人类语言的 AI。你只需要告诉 AI 你想提取什么(比如“提取汽车的品牌、型号、年份、里程数和价格”),它就能从千变万化的商品描述中,帮你把数据整理得明明白白。这个项目为我们打开了一扇门:在面对大量非标准化文本数据时,如何将大语言模型(LLM)的能力与传统的自动化流程相结合,高效地完成信息提取任务。

2. 核心思路与技术选型解析

为什么选择“传统爬虫 + ChatGPT API”这条技术路线?这背后是对问题本质和现有技术方案的权衡。

2.1 传统方案的瓶颈:规则之困

在 ChatGPT 这类大语言模型普及之前,要从 Leboncoin 这样的网站提取结构化数据,主流方案无外乎以下几种:

  1. 正则表达式(Regex):针对固定模式的文本(如“Prix: 500€”)非常有效。但 Leboncoin 上的描述是用户自由填写的,表达方式千奇百怪。“500欧”、“五百欧元”、“cinq cents euros”都可能表示价格。编写一个覆盖所有情况的正则表达式几乎是不可能的,维护成本极高。
  2. 基于 XPath/CSS Selector 的解析器:这需要依赖网页有稳定、清晰的 HTML 结构。然而,Leboncoin 的页面结构可能会随前端改版而变化,且商品的关键信息(如描述文本)往往嵌套在复杂的divspan标签中,没有稳定的classid可供定位。一个微小的前端改动就可能导致整个解析器失效。
  3. 专业的网页抓取框架(如 Scrapy):虽然功能强大,能处理复杂的抓取逻辑(登录、分页、反爬),但在信息提取(Information Extraction)这个核心环节,它依然依赖于上述两种方法,同样无法解决文本语义理解的根本难题。

这些方法的共性问题在于,它们都是基于规则的。而人类语言是充满歧义、省略和变化的。当规则遇到变化,代码就会崩溃。

2.2 ChatGPT 带来的范式转变:理解而非解析

OpenAI 的 ChatGPT API(特别是gpt-3.5-turbogpt-4)本质上提供了一个强大的“文本理解即服务”。你给它一段文本和一个指令(Prompt),它就能基于对语言的整体理解来完成任务。

对于 Leboncoin 数据提取,这意味着:

  • 无需预定义规则:你不需要告诉程序“价格可能以‘€’或‘euros’结尾”。你只需要说:“从以下文本中提取价格。”
  • 强大的泛化能力:无论用户写成“Vends iPhone 13 pro max 256Go bon état”(卖iPhone 13 Pro Max 256GB,成色好),还是“iPhone 13 Pro Max, capacité 256, état impeccable”,ChatGPT 都能理解这是在描述一个手机的型号、容量和状态。
  • 处理复杂语境:例如,描述中可能说“价格可议(prix à débattre)”或“交换优先(échange possible)”。传统方法很难处理这些没有明确数字的价格信息,而 ChatGPT 可以将其识别为一种特殊的价格状态。

因此,技术选型就变得清晰了:

  • 前端抓取:使用轻量级的requests库获取网页 HTML,配合BeautifulSoup进行初步的清理和关键文本块的提取(比如定位到商品描述所在的div)。这一步相对稳定,因为只要网页大体结构不变,我们总能找到描述文本所在的大致区域。
  • 核心提取引擎:将提取出的纯文本描述,连同精心设计的指令(Prompt),发送给 ChatGPT API。由 AI 来承担最复杂的语义理解和字段抽取工作。
  • 数据后处理:将 ChatGPT 返回的(通常是 JSON 格式)结构化数据,进行清洗、验证并保存到数据库或文件中(如 CSV、JSONL)。

这个架构的巧妙之处在于责任分离:爬虫只做它擅长的(获取原始数据),AI 只做它擅长的(理解自然语言),两者通过一个清晰的接口(Prompt)协作。当网站前端样式变化时,我们可能只需要调整爬虫的解析规则;而面对无穷无尽的文本描述变化时,我们则依靠 ChatGPT 的泛化能力来应对,极大地提升了系统的鲁棒性和开发效率。

3. 项目实战:从零搭建你的智能提取器

理解了为什么这么做,接下来我们看看具体怎么做。我会以一个提取二手自行车信息的场景为例,带你走通全流程。

3.1 环境准备与依赖安装

首先,你需要一个 Python 环境(建议 3.8 以上)。项目核心依赖并不多:

pip install requests beautifulsoup4 openai python-dotenv pandas
  • requests&beautifulsoup4:网页抓取和解析黄金搭档。
  • openai:OpenAI 官方 Python SDK,用于调用 ChatGPT API。
  • python-dotenv:管理敏感信息(如 API Key)的最佳实践,避免将密钥硬编码在代码中。
  • pandas:可选,用于将提取的数据方便地保存为 CSV 或进行进一步分析。

接下来是关键的API 密钥。你需要访问 OpenAI 平台 (platform.openai.com) 注册账号并创建 API Key。记住,这个 Key 是私密的,且按使用量计费。

在项目根目录创建一个名为.env的文件,内容如下:

OPENAI_API_KEY=你的_OpenAI_API_Key_在这里

然后在你的 Python 脚本中,通过dotenv加载它:

import os from dotenv import load_dotenv import openai load_dotenv() # 从 .env 文件加载环境变量 openai.api_key = os.getenv("OPENAI_API_KEY")

注意:请务必将.env文件添加到.gitignore中,切勿提交到公开的代码仓库,否则你的 API Key 可能会被他人盗用,导致财产损失。

3.2 网页抓取:获取原始描述文本

我们以一辆二手公路自行车的页面为例。假设我们已经找到了一个商品页面的 URL。

import requests from bs4 import BeautifulSoup import json def fetch_page(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } try: response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 检查请求是否成功 return response.text except requests.RequestException as e: print(f"抓取页面失败: {e}") return None def extract_description(html): soup = BeautifulSoup(html, 'html.parser') # 这里需要你手动分析 Leboncoin 页面的结构 # 使用浏览器的开发者工具(F12)查看商品描述所在的HTML元素 # 例如,描述可能在某个 <div class="description"> 或 <p> 标签里 # 这是一个示例,实际选择器需要你自行确定 description_div = soup.find('div', {'data-qa-id': 'adview_description_container'}) if description_div: # 获取纯文本,并清理多余的空格和换行 raw_text = description_div.get_text(separator=' ', strip=True) return raw_text else: print("未找到描述内容。") # 可以尝试其他选择器或备用方案 return None # 示例URL (请替换为真实URL) url = "https://www.leboncoin.fr/velos/1234567890.htm" html_content = fetch_page(url) if html_content: product_description = extract_description(html_content) print("提取到的描述文本:") print(product_description[:500]) # 打印前500字符预览

实操心得

  • User-Agent:设置一个常见的浏览器 User-Agent 可以降低被网站简单屏蔽的风险。
  • 选择器分析:这是抓取中最耗时但也最关键的一步。Leboncoin 的页面结构可能经常微调。使用soup.find()配合classid>def build_extraction_prompt(description_text, fields_to_extract): """ 构建用于信息提取的Prompt。 :param description_text: 商品描述文本 :param fields_to_extract: 一个字典,定义要提取的字段及其说明 :return: 发送给ChatGPT的消息列表 """ # 定义我们要提取的字段。这是一个示例,针对自行车。 # 字段说明要清晰、无歧义,并给出示例。 fields_definition = "" for field, instruction in fields_to_extract.items(): fields_definition += f"- {field}: {instruction}\n" system_message = f"""你是一个专业的数据提取助手。你的任务是从用户提供的商品描述文本中,精确提取出指定的结构化信息。 请严格根据以下字段定义进行提取: {fields_definition} 提取规则: 1. 只提取描述文本中明确提及的信息。如果文本中没有提到某个字段,则该字段值为 null。 2. 价格请统一提取为数字(浮点数),货币单位假设为欧元。如果写的是“ gratuit ”(免费),则价格为 0.0。如果写的是“ prix à débattre ”(价格可议),则值为 “negotiable”。 3. 地点请提取为字符串。如果描述中提到了“ région Parisienne ”(巴黎大区),可以提取为 “Paris”。 4. 品牌、型号等文本字段,请保持原样提取。 5. 年份、里程等数字字段,请提取为整数。 6. 最终输出必须是一个纯JSON对象,不要有任何额外的解释、Markdown格式或JSON代码块标记。键名必须与上述字段定义完全一致。 """ user_message = f"请从以下商品描述中提取信息:\n\n{description_text}" messages = [ {"role": "system", "content": system_message}, {"role": "user", "content": user_message} ] return messages # 定义要提取的字段 fields_spec = { "brand": "自行车的品牌,例如:Decathlon, Trek, Giant。", "model": "自行车的具体型号。", "bike_type": "自行车类型,例如:公路车(road bike)、山地车(mountain bike)、城市车(city bike)。", "frame_size": "车架尺寸,单位厘米(cm)或英寸(\“),例如:54cm, M, L。", "year": "购买年份或车型年份,是一个整数。", "condition": "车况描述,例如:neuf(全新)、très bon état(非常好)、bon état(好)、à rénover(需要翻新)。", "price": "价格,以欧元为单位的数字。如果免费则为0.0,如果价格可议则为字符串'negotiable'。", "location": "商品所在的城市或地区。", "description_summary": "对商品描述核心卖点的简短总结,不超过30个词。" } # 假设我们已经有了 product_description if product_description: prompt_messages = build_extraction_prompt(product_description, fields_spec) # 打印System Prompt看看(在实际调用前) print("System Prompt预览:") print(prompt_messages[0]['content'][:300])

    Prompt 设计技巧

    • 系统指令(System):用于设定 AI 的角色和基础规则。这里明确其为“数据提取助手”,并给出了详细的字段定义和提取规则。规则越具体,AI 输出越可控。
    • 用户指令(User):清晰给出待处理的文本。格式要干净。
    • 字段定义:每个字段都配有一句简单的说明和示例,这能极大地提升 AI 的理解准确性。例如,明确“价格可议”的输出格式,避免了 AI 自由发挥。
    • 输出格式:强制要求输出“纯 JSON 对象”,并强调不要任何额外格式。这是为了便于我们后续用json.loads()直接解析。

    3.4 调用 ChatGPT API 并解析结果

    现在,我们将精心设计的 Prompt 发送给 OpenAI。

    def extract_with_chatgpt(messages, model="gpt-3.5-turbo"): """ 调用ChatGPT API进行信息提取。 :param messages: 构建好的消息列表 :param model: 使用的模型,gpt-3.5-turbo性价比高,gpt-4准确率可能更高但更贵。 :return: 提取出的结构化数据(字典),或None(如果失败) """ try: response = openai.ChatCompletion.create( model=model, messages=messages, temperature=0.1, # 温度设低,让输出更确定、更少随机性 max_tokens=500 # 根据输出字段数量设定,预留足够空间 ) # 获取AI返回的文本内容 result_text = response.choices[0].message.content.strip() # 尝试解析为JSON # AI有时会在JSON外加一层```json ```的markdown标记,需要处理 if result_text.startswith('```json'): result_text = result_text[7:-3].strip() # 去除 ```json 和 ``` elif result_text.startswith('```'): result_text = result_text[3:-3].strip() # 去除通用的 ``` extracted_data = json.loads(result_text) return extracted_data except json.JSONDecodeError as e: print(f"解析AI返回的JSON失败: {e}") print(f"原始返回内容: {result_text}") # 这里可以加入重试或更复杂的清洗逻辑 return None except openai.error.OpenAIError as e: print(f"调用OpenAI API失败: {e}") return None # 执行提取 if product_description: extracted_info = extract_with_chatgpt(prompt_messages, model="gpt-3.5-turbo") if extracted_info: print("成功提取的结构化数据:") print(json.dumps(extracted_info, indent=2, ensure_ascii=False))

    关键参数解析

    • modelgpt-3.5-turbo在成本(约 $0.002 / 1K tokens)和性能之间取得了很好的平衡,非常适合此类任务。如果对准确性要求极高且预算充足,可以尝试gpt-4
    • temperature:设置为0.1(接近0)。在信息提取任务中,我们需要的是确定性的、一致的输出,而不是创造性。低温度值能确保对于相同的输入,AI 的输出变化很小。
    • max_tokens:根据你期望的 JSON 输出长度来设定。一个包含10个字段的 JSON 对象,大约需要 200-300 个 token。设置一个稍大的值(如500)可以避免输出被截断。
    • 错误处理:非常重要!AI 可能偶尔不按格式输出,json.loads()会失败。代码中捕获了JSONDecodeError并打印原始内容,便于调试和优化 Prompt。

    3.5 数据后处理与存储

    拿到结构化的 JSON 数据后,我们可以进行一些简单的清洗,然后保存起来。

    import pandas as pd from datetime import datetime def clean_and_validate_data(data_dict, source_url): """ 对提取的数据进行简单的清洗和验证,并添加元数据。 """ if not data_dict: return None # 1. 添加元数据 data_dict['extraction_timestamp'] = datetime.now().isoformat() data_dict['source_url'] = source_url # 2. 简单的数据清洗(示例) # 确保价格是数字或特定字符串 price = data_dict.get('price') if price is not None: if isinstance(price, str) and price.lower() in ['gratuit', 'free', '0']: data_dict['price'] = 0.0 elif isinstance(price, str) and 'négociable' in price.lower(): data_dict['price'] = 'negotiable' # 可以尝试将字符串数字转为浮点数 elif isinstance(price, str) and price.replace('.', '', 1).isdigit(): data_dict['price'] = float(price) # 3. 验证必要字段(可选) # if not data_dict.get('brand'): # print(f"警告:从 {source_url} 提取的数据缺少品牌信息。") return data_dict def save_to_csv(data_list, filename='leboncoin_extracted.csv'): """ 将数据列表保存到CSV文件。 """ if not data_list: print("没有数据可保存。") return df = pd.DataFrame(data_list) # 重新排列列的顺序,让元数据在最后 cols = [c for c in df.columns if c not in ['extraction_timestamp', 'source_url']] cols += ['extraction_timestamp', 'source_url'] df = df[cols] df.to_csv(filename, index=False, encoding='utf-8-sig') # utf-8-sig 方便Excel打开 print(f"数据已保存到 {filename},共 {len(df)} 条记录。") # 主流程示例 all_extracted_data = [] urls_to_scrape = [...] # 你的目标URL列表 for url in urls_to_scrape: print(f"处理: {url}") html = fetch_page(url) if not html: continue desc = extract_description(html) if not desc: continue prompt = build_extraction_prompt(desc, fields_spec) data = extract_with_chatgpt(prompt) if data: cleaned_data = clean_and_validate_data(data, url) if cleaned_data: all_extracted_data.append(cleaned_data) # 出于礼貌和避免被封,建议在请求间添加延迟 time.sleep(1) # 保存所有数据 if all_extracted_data: save_to_csv(all_extracted_data)

    至此,一个完整的、针对 Leboncoin 的智能数据提取流水线就搭建完成了。你可以通过循环一个 URL 列表,来批量处理多个商品页面。

    4. 成本控制、优化与规模化实战

    项目跑起来后,你会立刻关注两个实际问题:成本稳定性。毕竟,ChatGPT API 是按 token 收费的。

    4.1 成本估算与优化策略

    假设我们处理一条商品描述,平均有 200 个单词(约 250 个 token)。我们的 Prompt(系统指令 + 用户指令)大约有 300 个 token。那么一次 API 调用的输入 token 约为 550 个。输出一个包含10个字段的 JSON,大约需要 150 个 token。总计约700 tokens/次

    • 使用gpt-3.5-turbo模型:输入 $0.0005 /1K tokens,输出 $0.0015 /1K tokens。
    • 单次调用成本 ≈(0.55 * 0.0005) + (0.15 * 0.0015) = 0.000275 + 0.000225 = $0.0005(即万分之五美元)。
    • 处理1000 个商品的成本大约是$0.5。处理 1 万个商品约 $5。这个成本对于个人项目或小规模商业分析是可以接受的。

    优化策略

    1. 精简 Prompt:检查系统指令,去掉不必要的描述性语言,保持指令清晰且简洁。字段说明也可以更精炼。
    2. 缓存结果:对于相同的或极其相似的描述,可以不必重复调用 API。建立一个本地缓存(例如用sqlite数据库存储(描述文本哈希值, 提取结果)),在调用前先查询缓存。
    3. 批量处理:OpenAI API 支持在单次请求中处理多个独立的对话吗?不直接支持。但你可以将多个商品的描述文本,通过精心设计的 Prompt,让 AI 一次性返回一个包含多个商品信息的 JSON 数组。这需要更复杂的 Prompt 工程和错误处理,但能减少 API 调用次数。注意:这可能会触及上下文长度限制(gpt-3.5-turbo是 4096 tokens),且一个错误可能导致整批失败。
    4. 模型选择:对于绝大多数信息提取任务,gpt-3.5-turbo已经足够准确。仅在字段非常复杂、描述极其模糊时,才考虑使用更昂贵的gpt-4

    4.2 提升准确率与鲁棒性

    即使 ChatGPT 很强大,提取结果也不可能 100% 准确。我们需要一套机制来评估和提升。

    1. 设计验证规则:在后处理阶段 (clean_and_validate_data函数) 加入业务逻辑验证。

      • 范围检查:自行车的价格通常在一定范围内(如 50-5000 欧),年份不会是未来年份。
      • 逻辑一致性:如果“车况”是“全新(neuf)”,那么“年份”很可能就是今年或去年。
      • 必填字段检查:对于分析至关重要的字段(如价格、品牌),如果为null,可以标记该条数据质量较低。
    2. 实施人工审核与反馈循环

      • 在初始阶段,随机抽取一部分(比如 5%)的提取结果进行人工核对。
      • 记录 AI 出错的模式。是某个字段总是提取不到?还是对某种表述理解有误?
      • 根据这些错误样本,迭代优化你的 Prompt。这是提升准确率最有效的方法。例如,如果发现 AI 总是把“Vélo de route”(公路车)错误归类为“VTT”(山地车),就在 Prompt 的bike_type字段说明里加入更明确的区分定义和反例。
    3. 使用更结构化的输出格式(Function Calling):OpenAI API 提供了Function Calling功能。你可以定义一个“函数”,描述其参数(即你想要提取的字段的 JSON Schema),然后让 AI 返回一个符合该 Schema 的 JSON 对象。这种方式比纯文本指令更规范,能强制 AI 输出特定格式,通常准确率更高,且更容易集成。这可以替代我们上面手动构建系统指令的方法。

    4.3 规模化与生产部署考量

    如果要从一个实验脚本升级为一个可持续运行的生产服务,需要考虑以下几点:

    1. 任务队列与异步处理:使用Celery+RedisRQ等工具,将抓取 URL、提取信息等任务放入队列,由后台工作进程异步执行。这能提高吞吐量,并实现失败重试。
    2. 反爬策略应对:Leboncoin 可能有反爬机制。除了设置合理的请求间隔(time.sleep),还需要:
      • 使用代理 IP 池轮换 IP 地址。
      • 随机化 User-Agent。
      • 模拟更真实的浏览器行为(可考虑使用seleniumplaywright,但资源消耗更大)。
    3. 监控与告警:监控 API 调用成功率、费用消耗、数据提取的字段填充率(非空率)。设置告警,当错误率突增或费用异常时通知你。
    4. 数据存储:对于大规模数据,CSV 文件会变得难以管理。应考虑使用数据库,如PostgreSQLMongoDB。数据库便于查询、去重和建立数据之间的关系。
    5. 模块化设计:将代码拆分为独立模块:crawler.py(抓取)、extractor.py(AI 提取)、cleaner.py(清洗)、storage.py(存储)。这样便于维护和测试。

    5. 常见问题与排查技巧实录

    在实际操作中,你肯定会遇到各种问题。以下是我在类似项目中踩过的坑和解决方案。

    5.1 API 调用失败与错误处理

    问题现象可能原因解决方案
    openai.error.AuthenticationErrorAPI Key 错误或过期。检查.env文件中的OPENAI_API_KEY是否正确,或在 OpenAI 平台验证 Key 是否有效、是否有余额。
    openai.error.RateLimitError达到 API 调用速率限制(RPM/TPM)。免费用户和付费用户都有限制。最佳实践是加入指数退避重试机制。在代码中捕获此异常,等待一段时间(如2**retry_count秒)后重试。
    openai.error.APIError或网络超时OpenAI 服务端临时问题或网络不稳定。同样,实现重试逻辑。对于非关键任务,可以记录错误并跳过当前条目,继续处理下一个。
    json.JSONDecodeErrorAI 的回复不是有效的 JSON。这是最常见的问题之一。首先打印出result_text查看 AI 到底返回了什么。通常是因为 Prompt 指令不够严格,AI 在 JSON 前后加了解释性文字。优化 Prompt,强调“只输出 JSON”。也可以在代码中加入更强大的文本清洗,尝试匹配{...}之间的内容。

    重试机制代码示例

    import time from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type import openai.error @retry( stop=stop_after_attempt(3), # 最多重试3次 wait=wait_exponential(multiplier=1, min=4, max=10), # 指数退避等待 retry=retry_if_exception_type((openai.error.RateLimitError, openai.error.APIError, openai.error.Timeout)) ) def robust_chatgpt_call(messages, model="gpt-3.5-turbo"): """带有重试机制的API调用函数""" response = openai.ChatCompletion.create( model=model, messages=messages, temperature=0.1, max_tokens=500 ) return response

    使用tenacity库可以优雅地实现重试逻辑。

    5.2 数据提取不准确

    问题诊断与解决
    字段遗漏(应为null但实际有值,或反之)检查 Prompt 中该字段的说明是否清晰。例如,对于“颜色”字段,如果描述没提,AI 可能会猜一个常见色。在 Prompt 中必须强调“仅提取明确提及的信息,否则为 null”。
    格式不一致(如价格有时是字符串,有时是数字)在 Prompt 的“提取规则”部分,用非常具体、带示例的语句规定输出格式。例如:“价格必须为数字(浮点数),或字符串 ‘negotiable’,或 0.0(如果免费)。” 在后处理代码中再做一次强制转换作为兜底。
    理解偏差(如把“Vélo course”理解为“比赛”而非“公路车”)这是语言模型固有的歧义问题。提供更精确的映射关系。在bike_type的说明里可以写:“‘Vélo de course’, ‘Vélo route’, ‘course’ 都应提取为 ‘road bike’;‘VTT’, ‘montagne’ 提取为 ‘mountain bike’。” 建立一个小的同义词表放在 Prompt 里。
    语言问题(描述是法语,但提取指令是英语)虽然 ChatGPT 是多语言的,但为了最佳效果,建议让系统指令和字段说明与目标描述文本使用同一种语言。如果你的目标网站是 Leboncoin(法语),那么最好用法语来写 Prompt。这能减少跨语言理解带来的误差。

    5.3 网页抓取不稳定

    问题解决方案
    HTML 结构变化,选择器失效不要依赖单一的、过于具体的 CSS 选择器。尝试寻找更稳定的父级容器,或者使用包含部分文本内容的查找方法(如soup.find(string=re.compile(‘Description’))然后找其父元素)。定期运行测试脚本,监控抓取成功率。
    遇到 JavaScript 渲染的页面requests获取的是静态 HTML。如果关键信息由 JavaScript 动态加载,你需要使用seleniumplaywright这类能驱动真实浏览器的工具。这会大幅增加复杂性和资源消耗,应作为备选方案。
    IP 被暂时封锁这是最头疼的。立即措施:大幅增加请求间隔(如time.sleep(10 + random.random()*5)),并更换 User-Agent。长期方案:使用住宅代理 IP 池。对于个人项目,最务实的做法是控制抓取速度,模拟人类浏览行为,并准备好一旦被封就暂停一段时间。

    这个项目完美地展示了如何将前沿的 AI 能力与经典的自动化脚本结合起来,解决一个非常实际的数据获取难题。它不再需要你为每一个网站、每一种商品类别编写脆弱的解析规则,而是提供了一个通用的、基于理解的解决方案框架。你可以很容易地将这个框架适配到其他类似的平台,比如其他国家的二手网站、分类信息网站,甚至是新闻摘要、评论情感分析等领域。核心在于,你掌握了如何用自然语言(Prompt)来“编程”,指挥 AI 为你完成繁琐的信息结构化工作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 17:10:25

如何用500KB小工具完全替代AWCC:AlienFX Tools终极指南

如何用500KB小工具完全替代AWCC&#xff1a;AlienFX Tools终极指南 【免费下载链接】alienfx-tools Alienware systems lights, fans, and power control tools and apps 项目地址: https://gitcode.com/gh_mirrors/al/alienfx-tools 厌倦了Alienware Command Center&am…

作者头像 李华
网站建设 2026/5/2 17:09:50

OpenClaw中文教学技能包:从内容规范化到安全发布的工程实践

1. 项目概述&#xff1a;一个为中文教学场景设计的OpenClaw技能包如果你正在探索如何利用AI工具来优化和规模化你的中文教学流程&#xff0c;特别是当你手头有一堆零散的课程录音、视频字幕或文字稿&#xff0c;需要将它们系统化地整理成结构化的课程内容时&#xff0c;那么你遇…

作者头像 李华
网站建设 2026/5/2 17:07:23

火警电话,不能问对方鸡毛蒜皮,要准确说出对方姓名位置

前几天在公交车上&#xff0c;看了个火警广告&#xff0c;教育大家怎么打火警电话。实际上&#xff0c;广告内容有严重问题&#xff0c;根本就是故意拖延。内容就是接线员反复问对方鸡毛蒜皮&#xff0c;什么在哪里、叫什么这一类。设身处地想想&#xff0c;你遇到火情&#xf…

作者头像 李华
网站建设 2026/5/2 17:05:25

Arm Neoverse MMU S3性能监控与优化实践

1. Arm Neoverse MMU S3性能监控体系解析 在Arm Neoverse架构中&#xff0c;内存管理单元(MMU)的性能监控能力对于系统调优至关重要。MMU S3作为最新一代实现&#xff0c;基于SMMUv3架构规范&#xff0c;提供了细粒度的性能事件监控机制。这套体系的核心价值在于能够捕捉内存子…

作者头像 李华
网站建设 2026/5/2 17:04:23

如何快速掌握KLayout版图设计:开源EDA工具的完整入门指南

如何快速掌握KLayout版图设计&#xff1a;开源EDA工具的完整入门指南 【免费下载链接】klayout KLayout Main Sources 项目地址: https://gitcode.com/gh_mirrors/kl/klayout KLayout是一款功能强大的开源版图设计工具&#xff0c;专为集成电路设计、PCB布局和微机电系统…

作者头像 李华