通义千问1.5-1.8B-Chat-GPTQ-Int4 Python爬虫数据清洗实战:智能文本处理
通义千问1.5-1.8B-Chat-GPTQ-Int4 Python爬虫数据清洗实战:智能文本处理
你是不是也遇到过这种情况?辛辛苦苦用Python爬虫抓回来一堆网页数据,结果发现全是“毛坯房”——各种HTML标签、广告语、无关的导航信息、重复内容,还有一堆乱码和格式不统一的文本。想要从这些原始数据里提炼出有价值的信息,手动处理简直是一场噩梦,效率低不说,还容易出错。
最近我在处理一批电商评论数据时就遇到了这个难题。几千条评论里混杂着表情符号、网络用语、错别字,还有大量无意义的“好评”、“快递很快”之类的短评。传统的关键词匹配和正则表达式规则越写越复杂,效果却越来越差。
后来我尝试用大模型来做这件事,效果出奇的好。特别是像通义千问1.5-1.8B-Chat-GPTQ-Int4这样经过量化、对硬件要求不高的模型,在本地就能快速部署,专门处理这类文本清洗和结构化任务再合适不过了。今天我就来分享一下,如何用这个模型把爬虫抓回来的“毛坯数据”变成可以直接分析的“精装修”结构化信息。
1. 为什么需要大模型来做数据清洗?
传统的数据清洗方法,比如正则表达式、基于规则的关键词过滤,在处理简单、格式固定的文本时还行得通。但现实中的爬虫数据往往复杂得多。
举个例子,你爬取新闻网站,一篇文章里可能包含记者署名、发布时间、正文、图片说明、相关推荐链接、广告语等等。用规则去剥离这些非正文内容,你需要为每个网站写一套复杂的解析规则,一旦网站改版,规则就失效了。
再比如,从社交媒体或论坛爬取的评论,语言风格千差万别,有缩写、有谐音、有表情符号替代的文字。你想提取评论中的产品名称或情感倾向,规则很难覆盖所有情况。
通义千问这类大模型的核心优势在于它的“理解”能力。它不需要你明确告诉它“标题通常在<h1>标签里”或者“好评通常包含‘不错’、‘很好’这些词”。它通过阅读大量文本,已经学会了人类语言的常见模式和结构。你只需要用自然语言告诉它你想做什么,比如“请提取这段文本中的核心事件描述”,它就能给出相对准确的结果。
对于爬虫开发者来说,这意味着清洗规则的泛化能力大大增强。一套提示词(Prompt)往往能处理多个来源、多种格式的文本,显著降低了开发和维护成本。
2. 环境准备与模型快速部署
首先,我们需要把模型跑起来。通义千问1.5-1.8B-Chat-GPTQ-Int4这个版本是经过GPTQ量化到4位精度的,对显存要求很低,通常6GB甚至更小的显存就能流畅运行,用CPU跑虽然慢点,但也完全可行。
这里我推荐使用transformers库和auto-gptq库来加载和运行模型,这是目前比较方便的方式。
# 安装必要的库 pip install transformers torch auto-gptq如果你的网络环境访问Hugging Face比较慢,可以提前从镜像站下载好模型文件。模型名称通常是Qwen/Qwen1.5-1.8B-Chat-GPTQ-Int4。下载后,加载模型和分词器的代码非常简单:
from transformers import AutoModelForCausalLM, AutoTokenizer # 指定模型本地路径或Hugging Face模型ID model_name_or_path = "./models/Qwen1.5-1.8B-Chat-GPTQ-Int4" # 或者 "Qwen/Qwen1.5-1.8B-Chat-GPTQ-Int4" # 加载分词器和模型 tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) model = AutoModelForCausalLM.from_pretrained( model_name_or_path, device_map="auto", # 自动分配设备(GPU/CPU) trust_remote_code=True # 信任来自作者的远程代码 )为了让模型输出更稳定、更符合我们的指令,通常需要设置一些生成参数。下面这个函数封装了调用过程:
def ask_qwen(prompt, max_new_tokens=512): """向通义千问模型提问并获取回复""" # 构建模型所需的对话格式 messages = [ {"role": "system", "content": "你是一个专业的数据处理助手,擅长清洗、分析和结构化文本信息。"}, {"role": "user", "content": prompt} ] # 将对话格式转换为模型输入的文本 text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) # 对输入文本进行分词,并转换为PyTorch张量,移动到模型所在的设备 model_inputs = tokenizer([text], return_tensors="pt").to(model.device) # 设置生成参数 generated_ids = model.generate( **model_inputs, max_new_tokens=max_new_tokens, do_sample=True, # 启用采样,使输出更多样 temperature=0.2, # 较低的温度使输出更集中、确定 top_p=0.9, # 核采样,保留概率质量前90%的词汇 repetition_penalty=1.1 # 重复惩罚,避免重复输出 ) # 解码生成的token,跳过输入部分 generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] # 将token转换回文本 response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] return response.strip()现在,你可以用一个简单的问题测试一下模型是否正常工作:
test_response = ask_qwen("你好,请介绍一下你自己。") print(test_response)如果看到模型返回了一段自我介绍,恭喜你,环境已经搭建成功。接下来,我们就进入实战环节,看看怎么用它来解决爬虫数据清洗的具体问题。
3. 实战:从杂乱网页文本到规整信息
假设我们爬取了一篇科技新闻的页面,原始HTML经过简单的BeautifulSoup处理后,得到了下面这样一段混杂的文本:
【首页 > 科技频道 > 人工智能】 发布时间:2023-10-27 15:30:22 来源:XX新闻网 AI芯片竞争白热化:新型架构突破算力瓶颈 记者:张伟 [点击查看高清大图] 随着大模型参数规模不断扩大,传统GPU在能效上面临挑战。近日,某初创公司发布了其首款存算一体AI芯片“灵犀X1”,宣称在特定AI工作负载下,能效比可达主流产品的5倍以上。专家认为,这标志着AI芯片设计进入新阶段。 相关阅读:GPU价格走势分析 | 十大AI芯片公司盘点 【广告】企业级AI服务器,限时特惠中... 评论(132) 收藏 分享我们的目标是提取出标题、发布时间、来源、正文核心内容和记者。用正则表达式来写规则会非常繁琐,而且换个网站格式又变了。我们试试用通义千问。
3.1 设计清洗提示词(Prompt)
和大模型打交道,关键就在于如何清晰地告诉它你的需求。提示词设计得好,效果事半功倍。针对上面的任务,我们可以这样设计提示词:
raw_text = """【首页 > 科技频道 > 人工智能】 发布时间:2023-10-27 15:30:22 来源:XX新闻网 AI芯片竞争白热化:新型架构突破算力瓶颈 记者:张伟 [点击查看高清大图] 随着大模型参数规模不断扩大,传统GPU在能效上面临挑战。近日,某初创公司发布了其首款存算一体AI芯片“灵犀X1”,宣称在特定AI工作负载下,能效比可达主流产品的5倍以上。专家认为,这标志着AI芯片设计进入新阶段。 相关阅读:GPU价格走势分析 | 十大AI芯片公司盘点 【广告】企业级AI服务器,限时特惠中... 评论(132) 收藏 分享""" prompt = f""" 你是一个专业的信息抽取助手。请分析以下爬虫获取的新闻文本,并严格按照JSON格式输出提取出的信息,只输出JSON,不要有其他任何解释。 需要提取的字段包括: 1. `title`: 新闻主标题。 2. `publish_time`: 新闻发布时间,格式化为'YYYY-MM-DD HH:MM:SS'。 3. `source`: 新闻来源。 4. `reporter`: 记者姓名,如果没有则输出空字符串""。 5. `main_content`: 新闻正文的核心内容摘要,请用简洁连贯的一段话概括,不超过100字。 待处理的文本内容:{raw_text}
""" cleaned_result = ask_qwen(prompt, max_new_tokens=300) print("模型返回的清洗结果:") print(cleaned_result)运行这段代码,模型很可能会返回类似下面的JSON字符串:
{ "title": "AI芯片竞争白热化:新型架构突破算力瓶颈", "publish_time": "2023-10-27 15:30:22", "source": "XX新闻网", "reporter": "张伟", "main_content": "近日,某初创公司发布首款存算一体AI芯片“灵犀X1”,在特定AI工作负载下能效比可达主流产品5倍以上。专家认为,这标志着AI芯片设计进入新阶段,以应对大模型发展对算力能效的挑战。" }看,原本杂乱无章的文本,瞬间变成了结构清晰的字典对象。你可以直接用json.loads()把它解析成Python字典,存入数据库或进行下一步分析。这个提示词模板稍加修改(比如调整需要提取的字段),就可以复用到很多类似的新闻、博客、公告类网页的清洗任务中。
3.2 处理非结构化评论与UGC内容
新闻文本相对规整,而用户生成内容(UGC)如商品评论、论坛帖子,才是真正的挑战。我们来看一个电商评论的例子:
raw_comment = “手机收到了,物流超快!给快递小哥点赞👍。外观颜值很高,和我预想的差不多。就是电池感觉有点不够用啊,玩两局游戏就掉电30%。系统流畅度还行吧,这个价位还要啥自行车。对了,拍照效果挺惊艳的,夜景模式给力!总体好评,推荐购买。”我们想提取的信息包括:情感倾向(正面/负面/中性)、提到的产品维度(如电池、拍照、物流等)、以及对应的具体评价。
prompt_for_comment = f""" 请分析以下电商商品评论,并输出一个JSON对象。 JSON对象需要包含以下字段: - `overall_sentiment`: 整体情感倾向,取值为“正面”、“负面”或“中性”。 - `aspects`: 一个列表,包含评论中提到的各个产品维度(如电池、拍照、物流等)及其对应的评价情感和具体描述。列表中的每个元素是一个字典,包含`aspect`(维度名)、`sentiment`(对该维度的情感,“正面”、“负面”或“中性”)、`comment`(相关具体描述文本)。 请确保只输出JSON,不要有任何其他文字。 评论内容:{raw_comment}
""" result_comment = ask_qwen(prompt_for_comment, max_new_tokens=400) print(result_comment)模型可能会返回这样的结构化结果:
{ "overall_sentiment": "正面", "aspects": [ { "aspect": "物流", "sentiment": "正面", "comment": "超快,给快递小哥点赞" }, { "aspect": "外观", "sentiment": "正面", "comment": "颜值很高,和预想差不多" }, { "aspect": "电池", "sentiment": "负面", "comment": "不够用,玩两局游戏掉电30%" }, { "aspect": "系统流畅度", "sentiment": "中性", "comment": "还行,这个价位可以接受" }, { "aspect": "拍照", "sentiment": "正面", "comment": "效果惊艳,夜景模式给力" } ] }这样一来,原本一段主观、非结构化的评论,就被分解成了可以量化分析的数据。你可以轻松地统计哪个产品维度被提及最多,正面评价和负面评价主要集中在哪些方面,为产品改进或市场分析提供直接依据。
4. 构建自动化清洗流水线
单次调用演示了可能性,但爬虫数据往往是批量的。我们需要构建一个稳定、高效的自动化处理流水线。这里有几个关键点需要注意。
4.1 批处理与效率优化
直接循环调用模型,每次都要加载上下文,效率不高。我们可以稍微改造一下函数,支持批量处理,并加入简单的错误处理。
import json from typing import List, Dict, Any def batch_clean_text(text_list: List[str], instruction_prompt: str) -> List[Dict[str, Any]]: """ 批量清洗文本数据。 Args: text_list: 待清洗的原始文本列表。 instruction_prompt: 清洗指令提示词模板,其中用`{{text}}`作为原始文本的占位符。 Returns: 清洗后结构化结果的列表,每个元素是一个字典。 """ cleaned_results = [] for i, raw_text in enumerate(text_list): try: # 构造本次请求的具体提示词 prompt = instruction_prompt.replace("{{text}}", raw_text) response = ask_qwen(prompt, max_new_tokens=512) # 尝试解析返回的JSON # 模型有时会在JSON外包裹markdown代码块或多余文字,这里做简单清理 response = response.strip() if response.startswith("```json"): response = response[7:] if response.endswith("```"): response = response[:-3] response = response.strip() result_dict = json.loads(response) cleaned_results.append(result_dict) print(f"已处理第 {i+1}/{len(text_list)} 条数据") except json.JSONDecodeError as e: print(f"第 {i+1} 条数据解析JSON失败,原始返回:{response[:200]}...") # 可以选择记录失败数据,或返回一个错误标记 cleaned_results.append({"error": "JSON解析失败", "raw_response": response[:500]}) except Exception as e: print(f"处理第 {i+1} 条数据时发生未知错误:{e}") cleaned_results.append({"error": str(e)}) return cleaned_results # 使用示例 news_instruction = """ 你是一个专业的信息抽取助手。请分析以下爬虫获取的新闻文本,并严格按照JSON格式输出提取出的信息,只输出JSON,不要有其他任何解释。 需要提取的字段:`title`(标题), `publish_time`(发布时间,格式化为'YYYY-MM-DD HH:MM:SS'), `source`(来源), `reporter`(记者), `main_content`(核心内容摘要,100字内)。 待处理的文本内容:{{text}}
""" # 假设raw_texts是你的爬虫数据列表 # cleaned_data = batch_clean_text(raw_texts, news_instruction)4.2 处理长文本与上下文限制
通义千问1.5-1.8B-Chat模型有上下文长度限制。如果爬取的文本非常长(比如一篇长篇小说或报告),直接塞进提示词可能会被截断。
解决方法有两种:
- 预处理分割:在调用模型前,先用规则或简单的文本分割算法(如按段落、按句子)将长文本切分成语义相对完整的片段,分别处理后再合并结果。
- 让模型总结摘要:如果目标是获取摘要或核心信息,可以直接要求模型先对长文本进行总结,再对总结后的文本进行信息抽取。提示词可以设计为两步:“第一步,请用200字概括以下文本的核心内容。第二步,从你概括的内容中提取以下信息:...”。
4.3 结果的后处理与校验
模型输出并非100%准确,尤其是处理格式特别混乱或语言特别不规范的文本时。在生产环境中,建议加入后处理校验步骤:
- 格式校验:检查输出的JSON是否包含所有必需的字段,字段类型是否正确(如时间是否为合法格式)。
- 逻辑校验:进行简单的逻辑判断。例如,如果
overall_sentiment是“正面”,但aspects里所有维度的情感都是“负面”,这可能就是一个需要复核的异常结果。 - 人工抽样审核:定期对批量处理的结果进行人工抽样检查,评估准确率,并据此考虑是否需要优化提示词。
5. 更多应用场景与提示词灵感
除了上面提到的新闻和评论清洗,这个思路可以拓展到很多场景。关键在于设计出针对性的提示词。
招聘信息结构化:从招聘网站爬取的描述中,提取职位名称、公司、薪资范围、工作地点、职责要求、任职资格等。
- 提示词要点:明确列出需要提取的字段,并说明某些字段可能是多值的(如“职责要求”可能是一个列表)。
学术论文摘要与关键词抽取:从爬取的论文PDF文本或网页中,提取标题、作者、摘要、关键词、发表年份等。
- 提示词要点:要求模型区分“作者列表”和“通讯作者”,并规范关键词的格式(如要求用分号隔开)。
社交媒体舆情监控:从微博、贴吧等平台爬取的帖子中,识别讨论的主题、核心观点、情感倾向以及提到的关键实体(如品牌名、产品名、人名)。
- 提示词要点:要求模型区分事实陈述和观点表达,并识别出文本中隐含的情感。
格式化规整:将格式不统一的地址、电话号码、日期等数据,清洗成标准格式。
- 提示词要点:给出明确的目标格式示例(如“日期统一为YYYY-MM-DD”),并让模型纠正明显的错别字(如“北京是”->“北京市”)。
6. 总结与建议
实际用下来,通义千问1.5-1.8B-Chat-GPTQ-Int4这个模型在文本清洗和结构化任务上的表现,确实能给爬虫工作流带来质的提升。它最大的好处是把我们从编写和维护无数复杂、脆弱的解析规则中解放了出来,转向更高效、更泛化的提示词设计。
当然,它也不是万能的。对于格式极其复杂、信息密度极低或者需要极高准确率(如金融数据提取)的场景,可能需要更大、更专业的模型,或者采用“大模型初步清洗+规则后校验”的混合模式。本地部署的这个版本,在速度和成本之间取得了很好的平衡,特别适合作为爬虫数据预处理环节的一个强力工具。
如果你正准备尝试,我的建议是:先从一两个最让你头疼的清洗任务开始,设计好提示词,跑通单条数据的处理流程。然后,构建一个简单的批处理和错误处理框架。在这个过程中,你会逐渐摸清模型的“脾气”,知道什么样的指令它执行得最好。最后,再把它集成到你现有的爬虫系统中去,让数据从“毛坯”到“精装”的过程实现自动化。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
