Qwen1.5-1.8B GPTQ项目实战搭建一个简单的Python爬虫数据清洗与摘要系统1. 引言你有没有遇到过这样的场景每天需要从几十个技术博客里手动收集信息复制粘贴、整理格式、提炼要点一套流程下来半天时间就没了。或者你的项目需要分析大量网络文本但面对抓取下来的杂乱无章、充满HTML标签和广告的原始数据光是清洗和摘要就让人头疼。传统的做法是写一堆正则表达式或者用复杂的规则引擎但效果往往不尽如人意稍微换个网站结构整个脚本就得重写。更别提从海量文本里快速提炼核心观点了这基本靠人工效率极低。现在情况不一样了。我们可以把大语言模型的能力直接嵌入到数据处理流程里。这篇文章我就带你动手搭建一个迷你系统用Python爬虫从技术博客抓取文章然后用部署好的Qwen1.5-1.8B GPTQ模型自动完成文本清洗和智能摘要。这个系统的价值在于它把“体力活”和“脑力活”都自动化了。爬虫负责“搬砖”把原始数据拿回来大模型则扮演“分析师”的角色帮你把杂乱的信息整理干净并提炼出核心内容。整个过程你只需要写一次代码就能持续、批量地处理信息。对于内容分析、市场调研、知识库构建这些需要处理大量文本的场景效率的提升是肉眼可见的。2. 项目整体设计思路在开始写代码之前我们先理清整个系统要做什么以及各个部分如何协同工作。这样写起来思路会更清晰。我们的目标是构建一个端到端的自动化信息处理流水线。整个流程可以拆解为四个核心环节它们像一条生产线上的不同工位依次对数据进行加工。第一个环节是数据采集。这由我们的Python爬虫负责。它的任务很明确模拟浏览器访问指定的技术博客页面定位到文章正文所在的HTML区域然后把里面的文本内容“抓取”下来。这里的关键是准确性和稳定性要能应对不同网站的页面结构并且遵守网络礼仪避免给目标网站造成压力。第二个环节是数据清洗。从网页上抓下来的原始文本就像刚从矿场挖出来的原石里面混杂着大量我们不需要的“杂质”比如导航栏文字、广告代码、版权声明、多余的空白和换行符。这个环节的任务就是通过一系列文本处理技术把这些杂质过滤掉得到纯净的、结构化的文章正文。这是为后续的智能处理打好基础。第三个环节是智能处理也是本项目的核心。清洗后的干净文本会被送入我们事先部署好的Qwen1.5-1.8B GPTQ模型。我们会设计好“指令”让模型扮演一个“信息提炼专家”的角色。具体来说我们会让它做两件事一是提取文章的关键信息比如主题、技术栈、核心结论等二是生成一段简洁、连贯的摘要。这一步大模型替代了人工阅读和总结是智能化的体现。第四个环节是结果存储与展示。模型处理完的结果不能只停留在内存里我们需要把它保存下来方便查看和进一步使用。最简单的办法就是存成文本文件或者结构化的JSON文件。这样一个完整的“采集-清洗-分析-存储”闭环就形成了。整个系统的技术栈也很轻量用requests和BeautifulSoup库来写爬虫和解析网页用re正则表达式和基本的字符串方法做文本清洗通过transformers库或类似的方式调用本地部署的Qwen模型最后用Python内置的文件操作把结果存下来。思路清晰了我们接下来就一步步实现它。3. 环境准备与依赖安装工欲善其事必先利其器。我们先来把项目需要的“工具箱”准备好。这个项目对电脑配置要求不高但需要安装几个关键的Python库。首先确保你的电脑上已经安装了Python版本建议在3.8以上。打开你的命令行终端比如Windows的CMD或PowerShellMac/Linux的Terminal我们就可以开始安装依赖了。最核心的几个库我们可以用pip命令一次性安装。你可以新建一个项目文件夹然后在里面执行下面的命令pip install requests beautifulsoup4 transformers torch我来简单解释一下这几个库是干什么用的requests这是Python里最常用的HTTP库我们将用它来向博客网站发送请求获取网页的HTML源代码。简单来说它就是负责“敲门”和“接收包裹”的。beautifulsoup4网页的HTML代码像一棵树结构复杂。这个库能帮我们轻松地解析这棵树并从中提取出我们想要的特定部分比如文章的标题和正文。它是我们的“信息提取器”。transformers和torch这是调用大模型的核心。transformers库由Hugging Face提供它封装了加载和使用各种预训练模型包括Qwen的标准化接口。torchPyTorch则是模型运行所需的深度学习框架。它们是和我们的“AI分析师”——Qwen模型——沟通的桥梁。除了这些我们可能还会用到Python标准库里的re正则表达式和json不过它们不需要额外安装。另外一个非常重要的前提是你需要已经在本机或可访问的服务器上成功部署了Qwen1.5-1.8B的GPTQ量化版本。GPTQ是一种模型量化技术能显著减少模型对显存的需求让像1.8B这样的模型在消费级显卡甚至只有CPU的机器上也能运行。部署好后你会知道模型的本地路径比如./qwen1.5-1.8b-gptq。我们后续的代码就会去这个路径加载模型。环境准备好之后我们就可以动手搭建第一个环节了。4. 第一步编写Python爬虫抓取文章现在我们开始打造流水线的第一个工位——爬虫。它的任务是从目标网站比如CSDN的技术博客上把指定文章的原始内容“拿”下来。我们以CSDN博客为例但思路是通用的。首先我们需要分析目标网页的结构。用浏览器打开一篇CSDN博客文章按下F12打开开发者工具使用元素选择器通常是个箭头图标点击文章正文部分。你会发现正文内容通常包裹在一个带有特定id或class的div标签里比如idarticle_content或classblog-content-box。记下这个选择器这是我们提取内容的关键。接下来我们写代码。新建一个Python文件比如叫做web_crawler.py。import requests from bs4 import BeautifulSoup import time def fetch_article_content(url): 从给定的URL抓取文章正文内容 Args: url (str): 目标文章的网址 Returns: str: 提取到的文章正文文本如果失败则返回空字符串 # 设置请求头模拟浏览器访问避免被简单的反爬机制拦截 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: print(f正在抓取: {url}) # 发送GET请求获取网页内容 response requests.get(url, headersheaders, timeout10) # 检查请求是否成功状态码200表示成功 response.raise_for_status() # 指定网页的编码这里使用UTF-8如果遇到乱码可能需要调整 response.encoding utf-8 # 使用BeautifulSoup解析HTML内容html.parser是Python内置的解析器 soup BeautifulSoup(response.text, html.parser) # 核心步骤根据之前分析的选择器找到文章正文的HTML元素 # 这里以CSDN常见的正文容器id为例你需要根据实际网站调整 content_div soup.find(div, idarticle_content) # 如果没找到尝试其他常见的选择器 if not content_div: content_div soup.find(div, class_blog-content-box) if not content_div: content_div soup.find(article) # 有些网站用article标签 if content_div: # 获取该元素内的所有纯文本并用空格连接 article_text content_div.get_text(separator , stripTrue) print(抓取成功) return article_text else: print(警告未在页面中找到文章正文区域。) return except requests.exceptions.RequestException as e: print(f网络请求出错: {e}) return except Exception as e: print(f解析过程出错: {e}) return # 测试一下这个函数 if __name__ __main__: # 替换成你想抓取的实际文章URL test_url https://blog.csdn.net/example_author/article/details/123456789 raw_content fetch_article_content(test_url) if raw_content: # 打印前500个字符看看效果 print(\n抓取到的内容预览) print(raw_content[:500]) # 也可以保存到文件供后续步骤使用 with open(raw_article.txt, w, encodingutf-8) as f: f.write(raw_content) print(\n原始内容已保存到 raw_article.txt) else: print(抓取失败请检查URL或网络。) # 礼貌性延时避免短时间内请求过于频繁 time.sleep(2)这段代码定义了一个fetch_article_content函数。它做了几件事模拟浏览器访问、获取网页、用BeautifulSoup解析HTML、根据我们预设的规则找到正文区域最后提取出纯文本。代码里加了异常处理和友好的提示信息还遵守了基本的爬虫礼仪设置请求头、访问后延时。运行这个脚本如果一切顺利你就会得到一个包含了目标文章所有文本内容的raw_article.txt文件。不过这个文件里的内容还很“粗糙”充满了我们不需要的东西这就是下一个环节要解决的问题。5. 第二步数据清洗与预处理从爬虫那里拿到手的文本我们称之为“原始数据”。它就像刚从地里挖出来的土豆沾满了泥土无关信息。直接交给模型处理效果会大打折扣因为模型会被这些“噪音”干扰。所以数据清洗这一步至关重要目的是把“土豆”洗干净。原始文本里常见的问题有哪些呢我列举几个典型的冗余空白和换行HTML渲染会产生大量多余的空格、制表符和换行让文本看起来松散杂乱。无关的广告和推荐文字比如“关注博主查看更多精彩内容”、“相关推荐”等。代码块和特殊字符技术博客里常有代码虽然有时是重要信息但夹杂在正文中可能影响摘要的连贯性。此外还有HTML实体字符如nbsp;。版权声明和固定模板文字每篇文章开头结尾可能都有固定的作者信息、版权声明等。我们的清洗策略是“分步过滤逐步精炼”。下面是一个清洗函数的示例你可以根据实际抓取到的文本特点进行调整。import re def clean_article_text(raw_text): 清洗爬取到的原始文章文本 Args: raw_text (str): 原始的、未处理的文章文本 Returns: str: 清洗后的干净文本 if not raw_text: return cleaned_text raw_text # 1. 移除多余的空白字符多个空格、制表符、换行符合并为单个空格或换行 # 将所有的换行符、制表符等先统一转换为空格 cleaned_text re.sub(r\s, , cleaned_text) # 这一步之后文本变成了一大段但去除了杂乱格式 # 2. 移除常见的、固定的无关短语这部分需要根据目标网站定制 noise_patterns [ r关注博主.*?查看更多精彩内容, r相关推荐, r本文由.*?发布, r版权声明.*, r转载请注明出处, r#\s*在这里插入图片描述\s*#, # 移除Markdown图片占位符 # 可以在这里添加更多你观察到的噪音模式 ] for pattern in noise_patterns: cleaned_text re.sub(pattern, , cleaned_text, flagsre.IGNORECASE) # 3. 处理代码块可选策略保留或移除 # 策略A完全移除代码块如果代码不是摘要重点 # cleaned_text re.sub(r[\s\S]*?, [代码块], cleaned_text) # 标记 # cleaned_text re.sub(r.*?, , cleaned_text) # 移除行内代码 # 策略B保留代码块但简化对于技术摘要代码有时是关键 # 这里我们选择简单移除反引号标记保留代码内容因为后续模型能理解 cleaned_text re.sub(r, , cleaned_text) # 4. 再次清理因移除内容可能产生的多余空格和空行 cleaned_text re.sub(r\s, , cleaned_text).strip() # 5. 简单分段在句号、问号、感叹号后分割形成粗略的段落 # 这能让文本结构更清晰但不是必须步骤 sentences re.split(r(?[。]), cleaned_text) cleaned_text \n.join([s.strip() for s in sentences if s.strip()]) return cleaned_text # 测试清洗函数 if __name__ __main__: # 读取上一步保存的原始文件 with open(raw_article.txt, r, encodingutf-8) as f: dirty_text f.read() clean_text clean_article_text(dirty_text) print(清洗后的文本预览) print(clean_text[:800]) # 打印前800字符查看效果 with open(cleaned_article.txt, w, encodingutf-8) as f: f.write(clean_text) print(\n清洗后的内容已保存到 cleaned_article.txt)这个clean_article_text函数就是一个简单的文本处理流水线。它主要依靠正则表达式来匹配和替换不需要的模式。清洗的粒度可以根据需求调整比如对于技术文章代码块可能很重要我们可以选择保留而不是移除。经过这一步我们得到了一个相对干净、结构清晰的文本文件cleaned_article.txt。现在这块“洗净的土豆”可以交给我们的“AI大厨”——Qwen模型去烹饪成一道美味的“信息摘要”了。6. 第三步调用Qwen模型进行智能摘要这是整个项目最核心、也最体现价值的一步。我们将把清洗好的文本交给本地部署的Qwen1.5-1.8B GPTQ模型让它理解内容并按要求输出关键信息和摘要。调用本地大模型我们使用transformers库。首先确保你的模型路径是正确的。然后我们需要精心设计一个“提示词”Prompt来告诉模型我们想要它做什么。一个好的提示词能极大地提升模型输出的质量。我们的任务有两个提取关键信息和生成摘要。我们可以设计一个综合的提示词让模型一次完成这两项工作。from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import torch def load_qwen_model(model_path): 加载本地部署的Qwen GPTQ模型和分词器 Args: model_path (str): 模型在本地的路径 Returns: tuple: (tokenizer, model) 或 text-generation pipeline print(f正在从 {model_path} 加载模型和分词器...) try: # 加载分词器 tokenizer AutoTokenizer.from_pretrained(model_path, trust_remote_codeTrue) # 加载模型。device_mapauto让Transformers自动分配模型层到可用的设备GPU/CPU model AutoModelForCausalLM.from_pretrained( model_path, device_mapauto, torch_dtypetorch.float16, # 使用半精度浮点数节省显存 trust_remote_codeTrue ) print(模型加载成功) # 创建一个文本生成的pipeline方便调用 text_generator pipeline( text-generation, modelmodel, tokenizertokenizer, max_new_tokens512, # 生成文本的最大长度 do_sampleTrue, # 启用采样使输出更多样 temperature0.7, # 采样温度控制随机性。0.7是一个常用值 top_p0.9, # 核采样参数控制生成文本的多样性 ) return text_generator except Exception as e: print(f加载模型失败: {e}) return None def generate_summary_with_qwen(pipeline, clean_text): 使用加载的Qwen模型生成文章摘要和关键信息 Args: pipeline: 加载好的text-generation pipeline clean_text (str): 清洗后的文章正文 Returns: str: 模型生成的包含摘要和关键信息的文本 # 构造提示词Prompt。这是引导模型生成内容的关键。 # 我们明确告诉模型它的角色、任务、输入和输出格式。 prompt f你是一个专业的技术文章分析助手。请根据用户提供的文章内容完成以下两个任务 任务一提取关键信息。 请以简洁的条目形式列出文章的核心要点例如 - 主要主题 - 涉及的技术或工具 - 解决的核心问题 - 主要结论或建议 任务二生成内容摘要。 请用一段连贯、简洁的文字不超过200字概括文章的主要内容。 以下是需要分析的文章内容 {clean_text} 请开始你的分析 print(正在调用模型生成摘要...) try: # 调用模型生成文本 result pipeline(prompt) generated_text result[0][generated_text] # 生成的文本包含了我们的提示词和模型的新内容我们只取模型新生成的部分 # 简单的方法找到提示词末尾然后截取后面的内容 summary generated_text[len(prompt):].strip() return summary except Exception as e: print(f模型生成过程中出错: {e}) return # 主流程串联前几步 if __name__ __main__: # 1. 指定你的Qwen GPTQ模型本地路径 MODEL_PATH ./qwen1.5-1.8b-gptq # 请修改为你的实际路径 # 2. 加载模型 (这一步比较耗时且消耗显存/内存) qwen_pipeline load_qwen_model(MODEL_PATH) if qwen_pipeline is None: print(无法加载模型程序退出。) exit() # 3. 读取清洗后的文章 with open(cleaned_article.txt, r, encodingutf-8) as f: article_content f.read() # 4. 如果文章太长可能需要截断因为模型有上下文长度限制 # Qwen1.5-1.8B的上下文长度通常是2K或4K tokens。这里简单按字符截断更严谨的做法应按tokens截断。 max_input_length 1500 # 预留空间给提示词和生成内容 if len(article_content) max_input_length: print(f文章较长进行截断处理...) article_content article_content[:max_input_length] ... # 5. 调用模型生成摘要 analysis_result generate_summary_with_qwen(qwen_pipeline, article_content) if analysis_result: print(\n *50) print(模型分析结果) print(*50) print(analysis_result) print(*50) # 6. 保存结果 with open(article_analysis.txt, w, encodingutf-8) as f: f.write(analysis_result) print(分析结果已保存到 article_analysis.txt) else: print(摘要生成失败。)这段代码的核心是generate_summary_with_qwen函数。我们通过精心设计的prompt来引导模型。Prompt中明确了模型的身份技术文章分析助手、具体任务提取关键信息、生成摘要、输入格式和期望的输出格式。这种结构化的指令能帮助模型更好地理解我们的意图。加载模型时我们使用了pipelineAPI它封装了生成文本的复杂步骤。参数如max_new_tokens控制生成长度temperature控制创造性值越高越随机值越低越确定。对于摘要任务temperature设为0.3-0.7之间通常能取得不错的效果。运行这段代码稍等片刻时间取决于你的硬件你就能在控制台看到模型输出的分析结果并保存到article_analysis.txt文件中。结果可能会是这样的结构任务一提取关键信息。 - 主要主题使用Python的FastAPI框架构建RESTful API。 - 涉及的技术或工具Python, FastAPI, Pydantic, SQLAlchemy。 - 解决的核心问题如何快速搭建一个高性能、易于维护的Web API后端。 - 主要结论或建议FastAPI凭借其自动文档生成、类型提示和异步支持是构建现代API的优秀选择。 任务二生成内容摘要。 本文介绍了使用FastAPI框架构建RESTful API的快速入门指南。文章首先阐述了FastAPI的优势如高性能和自动交互式文档。接着通过一个简单的示例演示了如何定义路径操作函数、使用Pydantic模型进行数据验证以及如何运行开发服务器。最后总结了FastAPI适合用于快速开发对性能要求较高的API项目。7. 第四步整合与自动化运行前面三步我们分别实现了爬取、清洗和摘要生成。现在是时候把它们串联起来形成一个可以一键运行的自动化脚本了。同时我们也会考虑一些工程化的改进比如错误处理、结果存储格式和简单的进度提示。我们将创建一个主函数main()把前面的功能模块像拼积木一样组合起来。为了让结果更规整我们不再简单地把所有输出堆在一个文本文件里而是使用JSON格式来存储这样结构更清晰也方便后续如果有其他程序要读取这些结果。import json from datetime import datetime import os def main(target_url, model_path): 主函数执行完整的爬取、清洗、摘要流程 Args: target_url (str): 要处理的技术博客文章URL model_path (str): Qwen GPTQ模型的本地路径 print(*60) print(开始自动化文章处理流程) print(*60) results { url: target_url, timestamp: datetime.now().isoformat(), status: success, error_message: None, raw_content: , cleaned_content: , analysis: } # 步骤1: 爬取文章 print(\n[步骤1/3] 爬取文章内容...) raw_content fetch_article_content(target_url) if not raw_content: results[status] failed results[error_message] 文章抓取失败 save_results(results) return results[raw_content] raw_content[:500] ... if len(raw_content) 500 else raw_content # 只存预览 # 步骤2: 清洗文本 print([步骤2/3] 清洗文本数据...) cleaned_content clean_article_text(raw_content) if not cleaned_content: results[status] failed results[error_message] 文本清洗后为空 save_results(results) return results[cleaned_content] cleaned_content[:500] ... if len(cleaned_content) 500 else cleaned_content # 步骤3: 加载模型并生成摘要 (这一步最耗时) print([步骤3/3] 加载AI模型并生成摘要...) # 注意在实际自动化中如果处理多篇文章模型应该只加载一次这里为演示清晰每次加载。 qwen_pipeline load_qwen_model(model_path) if qwen_pipeline is None: results[status] failed results[error_message] 模型加载失败 save_results(results) return # 处理长文本简单截断 max_len 1500 model_input cleaned_content[:max_len] ... if len(cleaned_content) max_len else cleaned_content analysis_result generate_summary_with_qwen(qwen_pipeline, model_input) if not analysis_result: results[status] partial results[error_message] 摘要生成失败 else: results[analysis] analysis_result # 保存最终结果 save_results(results) print(\n流程结束) def save_results(data): 将处理结果保存为JSON文件 filename farticle_result_{datetime.now().strftime(%Y%m%d_%H%M%S)}.json with open(filename, w, encodingutf-8) as f: # ensure_asciiFalse 确保中文正常显示indent2 让JSON文件有缩进更易读 json.dump(data, f, ensure_asciiFalse, indent2) print(f结果已保存至文件: {filename}) # 同时也把摘要单独保存为一个txt文件方便快速查看 if data.get(analysis): summary_filename filename.replace(.json, _summary.txt) with open(summary_filename, w, encodingutf-8) as f: f.write(data[analysis]) print(f摘要已单独保存至: {summary_filename}) # 程序入口 if __name__ __main__: # 在这里配置你要处理的文章URL和模型路径 TARGET_URL https://blog.csdn.net/example_author/article/details/123456789 # 请替换为真实URL LOCAL_MODEL_PATH ./qwen1.5-1.8b-gptq # 请替换为你的模型实际路径 # 检查模型路径是否存在可选 if not os.path.exists(LOCAL_MODEL_PATH): print(f错误在路径 {LOCAL_MODEL_PATH} 未找到模型。) print(请确认模型已正确下载并解压到该目录。) else: # 运行主流程 main(TARGET_URL, LOCAL_MODEL_PATH)这个main函数就是我们的总指挥。它按顺序调用之前写好的三个功能函数并用一个results字典记录每一步的结果和状态。我们增加了基本的错误处理比如抓取失败或清洗后内容为空时流程会提前终止并记录错误。保存结果时我们使用了JSON格式因为它结构清晰包含了时间戳、状态、原始内容预览、清洗后内容预览和最终的AI分析结果。同时我们也把摘要单独存为一个txt文件方便直接打开阅读。现在你只需要修改脚本开头的TARGET_URL和LOCAL_MODEL_PATH两个变量然后运行这个脚本它就会自动完成从抓取到生成摘要的全过程并在当前目录下生成带有时间戳的结果文件。8. 总结与展望走完这一整套流程你应该能切身感受到将大语言模型接入传统的数据处理流水线能带来多么显著的效率提升和智能化改变。我们不再需要手动从杂乱的信息中大海捞针而是构建了一个不知疲倦的“信息助理”它能在几分钟内完成阅读、理解和总结的工作。回顾这个项目它的核心价值在于提供了一个清晰的范式用爬虫解决“数据从哪里来”的问题用大模型解决“数据如何理解”的问题。这个范式可以轻松地迁移到无数类似的场景中。比如你可以修改爬虫规则去抓取新闻网站、产品评论、论坛帖子然后让模型做情感分析、观点提炼或事件追踪。只需要更换目标网址和调整给模型的指令Prompt这个系统的应用面就能极大地扩展。当然这只是一个起点。在实际生产中这个迷你系统还有很多可以优化和加强的地方。例如我们可以引入更健壮的爬虫框架如Scrapy来处理复杂的网站结构和反爬机制可以设计更精细的文本清洗管道甚至用一些小模型来辅助识别和过滤广告对于模型调用可以考虑使用异步处理来批量摘要多篇文章或者将模型服务化通过FastAPI等框架提供HTTP接口让其他系统也能方便地调用。最有趣的部分可能在于Prompt工程。如何设计提示词让模型提取的信息更结构化比如直接输出JSON或者完成更复杂的任务比如对比多篇文章的观点这里面有巨大的探索空间。Qwen1.5-1.8B这个尺寸的模型在消费级硬件上运行流畅响应速度也很快非常适合作为这类自动化任务的“大脑”。希望这个实战项目能给你带来启发。技术的魅力就在于用一些不算复杂的工具和代码就能搭建出真正有用的东西解决实际的问题。不妨动手试试用这个框架去处理你感兴趣领域的信息看看AI能帮你发现哪些意想不到的洞察。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。