通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI实战爬虫数据清洗与信息摘要生成你是不是也遇到过这种情况辛辛苦苦写了个爬虫吭哧吭哧跑了一晚上结果拿到的数据乱七八糟——正文里混着广告、重复内容一大堆、关键信息散落在各个角落整理起来比爬数据还累。我之前处理一个新闻网站的数据爬下来几千条光是人工筛选和整理摘要就花了两天时间眼睛都快看花了。后来我发现其实这种重复性高、规则性强的文本处理工作交给合适的大语言模型来做效率能提升几十倍。今天我就跟你分享一下怎么用通义千问1.5-1.8B-Chat这个轻量级模型通过WebUI来搞定爬虫数据的清洗和摘要生成。这个模型虽然参数不大但处理这类结构化信息提取任务特别合适而且经过GPTQ-Int4量化后对硬件要求很低普通电脑就能跑起来。1. 为什么用大模型处理爬虫数据你可能觉得爬虫数据清洗用正则表达式或者写点规则不就行了吗确实对于结构非常规整的网站传统方法很有效。但现实情况往往更复杂。我最近处理过一个电商商品页面不同商家的描述格式千差万别。有的把价格放在“售价”后面有的写“价格”还有的直接写“¥99”。用规则去匹配得写一堆正则还经常漏掉一些变体。更麻烦的是有些页面会有“推荐商品”、“看了又看”这种模块爬下来的数据里混着不相关的内容。这时候大模型的优势就体现出来了。它不需要你告诉它价格可能出现在哪些关键词后面它自己能从上下文中理解什么是价格。你只需要告诉它“从这段文本里提取商品名称、价格和主要特点”它就能给你整理得明明白白。通义千问1.5-1.8B-Chat这个版本在信息提取和摘要生成上表现不错关键是它比较“听话”——你让它输出JSON格式它基本上就会按JSON格式来这对于后续的数据入库特别友好。2. 环境准备与WebUI部署先说说怎么把这个模型跑起来。我选择的是GPTQ-Int4量化版本这个版本在几乎不损失精度的情况下把模型大小压缩了很多运行起来内存占用小速度也快。2.1 基础环境搭建如果你已经有Python环境安装起来很简单。我建议用conda创建一个独立环境避免包冲突。# 创建并激活环境 conda create -n qwen_clean python3.10 conda activate qwen_clean # 安装基础依赖 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 根据你的CUDA版本调整 pip install transformers accelerate2.2 WebUI部署与模型加载现在有很多现成的WebUI框架可以用我比较喜欢用Gradio它简单直观部署也方便。# webui_demo.py import gradio as gr from transformers import AutoModelForCausalLM, AutoTokenizer import torch # 加载模型和分词器 model_name Qwen/Qwen1.5-1.8B-Chat-GPTQ-Int4 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto ) def chat_with_model(message, history): # 构建对话格式 messages [ {role: system, content: 你是一个专业的数据处理助手擅长从文本中提取结构化信息和生成简洁摘要。}, {role: user, content: message} ] # 应用聊天模板 text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) # 生成回复 inputs tokenizer(text, return_tensorspt).to(model.device) with torch.no_grad(): outputs model.generate(**inputs, max_new_tokens512) response tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokensTrue) return response # 创建Gradio界面 demo gr.ChatInterface( fnchat_with_model, title通义千问数据清洗助手, description输入爬虫获取的原始文本我会帮你提取关键信息和生成摘要 ) if __name__ __main__: demo.launch(server_name0.0.0.0, server_port7860)运行这个脚本在浏览器打开http://localhost:7860就能看到Web界面了。界面很简洁左边是聊天区域右边可以调整一些参数。第一次运行会下载模型大概需要3-4GB的磁盘空间。下载完成后后续启动就很快了。在我的GTX 3060笔记本上生成一段摘要大概需要2-3秒完全能满足批量处理的需求。3. 设计有效的Prompt模板用大模型处理数据最关键的就是Prompt设计。设计得好模型输出稳定可靠设计得不好每次输出格式都不一样后续处理就麻烦了。3.1 信息提取Prompt设计对于爬虫数据清洗我通常设计两种类型的Prompt一种是提取特定字段另一种是自由提取关键信息。先看个商品信息提取的例子def extract_product_info(raw_text): prompt f 请从以下商品描述文本中提取结构化信息并以JSON格式输出。 要求 1. 提取商品名称、价格、主要特点、适用场景 2. 价格统一转换为数字格式如99.00 3. 主要特点提取3-5个关键点 4. 如果某个信息不存在对应字段值为null 文本内容 {raw_text} 请输出JSON格式 {{ product_name: 商品名称, price: 价格数字, features: [特点1, 特点2, 特点3], scenarios: [场景1, 场景2] }} return prompt这个Prompt有几个设计要点明确输出格式直接告诉模型要输出JSON并给出具体格式字段说明清晰每个字段要提取什么内容都说清楚处理边界情况明确说明信息不存在时怎么处理格式要求具体比如价格要转成数字特点要列表形式实际使用时你可以根据你的数据特点调整字段。比如处理新闻数据时字段可能是“标题”、“发布时间”、“作者”、“正文摘要”、“关键词”。3.2 摘要生成Prompt设计对于长文本摘要Prompt设计要引导模型抓住重点而不是简单截取开头几句。def generate_summary(long_text, summary_lengthmedium): length_map { short: 50字左右, medium: 100-150字, long: 200-300字 } prompt f 请为以下文本生成一个简洁的摘要。 要求 1. 摘要长度{length_map[summary_length]} 2. 抓住核心内容和关键信息 3. 保持客观不要添加个人观点 4. 语言流畅逻辑连贯 文本内容 {long_text} 摘要 return prompt我发现在摘要生成时明确指定字数范围很重要。只说“简洁摘要”模型可能生成30字也可能生成300字。指定了字数范围输出就稳定多了。3.3 批量处理与格式统一爬虫数据往往是成批的我们需要确保每一条数据的处理结果格式一致。这里有个小技巧在Prompt里加入示例。def batch_extract_template(): prompt 你是一个数据提取专家。请从每条文本中提取公司名称、成立时间和主营业务。 输出格式要求 每条结果以JSON格式输出多个结果用两个换行符分隔。 示例 输入阿里巴巴集团成立于1999年主要业务包括电子商务、云计算、数字媒体等。 输出{company_name: 阿里巴巴集团, found_year: 1999, main_business: [电子商务, 云计算, 数字媒体]} 输入腾讯公司于1998年成立是一家互联网综合服务提供商。 输出{company_name: 腾讯公司, found_year: 1998, main_business: [互联网综合服务]} 现在请处理以下文本 return prompt给模型一两个示例它就能很好地理解你想要什么格式。这对于批量处理特别有用能保证所有输出都是统一的JSON方便后续用Python直接解析成字典列表。4. 实战新闻数据清洗与摘要我最近用这个流程处理了一批科技新闻数据效果很不错。跟你分享一下具体怎么操作。4.1 原始数据示例爬虫抓取的数据通常长这样【最新消息】苹果公司今日凌晨发布全新iPhone 16系列手机起售价7999元。这款手机搭载了最新的A18芯片性能提升30%。同时电池续航也有显著改善据称可支持全天候使用。发布时间2024年9月10日。作者科技快讯。标签苹果, iPhone, 手机发布。 相关阅读安卓手机市场最新动态...这里是无关的推荐内容 网友评论我觉得价格太贵了...这里是评论内容我们需要从这里面提取出核心信息并过滤掉无关内容。4.2 完整处理流程我写了一个完整的处理脚本你可以参考这个思路import json import re from typing import List, Dict import requests class NewsProcessor: def __init__(self, api_urlhttp://localhost:7860): self.api_url api_url def clean_raw_text(self, raw_text: str) - str: 初步清洗移除明显无关内容 # 移除“相关阅读”之后的内容 if 相关阅读 in raw_text: raw_text raw_text.split(相关阅读)[0] # 移除“网友评论”之后的内容 if 网友评论 in raw_text: raw_text raw_text.split(网友评论)[0] # 移除多余的空白字符 raw_text re.sub(r\s, , raw_text).strip() return raw_text def build_extraction_prompt(self, text: str) - str: 构建信息提取Prompt prompt f 请从以下新闻文本中提取结构化信息。 要求 1. 提取新闻标题、发布时间、作者、核心内容摘要 2. 摘要长度控制在100字左右 3. 识别并提取标签最多5个 4. 如果信息不存在对应字段值为null 新闻文本 {text} 请以JSON格式输出包含以下字段 - title: 新闻标题 - publish_time: 发布时间格式YYYY-MM-DD - author: 作者 - summary: 内容摘要 - tags: 标签列表 - has_price: 是否包含价格信息true/false return prompt def call_model(self, prompt: str) - str: 调用模型API # 这里简化了实际使用时需要根据你的WebUI接口调整 payload { message: prompt, history: [] } try: response requests.post( f{self.api_url}/chat, jsonpayload, timeout30 ) response.raise_for_status() return response.json()[response] except Exception as e: print(fAPI调用失败: {e}) return None def parse_model_response(self, response: str) - Dict: 解析模型返回的JSON # 尝试从响应中提取JSON部分 json_match re.search(r\{.*\}, response, re.DOTALL) if json_match: try: return json.loads(json_match.group()) except json.JSONDecodeError: print(fJSON解析失败: {response}) # 如果提取失败返回空结构 return { title: None, publish_time: None, author: None, summary: None, tags: [], has_price: False } def process_news(self, raw_text: str) - Dict: 处理单条新闻 # 1. 初步清洗 cleaned_text self.clean_raw_text(raw_text) # 2. 构建Prompt prompt self.build_extraction_prompt(cleaned_text) # 3. 调用模型 response self.call_model(prompt) if not response: return None # 4. 解析结果 result self.parse_model_response(response) # 5. 添加原始文本哈希用于去重 import hashlib text_hash hashlib.md5(cleaned_text.encode()).hexdigest()[:8] result[text_hash] text_hash return result def batch_process(self, news_list: List[str]) - List[Dict]: 批量处理新闻 results [] seen_hashes set() for i, news_text in enumerate(news_list): print(f处理第 {i1}/{len(news_list)} 条新闻...) result self.process_news(news_text) if result and result[text_hash] not in seen_hashes: seen_hashes.add(result[text_hash]) results.append(result) # 简单限流避免请求过快 import time time.sleep(0.5) return results # 使用示例 if __name__ __main__: processor NewsProcessor() # 模拟一批新闻数据 sample_news [ 【最新消息】苹果公司今日凌晨发布全新iPhone 16系列手机起售价7999元。这款手机搭载了最新的A18芯片性能提升30%。同时电池续航也有显著改善据称可支持全天候使用。发布时间2024年9月10日。作者科技快讯。标签苹果, iPhone, 手机发布。, 特斯拉宣布新款Model 3降价现价25.99万元起。此次降价旨在提升市场竞争力同时推出了新的自动驾驶套餐。发布时间2024年8月15日。作者汽车之家。, # ... 更多新闻数据 ] results processor.batch_process(sample_news) # 保存结果 with open(processed_news.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2) print(f处理完成共处理 {len(results)} 条有效新闻)4.3 处理效果分析运行这个脚本原来杂乱的爬虫数据就被整理成了干净的结构化数据。以第一条新闻为例处理后的结果大概是这样的{ title: 苹果发布全新iPhone 16系列手机, publish_time: 2024-09-10, author: 科技快讯, summary: 苹果公司今日发布iPhone 16系列手机起售价7999元。新品搭载A18芯片性能提升30%电池续航有显著改善支持全天候使用。, tags: [苹果, iPhone, 手机发布, 科技, 新品], has_price: true, text_hash: a1b2c3d4 }可以看到无关的“相关阅读”和“网友评论”被过滤掉了关键信息都被提取出来并且格式统一。这样的数据直接就能导入数据库或者用于进一步分析。5. 处理电商商品数据的技巧新闻数据相对规整电商商品页面就更复杂了。不同平台、不同商家的描述格式千差万别。我总结了一些处理这类数据的经验。5.1 多轮对话提取对于特别复杂的商品描述可以用多轮对话的方式让模型一步步提取信息。def extract_product_details(raw_description): 多轮对话提取商品详情 # 第一轮提取基本信息 prompt1 f 请从以下商品描述中提取基本信息 {raw_description} 请提取 1. 商品名称 2. 品牌 3. 主要类别如电子产品、服装、食品等 # 假设第一轮回复是 basic_info basic_info call_model(prompt1) # 第二轮提取规格参数 prompt2 f 基于之前的分析现在请提取详细规格 商品描述{raw_description} 已提取的基本信息{basic_info} 请提取 1. 颜色/款式选项 2. 尺寸/规格参数 3. 材质/成分信息 4. 特殊功能特点 # 第三轮提取价格库存 prompt3 f 现在请提取商业信息 商品描述{raw_description} 请提取 1. 价格信息当前价格、原价、折扣等 2. 库存状态有货/缺货/预售等 3. 配送信息 4. 促销活动 # 最后整合所有信息 final_prompt f 请将以下信息整合为完整的商品数据结构 基本信息{basic_info} 规格参数{specs_info} 商业信息{commerce_info} 请输出统一的JSON格式。 return call_model(final_prompt)这种方法虽然调用次数多但提取更准确特别适合那些信息分散在不同段落的情况。5.2 处理图片描述文本很多商品页面除了文字描述还有图片的alt文本或者图片描述。这些文本往往包含重要信息但格式很不规范。def process_image_descriptions(img_texts): 处理图片描述文本 prompt f 以下是商品页面的图片描述文本请从中提取有用的商品信息 图片描述列表 {chr(10).join(f- {text} for text in img_texts)} 请提取 1. 商品的不同角度展示信息 2. 商品的实际使用场景 3. 包装或配件信息 4. 尺寸对比或参考信息 注意忽略纯装饰性或重复的描述。 return call_model(prompt)5.3 价格信息规范化价格信息是最重要的但也是最混乱的。不同商家写法各异def normalize_price_info(price_text): 规范化价格信息 prompt f 请从以下价格相关文本中提取规范化信息 文本{price_text} 请识别 1. 当前售价取最低价格 2. 原价如果有 3. 折扣力度如果有 4. 价格单位元/美元等 5. 是否包邮 输出要求 - 价格统一转换为数字如99.99 - 货币单位统一为CNY - 包邮信息转换为布尔值 return call_model(prompt)6. 性能优化与批量处理建议当你需要处理成千上万条数据时性能就很重要了。我总结了一些优化经验。6.1 批量请求策略不要一条一条地请求可以适当批量处理def batch_process_texts(texts, batch_size5): 批量处理文本 results [] for i in range(0, len(texts), batch_size): batch texts[i:ibatch_size] # 构建批量处理的Prompt batch_prompt 请分别处理以下文本\n\n for j, text in enumerate(batch): batch_prompt f文本{j1}\n{text}\n\n batch_prompt 请为每个文本提取关键信息输出格式为JSON列表。 batch_result call_model(batch_prompt) results.extend(parse_batch_result(batch_result)) # 添加延迟避免请求过快 time.sleep(1) return results6.2 缓存与去重很多爬虫数据会有重复内容可以先做一轮去重def deduplicate_texts(texts): 基于内容相似度去重 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity # 计算文本相似度 vectorizer TfidfVectorizer() tfidf_matrix vectorizer.fit_transform(texts) similarity_matrix cosine_similarity(tfidf_matrix) # 找出相似度高的文本 duplicates set() for i in range(len(texts)): for j in range(i1, len(texts)): if similarity_matrix[i][j] 0.8: # 相似度阈值 duplicates.add(j) # 返回去重后的文本 return [texts[i] for i in range(len(texts)) if i not in duplicates]6.3 错误处理与重试网络请求总会有失败的时候要做好错误处理def robust_model_call(prompt, max_retries3): 带重试的模型调用 for attempt in range(max_retries): try: response call_model(prompt) if response and validate_response(response): return response except Exception as e: print(f第{attempt1}次尝试失败: {e}) if attempt max_retries - 1: wait_time 2 ** attempt # 指数退避 time.sleep(wait_time) print(所有重试均失败) return None def validate_response(response): 验证响应是否有效 # 检查响应是否包含必要信息 required_fields [title, summary] # 根据你的需求调整 try: data json.loads(response) for field in required_fields: if field not in data: return False return True except: return False7. 实际应用中的注意事项在实际项目中用了一段时间我总结了一些需要注意的地方。7.1 Prompt设计的经验保持一致性很重要。如果你这次让模型输出“价格”下次让输出“售价”虽然意思差不多但解析起来就麻烦。最好在项目开始时就确定好字段命名规范。给模型一些思考空间。有时候在Prompt里加一句“请仔细分析文本内容”效果会比直接下指令好。模型需要“理解”文本而不是简单地“匹配”关键词。处理不确定性。爬虫数据里经常有缺失信息要在Prompt里明确告诉模型怎么处理“如果找不到XX信息就输出null或空字符串”。这样能保证输出结构的一致性。7.2 模型输出的稳定性通义千问1.5-1.8B-Chat在格式遵循上表现不错但也不是100%稳定。我建议后处理校验对模型输出做一次格式校验比如检查JSON是否能正常解析必要字段是否存在。备用方案对于特别重要的字段可以准备正则表达式作为备用提取方案。人工审核样本定期抽样检查看看模型有没有什么奇怪的输出模式。7.3 成本与效率平衡这个模型本地部署其实没有API调用成本主要成本是电费和硬件折旧。但处理大量数据时时间成本也要考虑。我的经验是对于实时性要求不高的后台任务可以慢慢处理对于需要快速响应的场景可以考虑先用规则过滤掉简单情况复杂的再交给模型定期评估效果如果某些类型的文本模型处理不好可以考虑优化爬虫让原始数据更干净8. 总结用通义千问1.5-1.8B-Chat处理爬虫数据给我的感觉是“刚刚好”。它没有大到需要昂贵的GPU也没有小到处理不了复杂任务。对于大多数爬虫数据清洗和摘要生成的需求它都能很好地满足。实际用下来最深的体会是Prompt设计真的需要花心思。同样的模型不同的Prompt设计效果能差好几倍。开始的时候多花点时间设计好的Prompt模板后面批量处理时就轻松多了。另一个感受是这种方案特别适合处理“半结构化”数据——就是那种有点规律但又不太规整的数据。完全规整的数据用正则表达式更快完全无结构的数据需要更大的模型而这种半结构化的文本用这个大小的模型处理性价比最高。如果你也在做爬虫相关的数据清洗工作真的建议试试这个方案。从配置环境到跑通第一个例子一两个小时就够了。一旦流程跑通后面就是批量处理的事情能省下大量的手工整理时间。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI实战:爬虫数据清洗与信息摘要生成
通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI实战爬虫数据清洗与信息摘要生成你是不是也遇到过这种情况辛辛苦苦写了个爬虫吭哧吭哧跑了一晚上结果拿到的数据乱七八糟——正文里混着广告、重复内容一大堆、关键信息散落在各个角落整理起来比爬数据还累。我之前处理一个新闻网站的数据爬下来几千条光是人工筛选和整理摘要就花了两天时间眼睛都快看花了。后来我发现其实这种重复性高、规则性强的文本处理工作交给合适的大语言模型来做效率能提升几十倍。今天我就跟你分享一下怎么用通义千问1.5-1.8B-Chat这个轻量级模型通过WebUI来搞定爬虫数据的清洗和摘要生成。这个模型虽然参数不大但处理这类结构化信息提取任务特别合适而且经过GPTQ-Int4量化后对硬件要求很低普通电脑就能跑起来。1. 为什么用大模型处理爬虫数据你可能觉得爬虫数据清洗用正则表达式或者写点规则不就行了吗确实对于结构非常规整的网站传统方法很有效。但现实情况往往更复杂。我最近处理过一个电商商品页面不同商家的描述格式千差万别。有的把价格放在“售价”后面有的写“价格”还有的直接写“¥99”。用规则去匹配得写一堆正则还经常漏掉一些变体。更麻烦的是有些页面会有“推荐商品”、“看了又看”这种模块爬下来的数据里混着不相关的内容。这时候大模型的优势就体现出来了。它不需要你告诉它价格可能出现在哪些关键词后面它自己能从上下文中理解什么是价格。你只需要告诉它“从这段文本里提取商品名称、价格和主要特点”它就能给你整理得明明白白。通义千问1.5-1.8B-Chat这个版本在信息提取和摘要生成上表现不错关键是它比较“听话”——你让它输出JSON格式它基本上就会按JSON格式来这对于后续的数据入库特别友好。2. 环境准备与WebUI部署先说说怎么把这个模型跑起来。我选择的是GPTQ-Int4量化版本这个版本在几乎不损失精度的情况下把模型大小压缩了很多运行起来内存占用小速度也快。2.1 基础环境搭建如果你已经有Python环境安装起来很简单。我建议用conda创建一个独立环境避免包冲突。# 创建并激活环境 conda create -n qwen_clean python3.10 conda activate qwen_clean # 安装基础依赖 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 根据你的CUDA版本调整 pip install transformers accelerate2.2 WebUI部署与模型加载现在有很多现成的WebUI框架可以用我比较喜欢用Gradio它简单直观部署也方便。# webui_demo.py import gradio as gr from transformers import AutoModelForCausalLM, AutoTokenizer import torch # 加载模型和分词器 model_name Qwen/Qwen1.5-1.8B-Chat-GPTQ-Int4 tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto ) def chat_with_model(message, history): # 构建对话格式 messages [ {role: system, content: 你是一个专业的数据处理助手擅长从文本中提取结构化信息和生成简洁摘要。}, {role: user, content: message} ] # 应用聊天模板 text tokenizer.apply_chat_template( messages, tokenizeFalse, add_generation_promptTrue ) # 生成回复 inputs tokenizer(text, return_tensorspt).to(model.device) with torch.no_grad(): outputs model.generate(**inputs, max_new_tokens512) response tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokensTrue) return response # 创建Gradio界面 demo gr.ChatInterface( fnchat_with_model, title通义千问数据清洗助手, description输入爬虫获取的原始文本我会帮你提取关键信息和生成摘要 ) if __name__ __main__: demo.launch(server_name0.0.0.0, server_port7860)运行这个脚本在浏览器打开http://localhost:7860就能看到Web界面了。界面很简洁左边是聊天区域右边可以调整一些参数。第一次运行会下载模型大概需要3-4GB的磁盘空间。下载完成后后续启动就很快了。在我的GTX 3060笔记本上生成一段摘要大概需要2-3秒完全能满足批量处理的需求。3. 设计有效的Prompt模板用大模型处理数据最关键的就是Prompt设计。设计得好模型输出稳定可靠设计得不好每次输出格式都不一样后续处理就麻烦了。3.1 信息提取Prompt设计对于爬虫数据清洗我通常设计两种类型的Prompt一种是提取特定字段另一种是自由提取关键信息。先看个商品信息提取的例子def extract_product_info(raw_text): prompt f 请从以下商品描述文本中提取结构化信息并以JSON格式输出。 要求 1. 提取商品名称、价格、主要特点、适用场景 2. 价格统一转换为数字格式如99.00 3. 主要特点提取3-5个关键点 4. 如果某个信息不存在对应字段值为null 文本内容 {raw_text} 请输出JSON格式 {{ product_name: 商品名称, price: 价格数字, features: [特点1, 特点2, 特点3], scenarios: [场景1, 场景2] }} return prompt这个Prompt有几个设计要点明确输出格式直接告诉模型要输出JSON并给出具体格式字段说明清晰每个字段要提取什么内容都说清楚处理边界情况明确说明信息不存在时怎么处理格式要求具体比如价格要转成数字特点要列表形式实际使用时你可以根据你的数据特点调整字段。比如处理新闻数据时字段可能是“标题”、“发布时间”、“作者”、“正文摘要”、“关键词”。3.2 摘要生成Prompt设计对于长文本摘要Prompt设计要引导模型抓住重点而不是简单截取开头几句。def generate_summary(long_text, summary_lengthmedium): length_map { short: 50字左右, medium: 100-150字, long: 200-300字 } prompt f 请为以下文本生成一个简洁的摘要。 要求 1. 摘要长度{length_map[summary_length]} 2. 抓住核心内容和关键信息 3. 保持客观不要添加个人观点 4. 语言流畅逻辑连贯 文本内容 {long_text} 摘要 return prompt我发现在摘要生成时明确指定字数范围很重要。只说“简洁摘要”模型可能生成30字也可能生成300字。指定了字数范围输出就稳定多了。3.3 批量处理与格式统一爬虫数据往往是成批的我们需要确保每一条数据的处理结果格式一致。这里有个小技巧在Prompt里加入示例。def batch_extract_template(): prompt 你是一个数据提取专家。请从每条文本中提取公司名称、成立时间和主营业务。 输出格式要求 每条结果以JSON格式输出多个结果用两个换行符分隔。 示例 输入阿里巴巴集团成立于1999年主要业务包括电子商务、云计算、数字媒体等。 输出{company_name: 阿里巴巴集团, found_year: 1999, main_business: [电子商务, 云计算, 数字媒体]} 输入腾讯公司于1998年成立是一家互联网综合服务提供商。 输出{company_name: 腾讯公司, found_year: 1998, main_business: [互联网综合服务]} 现在请处理以下文本 return prompt给模型一两个示例它就能很好地理解你想要什么格式。这对于批量处理特别有用能保证所有输出都是统一的JSON方便后续用Python直接解析成字典列表。4. 实战新闻数据清洗与摘要我最近用这个流程处理了一批科技新闻数据效果很不错。跟你分享一下具体怎么操作。4.1 原始数据示例爬虫抓取的数据通常长这样【最新消息】苹果公司今日凌晨发布全新iPhone 16系列手机起售价7999元。这款手机搭载了最新的A18芯片性能提升30%。同时电池续航也有显著改善据称可支持全天候使用。发布时间2024年9月10日。作者科技快讯。标签苹果, iPhone, 手机发布。 相关阅读安卓手机市场最新动态...这里是无关的推荐内容 网友评论我觉得价格太贵了...这里是评论内容我们需要从这里面提取出核心信息并过滤掉无关内容。4.2 完整处理流程我写了一个完整的处理脚本你可以参考这个思路import json import re from typing import List, Dict import requests class NewsProcessor: def __init__(self, api_urlhttp://localhost:7860): self.api_url api_url def clean_raw_text(self, raw_text: str) - str: 初步清洗移除明显无关内容 # 移除“相关阅读”之后的内容 if 相关阅读 in raw_text: raw_text raw_text.split(相关阅读)[0] # 移除“网友评论”之后的内容 if 网友评论 in raw_text: raw_text raw_text.split(网友评论)[0] # 移除多余的空白字符 raw_text re.sub(r\s, , raw_text).strip() return raw_text def build_extraction_prompt(self, text: str) - str: 构建信息提取Prompt prompt f 请从以下新闻文本中提取结构化信息。 要求 1. 提取新闻标题、发布时间、作者、核心内容摘要 2. 摘要长度控制在100字左右 3. 识别并提取标签最多5个 4. 如果信息不存在对应字段值为null 新闻文本 {text} 请以JSON格式输出包含以下字段 - title: 新闻标题 - publish_time: 发布时间格式YYYY-MM-DD - author: 作者 - summary: 内容摘要 - tags: 标签列表 - has_price: 是否包含价格信息true/false return prompt def call_model(self, prompt: str) - str: 调用模型API # 这里简化了实际使用时需要根据你的WebUI接口调整 payload { message: prompt, history: [] } try: response requests.post( f{self.api_url}/chat, jsonpayload, timeout30 ) response.raise_for_status() return response.json()[response] except Exception as e: print(fAPI调用失败: {e}) return None def parse_model_response(self, response: str) - Dict: 解析模型返回的JSON # 尝试从响应中提取JSON部分 json_match re.search(r\{.*\}, response, re.DOTALL) if json_match: try: return json.loads(json_match.group()) except json.JSONDecodeError: print(fJSON解析失败: {response}) # 如果提取失败返回空结构 return { title: None, publish_time: None, author: None, summary: None, tags: [], has_price: False } def process_news(self, raw_text: str) - Dict: 处理单条新闻 # 1. 初步清洗 cleaned_text self.clean_raw_text(raw_text) # 2. 构建Prompt prompt self.build_extraction_prompt(cleaned_text) # 3. 调用模型 response self.call_model(prompt) if not response: return None # 4. 解析结果 result self.parse_model_response(response) # 5. 添加原始文本哈希用于去重 import hashlib text_hash hashlib.md5(cleaned_text.encode()).hexdigest()[:8] result[text_hash] text_hash return result def batch_process(self, news_list: List[str]) - List[Dict]: 批量处理新闻 results [] seen_hashes set() for i, news_text in enumerate(news_list): print(f处理第 {i1}/{len(news_list)} 条新闻...) result self.process_news(news_text) if result and result[text_hash] not in seen_hashes: seen_hashes.add(result[text_hash]) results.append(result) # 简单限流避免请求过快 import time time.sleep(0.5) return results # 使用示例 if __name__ __main__: processor NewsProcessor() # 模拟一批新闻数据 sample_news [ 【最新消息】苹果公司今日凌晨发布全新iPhone 16系列手机起售价7999元。这款手机搭载了最新的A18芯片性能提升30%。同时电池续航也有显著改善据称可支持全天候使用。发布时间2024年9月10日。作者科技快讯。标签苹果, iPhone, 手机发布。, 特斯拉宣布新款Model 3降价现价25.99万元起。此次降价旨在提升市场竞争力同时推出了新的自动驾驶套餐。发布时间2024年8月15日。作者汽车之家。, # ... 更多新闻数据 ] results processor.batch_process(sample_news) # 保存结果 with open(processed_news.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2) print(f处理完成共处理 {len(results)} 条有效新闻)4.3 处理效果分析运行这个脚本原来杂乱的爬虫数据就被整理成了干净的结构化数据。以第一条新闻为例处理后的结果大概是这样的{ title: 苹果发布全新iPhone 16系列手机, publish_time: 2024-09-10, author: 科技快讯, summary: 苹果公司今日发布iPhone 16系列手机起售价7999元。新品搭载A18芯片性能提升30%电池续航有显著改善支持全天候使用。, tags: [苹果, iPhone, 手机发布, 科技, 新品], has_price: true, text_hash: a1b2c3d4 }可以看到无关的“相关阅读”和“网友评论”被过滤掉了关键信息都被提取出来并且格式统一。这样的数据直接就能导入数据库或者用于进一步分析。5. 处理电商商品数据的技巧新闻数据相对规整电商商品页面就更复杂了。不同平台、不同商家的描述格式千差万别。我总结了一些处理这类数据的经验。5.1 多轮对话提取对于特别复杂的商品描述可以用多轮对话的方式让模型一步步提取信息。def extract_product_details(raw_description): 多轮对话提取商品详情 # 第一轮提取基本信息 prompt1 f 请从以下商品描述中提取基本信息 {raw_description} 请提取 1. 商品名称 2. 品牌 3. 主要类别如电子产品、服装、食品等 # 假设第一轮回复是 basic_info basic_info call_model(prompt1) # 第二轮提取规格参数 prompt2 f 基于之前的分析现在请提取详细规格 商品描述{raw_description} 已提取的基本信息{basic_info} 请提取 1. 颜色/款式选项 2. 尺寸/规格参数 3. 材质/成分信息 4. 特殊功能特点 # 第三轮提取价格库存 prompt3 f 现在请提取商业信息 商品描述{raw_description} 请提取 1. 价格信息当前价格、原价、折扣等 2. 库存状态有货/缺货/预售等 3. 配送信息 4. 促销活动 # 最后整合所有信息 final_prompt f 请将以下信息整合为完整的商品数据结构 基本信息{basic_info} 规格参数{specs_info} 商业信息{commerce_info} 请输出统一的JSON格式。 return call_model(final_prompt)这种方法虽然调用次数多但提取更准确特别适合那些信息分散在不同段落的情况。5.2 处理图片描述文本很多商品页面除了文字描述还有图片的alt文本或者图片描述。这些文本往往包含重要信息但格式很不规范。def process_image_descriptions(img_texts): 处理图片描述文本 prompt f 以下是商品页面的图片描述文本请从中提取有用的商品信息 图片描述列表 {chr(10).join(f- {text} for text in img_texts)} 请提取 1. 商品的不同角度展示信息 2. 商品的实际使用场景 3. 包装或配件信息 4. 尺寸对比或参考信息 注意忽略纯装饰性或重复的描述。 return call_model(prompt)5.3 价格信息规范化价格信息是最重要的但也是最混乱的。不同商家写法各异def normalize_price_info(price_text): 规范化价格信息 prompt f 请从以下价格相关文本中提取规范化信息 文本{price_text} 请识别 1. 当前售价取最低价格 2. 原价如果有 3. 折扣力度如果有 4. 价格单位元/美元等 5. 是否包邮 输出要求 - 价格统一转换为数字如99.99 - 货币单位统一为CNY - 包邮信息转换为布尔值 return call_model(prompt)6. 性能优化与批量处理建议当你需要处理成千上万条数据时性能就很重要了。我总结了一些优化经验。6.1 批量请求策略不要一条一条地请求可以适当批量处理def batch_process_texts(texts, batch_size5): 批量处理文本 results [] for i in range(0, len(texts), batch_size): batch texts[i:ibatch_size] # 构建批量处理的Prompt batch_prompt 请分别处理以下文本\n\n for j, text in enumerate(batch): batch_prompt f文本{j1}\n{text}\n\n batch_prompt 请为每个文本提取关键信息输出格式为JSON列表。 batch_result call_model(batch_prompt) results.extend(parse_batch_result(batch_result)) # 添加延迟避免请求过快 time.sleep(1) return results6.2 缓存与去重很多爬虫数据会有重复内容可以先做一轮去重def deduplicate_texts(texts): 基于内容相似度去重 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity # 计算文本相似度 vectorizer TfidfVectorizer() tfidf_matrix vectorizer.fit_transform(texts) similarity_matrix cosine_similarity(tfidf_matrix) # 找出相似度高的文本 duplicates set() for i in range(len(texts)): for j in range(i1, len(texts)): if similarity_matrix[i][j] 0.8: # 相似度阈值 duplicates.add(j) # 返回去重后的文本 return [texts[i] for i in range(len(texts)) if i not in duplicates]6.3 错误处理与重试网络请求总会有失败的时候要做好错误处理def robust_model_call(prompt, max_retries3): 带重试的模型调用 for attempt in range(max_retries): try: response call_model(prompt) if response and validate_response(response): return response except Exception as e: print(f第{attempt1}次尝试失败: {e}) if attempt max_retries - 1: wait_time 2 ** attempt # 指数退避 time.sleep(wait_time) print(所有重试均失败) return None def validate_response(response): 验证响应是否有效 # 检查响应是否包含必要信息 required_fields [title, summary] # 根据你的需求调整 try: data json.loads(response) for field in required_fields: if field not in data: return False return True except: return False7. 实际应用中的注意事项在实际项目中用了一段时间我总结了一些需要注意的地方。7.1 Prompt设计的经验保持一致性很重要。如果你这次让模型输出“价格”下次让输出“售价”虽然意思差不多但解析起来就麻烦。最好在项目开始时就确定好字段命名规范。给模型一些思考空间。有时候在Prompt里加一句“请仔细分析文本内容”效果会比直接下指令好。模型需要“理解”文本而不是简单地“匹配”关键词。处理不确定性。爬虫数据里经常有缺失信息要在Prompt里明确告诉模型怎么处理“如果找不到XX信息就输出null或空字符串”。这样能保证输出结构的一致性。7.2 模型输出的稳定性通义千问1.5-1.8B-Chat在格式遵循上表现不错但也不是100%稳定。我建议后处理校验对模型输出做一次格式校验比如检查JSON是否能正常解析必要字段是否存在。备用方案对于特别重要的字段可以准备正则表达式作为备用提取方案。人工审核样本定期抽样检查看看模型有没有什么奇怪的输出模式。7.3 成本与效率平衡这个模型本地部署其实没有API调用成本主要成本是电费和硬件折旧。但处理大量数据时时间成本也要考虑。我的经验是对于实时性要求不高的后台任务可以慢慢处理对于需要快速响应的场景可以考虑先用规则过滤掉简单情况复杂的再交给模型定期评估效果如果某些类型的文本模型处理不好可以考虑优化爬虫让原始数据更干净8. 总结用通义千问1.5-1.8B-Chat处理爬虫数据给我的感觉是“刚刚好”。它没有大到需要昂贵的GPU也没有小到处理不了复杂任务。对于大多数爬虫数据清洗和摘要生成的需求它都能很好地满足。实际用下来最深的体会是Prompt设计真的需要花心思。同样的模型不同的Prompt设计效果能差好几倍。开始的时候多花点时间设计好的Prompt模板后面批量处理时就轻松多了。另一个感受是这种方案特别适合处理“半结构化”数据——就是那种有点规律但又不太规整的数据。完全规整的数据用正则表达式更快完全无结构的数据需要更大的模型而这种半结构化的文本用这个大小的模型处理性价比最高。如果你也在做爬虫相关的数据清洗工作真的建议试试这个方案。从配置环境到跑通第一个例子一两个小时就够了。一旦流程跑通后面就是批量处理的事情能省下大量的手工整理时间。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。