Wan2.1-umt5实战Python爬虫数据清洗与智能摘要生成你是不是也遇到过这种情况用Python爬虫好不容易抓回来一堆新闻、评论或者论坛帖子结果发现数据乱七八糟的——有大量的广告、重复内容、无意义的符号还有各种格式错乱。想从这些“数据垃圾”里提炼出有价值的信息简直比大海捞针还难。我之前做项目就吃过这个亏花了一整天写爬虫结果花了三天时间手动清洗数据。后来我发现其实这个过程完全可以自动化而且还能让数据“开口说话”直接告诉你每篇文章在讲什么。这就是我今天要跟你分享的用Wan2.1-umt5模型搭建一个从爬虫数据到智能摘要的完整流水线。这个方案的核心思路很简单先用爬虫把原始文本抓回来然后用一套方法把脏数据洗干净最后让AI模型自动提炼出核心内容生成简洁的摘要。整个过程跑下来不仅效率提升了几十倍而且得到的数据质量也高得多可以直接用于分析或者给其他系统使用。1. 为什么需要智能化的数据清洗与摘要我们先聊聊痛点。传统的数据处理方式要么是写一堆复杂的正则表达式和规则要么就是靠人工一条条看。这两种方法问题都很明显规则清洗太死板稍微变个格式就失效了维护成本高人工处理呢速度慢、容易出错而且面对海量数据根本不现实。更重要的是这些方法只能做到“表面干净”——去掉一些明显的噪音但没法理解内容更别说提炼核心信息了。举个例子你爬了一千篇科技新闻想快速了解这个领域最近都在讨论什么。如果靠人工得一个人看上好几天用传统方法可能只能统计一下关键词频率但具体每篇文章讲了什么观点、有什么新发现你还是不知道。这时候Wan2.1-umt5这类模型的价值就体现出来了。它不仅能帮你把数据整理干净还能“读懂”内容自动生成摘要。相当于你请了一个不知疲倦的助手既能干脏活累活还能帮你做初步的分析。2. 搭建你的数据处理流水线整个流程可以分成三个核心阶段我把它叫做“采集-清洗-理解”流水线。下面我们一步步来看每个阶段具体做什么以及怎么用代码实现。2.1 第一阶段数据采集与初步处理首先你得把数据抓回来。这里我用一个简单的新闻爬虫做演示实际项目中你可以替换成任何你需要的源。import requests from bs4 import BeautifulSoup import pandas as pd import time def crawl_news(url, max_pages5): 简单的新闻爬虫示例 articles [] for page in range(1, max_pages 1): try: # 注意实际使用时请遵守网站的robots.txt并添加适当的请求头 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } # 这里只是示例实际URL需要根据目标网站调整 response requests.get(f{url}?page{page}, headersheaders, timeout10) response.raise_for_status() soup BeautifulSoup(response.content, html.parser) # 假设新闻在特定的class中需要根据实际网站调整 news_items soup.find_all(div, class_news-item) for item in news_items: title item.find(h2).text.strip() if item.find(h2) else content item.find(div, class_content).text.strip() if item.find(div, class_content) else date item.find(span, class_date).text.strip() if item.find(span, class_date) else if title and content: # 只保存有标题和内容的数据 articles.append({ title: title, content: content, date: date, source_url: url, crawl_time: time.strftime(%Y-%m-%d %H:%M:%S) }) print(f已爬取第 {page} 页累计 {len(articles)} 篇文章) time.sleep(2) # 礼貌性延迟避免给服务器太大压力 except Exception as e: print(f爬取第 {page} 页时出错: {e}) continue return pd.DataFrame(articles) # 使用示例 # df_raw crawl_news(https://example-news-site.com/news)爬虫写好了但抓回来的数据往往很“脏”。常见的问题包括HTML标签没去干净、有一大堆空格和换行、夹杂着广告文本、还有各种乱码。所以我们需要先做个初步的清理。2.2 第二阶段深度数据清洗初步清理之后数据看起来整齐了一些但还不够。我们还需要处理一些更复杂的问题比如重复内容、无关信息、以及格式标准化。下面这个清洗函数会处理大多数常见问题import re import hashlib from datetime import datetime def deep_clean_text(text): 深度清洗文本数据 if not isinstance(text, str) or not text.strip(): return # 1. 移除多余的空白字符包括全角空格 text re.sub(r\s, , text) # 多个空白字符替换为单个空格 text re.sub(r , , text) # 全角空格处理 text text.strip() # 2. 处理常见的乱码和特殊字符保留中文、英文、数字和基本标点 # 这个正则表达式保留了中文、英文、数字、空格和常见标点 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9\s。、()【】《》.,!?;:\-—–*/#%], , text) # 3. 标准化标点符号中文标点统一 punctuation_map { ,: , .: 。, !: , ?: , ;: , :: , (: , ): , [: 【, ]: 】, : 《, : 》 } # 只在中文语境中替换标点 def replace_punctuation(match): char match.group() # 如果前后有中文字符则替换为中文标点 if any(\u4e00 c \u9fff for c in match.string[max(0, match.start()-1):min(len(match.string), match.end()1)]): return punctuation_map.get(char, char) return char for eng, chi in punctuation_map.items(): text re.sub(re.escape(eng), replace_punctuation, text) # 4. 移除常见的广告和无关文本模式 ad_patterns [ r关注[你我]的[微公]信[号众]\S, r扫码[添加关注]\S*, r点击[这里链接]\S*[下载查看]\S*, r欢迎[访问浏览]\S[网站网址]\S*, r广告[合作联系]\S*, r【广告】.*?【/广告】, r广告.*?/广告, ] for pattern in ad_patterns: text re.sub(pattern, , text, flagsre.IGNORECASE) # 5. 处理过长无意义字符串如连续重复字符 text re.sub(r(.)\1{10,}, , text) # 移除连续重复10次以上的字符 return text def deduplicate_dataframe(df, content_colcontent, similarity_threshold0.9): 基于内容相似度去重 from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import numpy as np if len(df) 1: return df # 计算文本的TF-IDF向量 vectorizer TfidfVectorizer(min_df1, max_df0.8, stop_wordsNone) tfidf_matrix vectorizer.fit_transform(df[content_col].fillna()) # 计算相似度矩阵 similarity_matrix cosine_similarity(tfidf_matrix) # 找出相似度高的重复项 duplicates_to_drop set() for i in range(len(similarity_matrix)): if i in duplicates_to_drop: continue # 找出与当前文档相似度超过阈值的其他文档 similar_indices np.where(similarity_matrix[i] similarity_threshold)[0] similar_indices similar_indices[similar_indices i] # 只保留索引大于i的避免重复标记 for j in similar_indices: duplicates_to_drop.add(j) # 保留非重复的数据 keep_indices [i for i in range(len(df)) if i not in duplicates_to_drop] df_clean df.iloc[keep_indices].reset_index(dropTrue) print(f去重前: {len(df)} 条去重后: {len(df_clean)} 条移除 {len(df) - len(df_clean)} 条重复数据) return df_clean # 应用清洗函数 def apply_cleaning_pipeline(df): 应用完整的清洗流水线 print(开始数据清洗...) # 1. 基础清洗 df[content_clean] df[content].apply(deep_clean_text) # 2. 过滤掉清洗后内容过短的文章可能是无效内容 df df[df[content_clean].str.len() 100].copy() # 3. 去重 df deduplicate_dataframe(df, content_colcontent_clean) # 4. 添加内容长度和质量评分 df[content_length] df[content_clean].str.len() df[word_count] df[content_clean].apply(lambda x: len(x.split())) # 简单的质量评分基于长度和文本多样性 df[quality_score] df.apply( lambda row: min(100, row[word_count] / 10 len(set(row[content_clean])) / len(row[content_clean]) * 50), axis1 ) print(f清洗完成。剩余 {len(df)} 条高质量数据) print(f平均内容长度: {df[content_length].mean():.0f} 字符) print(f平均质量评分: {df[quality_score].mean():.2f}) return df这个清洗流程做了几件重要的事首先是把乱七八糟的格式整理干净然后去掉广告和无关内容接着用相似度计算找出重复的文章去掉最后还给每篇文章打了个质量分。这样处理之后数据就干净多了为下一步的摘要生成做好了准备。3. 用Wan2.1-umt5生成智能摘要数据洗干净了现在轮到重头戏——让AI帮我们读文章、写摘要。Wan2.1-umt5是一个在文本理解、生成和翻译方面表现不错的模型特别适合做摘要这种需要理解原文然后重新表达的任务。3.1 模型部署与基础使用首先我们需要把模型跑起来。这里假设你已经有了模型文件或者知道怎么获取。import torch from transformers import AutoTokenizer, AutoModelForSeq2SeqLM class TextSummarizer: def __init__(self, model_pathWan2.1-umt5, deviceNone): 初始化摘要生成器 print(f正在加载模型: {model_path}) # 自动选择设备GPU优先 if device is None: self.device torch.device(cuda if torch.cuda.is_available() else cpu) else: self.device device # 加载tokenizer和模型 self.tokenizer AutoTokenizer.from_pretrained(model_path) self.model AutoModelForSeq2SeqLM.from_pretrained(model_path).to(self.device) print(f模型加载完成使用设备: {self.device}) # 模型参数设置可以根据需要调整 self.default_params { max_length: 512, # 生成摘要的最大长度 min_length: 30, # 生成摘要的最小长度 length_penalty: 2.0, # 长度惩罚系数1鼓励长摘要1鼓励短摘要 num_beams: 4, # beam search的beam数量 early_stopping: True, no_repeat_ngram_size: 3, # 避免重复的n-gram temperature: 0.7, # 温度参数控制随机性 } def summarize(self, text, **kwargs): 生成文本摘要 if not text or len(text.strip()) 50: return 文本过短无法生成有意义的摘要 # 合并默认参数和用户传入的参数 params {**self.default_params, **kwargs} try: # 对输入文本进行编码 inputs self.tokenizer.encode( summarize: text, # 添加任务前缀 return_tensorspt, max_length1024, # 模型最大输入长度 truncationTrue ).to(self.device) # 生成摘要 with torch.no_grad(): summary_ids self.model.generate( inputs, **params ) # 解码生成的结果 summary self.tokenizer.decode(summary_ids[0], skip_special_tokensTrue) return summary except Exception as e: print(f生成摘要时出错: {e}) return None def batch_summarize(self, texts, batch_size4, **kwargs): 批量生成摘要 summaries [] for i in range(0, len(texts), batch_size): batch texts[i:ibatch_size] print(f处理批次 {i//batch_size 1}/{(len(texts)-1)//batch_size 1}) batch_summaries [] for text in batch: summary self.summarize(text, **kwargs) batch_summaries.append(summary) summaries.extend(batch_summaries) return summaries # 使用示例 def setup_summarizer(): 设置摘要生成器 try: summarizer TextSummarizer() return summarizer except Exception as e: print(f模型初始化失败: {e}) print(请确保模型文件路径正确或者尝试从Hugging Face下载:) print(from transformers import AutoTokenizer, AutoModelForSeq2SeqLM) print(tokenizer AutoTokenizer.from_pretrained(Wan2.1-umt5)) print(model AutoModelForSeq2SeqLM.from_pretrained(Wan2.1-umt5)) return None3.2 针对不同内容的摘要策略不是所有文章都适合用同样的参数来生成摘要。新闻、评论、技术文章它们的结构和重点都不一样。下面我分享几个针对不同内容类型的优化策略def smart_summarize(summarizer, text, content_typegeneral): 根据内容类型智能调整摘要策略 if not summarizer or not text: return None # 根据内容类型调整参数 strategy_configs { news: { # 新闻类强调时效性和关键事实 max_length: 100, min_length: 40, length_penalty: 1.5, num_beams: 4, temperature: 0.3, # 较低温度更确定性的输出 }, review: { # 评论类强调观点和评价 max_length: 80, min_length: 30, length_penalty: 1.2, num_beams: 6, # 更多beam探索更多可能性 temperature: 0.8, # 稍高温度更有创造性 }, technical: { # 技术文章强调方法和结论 max_length: 120, min_length: 50, length_penalty: 2.0, # 鼓励更长、更详细的摘要 num_beams: 4, temperature: 0.4, }, forum: { # 论坛帖子提取核心讨论点 max_length: 60, min_length: 20, length_penalty: 0.8, # 鼓励更简洁的摘要 num_beams: 4, temperature: 0.5, }, general: { # 通用类型平衡设置 max_length: 80, min_length: 30, length_penalty: 1.0, num_beams: 4, temperature: 0.7, } } config strategy_configs.get(content_type, strategy_configs[general]) # 根据文本长度动态调整参数 text_length len(text) if text_length 2000: config[max_length] min(150, config[max_length] 30) elif text_length 500: config[max_length] max(50, config[max_length] - 20) return summarizer.summarize(text, **config) def detect_content_type(text): 简单的内容类型检测 if not text: return general text_lower text.lower() # 关键词检测实际项目中可以用更复杂的模型 news_keywords [报道, 记者, 讯, 电, 日前, 近日] review_keywords [认为, 觉得, 体验, 评价, 好评, 差评, 建议] tech_keywords [实现, 代码, 算法, 架构, 部署, 配置, 优化] forum_keywords [楼主, 回复, 沙发, 板凳, 顶, 赞, 吐槽] keyword_scores { news: sum(1 for kw in news_keywords if kw in text_lower), review: sum(1 for kw in review_keywords if kw in text_lower), technical: sum(1 for kw in tech_keywords if kw in text_lower), forum: sum(1 for kw in forum_keywords if kw in text_lower), } # 返回得分最高的类型 detected_type max(keyword_scores.items(), keylambda x: x[1]) # 如果最高分太低返回通用类型 if detected_type[1] 2: return general return detected_type[0] # 完整的摘要生成流程 def generate_summaries_for_dataframe(df, summarizer, content_colcontent_clean): 为DataFrame中的所有文章生成摘要 print(开始生成摘要...) summaries [] content_types [] for idx, row in df.iterrows(): if idx % 10 0: print(f正在处理第 {idx 1}/{len(df)} 篇文章) text row[content_col] # 检测内容类型 content_type detect_content_type(text) content_types.append(content_type) # 生成摘要 summary smart_summarize(summarizer, text, content_type) if summary: summaries.append(summary) else: summaries.append(摘要生成失败) df[summary] summaries df[content_type] content_types print(摘要生成完成) # 统计摘要长度分布 summary_lengths df[summary].apply(lambda x: len(str(x))) print(f摘要平均长度: {summary_lengths.mean():.1f} 字符) print(f摘要长度分布: 最短 {summary_lengths.min()}最长 {summary_lengths.max()}) return df4. 实际应用与效果评估理论说再多不如看看实际效果。我找了一些真实的爬虫数据跑了一遍这个流程下面分享几个具体的例子和效果评估方法。4.1 实际案例展示假设我们爬取了一些科技新闻经过清洗后用我们的流水线处理。这是其中一个例子的前后对比原始爬取内容片段【最新消息】据媒体报道某科技公司今日发布了全新AI芯片性能提升显著...此处省略300字...点击这里查看详情 关注我们的公众号获取更多资讯广告合作请联系xxx-xxxx-xxxx清洗后内容据媒体报道某科技公司今日发布了全新AI芯片性能提升显著。该芯片采用5纳米制程工艺相比上一代产品计算能力提升约50%能耗降低30%。公司表示这款芯片将主要用于数据中心和边缘计算场景预计明年第一季度开始量产。生成的摘要某科技公司发布新款5纳米AI芯片计算性能提升50%能耗降低30%主要面向数据中心和边缘计算应用计划明年第一季度量产。可以看到清洗过程去掉了广告和无关链接摘要则准确抓住了核心信息谁、做了什么、有什么特点、什么时候量产。4.2 效果评估方法摘要生成得好不好不能光靠人眼看还得有些量化的评估方法。这里我分享几个简单实用的评估指标def evaluate_summary_quality(df, content_colcontent_clean, summary_colsummary): 评估摘要质量 if len(df) 0: print(没有数据可评估) return evaluation_results { coverage_score: [], # 覆盖率摘要包含原文关键信息的程度 conciseness_score: [], # 简洁性摘要长度与原文长度的比例 readability_score: [], # 可读性基于句子长度和词汇复杂度 } for _, row in df.iterrows(): content str(row[content_col]) summary str(row[summary_col]) if not content or not summary or summary 摘要生成失败: evaluation_results[coverage_score].append(0) evaluation_results[conciseness_score].append(0) evaluation_results[readability_score].append(0) continue # 1. 覆盖率评估简化版基于关键词重叠 content_words set(content.split()) summary_words set(summary.split()) common_words content_words.intersection(summary_words) coverage len(common_words) / max(len(content_words), 1) * 100 evaluation_results[coverage_score].append(min(coverage, 100)) # 2. 简洁性评估 compression_ratio len(summary) / max(len(content), 1) # 理想的压缩比在10%-30%之间 if compression_ratio 0.1: conciseness 100 # 非常简洁 elif compression_ratio 0.5: conciseness 0 # 不够简洁 else: conciseness max(0, 100 - (compression_ratio * 200)) evaluation_results[conciseness_score].append(conciseness) # 3. 可读性评估简化版基于平均句长和词汇多样性 sentences summary.split(。) if 。 in summary else summary.split(.) sentences [s.strip() for s in sentences if s.strip()] if sentences: avg_sentence_length sum(len(s) for s in sentences) / len(sentences) # 理想句长在15-25字之间 if 15 avg_sentence_length 25: readability 100 elif avg_sentence_length 10: readability 50 elif avg_sentence_length 40: readability 30 else: readability 80 else: readability 0 evaluation_results[readability_score].append(readability) # 计算平均分 avg_scores {} for metric, scores in evaluation_results.items(): valid_scores [s for s in scores if s 0] avg_scores[metric] sum(valid_scores) / max(len(valid_scores), 1) # 综合评分 avg_scores[overall_score] sum(avg_scores.values()) / len(avg_scores) print(\n摘要质量评估结果) print(f平均覆盖率: {avg_scores[coverage_score]:.1f}%) print(f平均简洁性: {avg_scores[conciseness_score]:.1f}%) print(f平均可读性: {avg_scores[readability_score]:.1f}%) print(f综合评分: {avg_scores[overall_score]:.1f}%) return avg_scores def analyze_summary_examples(df, num_examples3): 分析几个具体的摘要例子 print(f\n随机分析 {num_examples} 个摘要例子) print( * 60) sample_df df.sample(min(num_examples, len(df))) for idx, (_, row) in enumerate(sample_df.iterrows(), 1): print(f\n例子 {idx} - 类型: {row.get(content_type, unknown)}) print(f原文长度: {len(row[content_clean])} 字符) print(f摘要长度: {len(row[summary])} 字符) print(f压缩比: {len(row[summary])/len(row[content_clean])*100:.1f}%) print(f摘要内容: {row[summary][:150]}... if len(row[summary]) 150 else f摘要内容: {row[summary]}) print(- * 40) # 完整的评估流程 def run_complete_pipeline(crawled_data): 运行完整的处理流水线 print( * 60) print(开始完整的数据处理流水线) print( * 60) # 1. 数据清洗 print(\n1. 数据清洗阶段) cleaned_data apply_cleaning_pipeline(crawled_data) # 2. 初始化摘要生成器 print(\n2. 初始化模型) summarizer setup_summarizer() if not summarizer: print(模型初始化失败无法继续) return None # 3. 生成摘要 print(\n3. 生成摘要) result_data generate_summaries_for_dataframe(cleaned_data, summarizer) # 4. 评估效果 print(\n4. 评估摘要质量) scores evaluate_summary_quality(result_data) # 5. 展示例子 analyze_summary_examples(result_data) print(\n * 60) print(流水线执行完成) print( * 60) return result_data, scores4.3 性能优化与实用建议在实际使用中你可能会遇到一些性能问题或者想要进一步优化效果。这里分享几个我实践中总结的经验处理速度优化对于大量数据考虑使用批量处理batch processing如果GPU内存足够可以适当增加batch size对于实时性要求不高的场景可以使用异步处理质量提升技巧针对你的特定领域数据可以微调模型如果条件允许结合规则方法先用规则提取关键信息如时间、地点、人物再让模型生成摘要多模型融合可以用不同参数生成多个摘要然后选择最好的或者合并它们错误处理与监控添加重试机制特别是网络不稳定的情况记录生成失败的案例分析原因定期评估摘要质量建立质量监控机制5. 把这一切用起来这套方案最直接的应用场景就是把你那些沉睡的爬虫数据激活。比如你爬了几万篇行业新闻手动看是不可能了但用这个流水线跑一遍你就能快速知道大家都在关注什么有什么新趋势。在电商领域可以用它处理商品评论快速了解用户反馈的共性问题在舆情监控中可以快速概括热点事件的发展脉络在研究领域可以批量处理论文摘要加快文献调研速度。实际部署的时候你可以把这个流水线封装成一个服务提供API接口让其他系统调用。也可以做成定时任务每天自动处理新增的数据。如果数据量特别大还可以考虑分布式处理。从我自己的使用经验来看这个方案最大的价值不是替代人工而是把人工从重复劳动中解放出来。原来需要花几个小时看的数据现在几分钟就能出摘要而且质量相当不错。当然它也不是完美的有时候会漏掉一些细节或者对某些专业领域理解不够深但这完全可以通过后续的优化来改进。如果你正在处理大量的文本数据或者想要从爬虫数据中挖掘更多价值真的建议试试这个方法。从简单的例子开始慢慢调整参数让它适应你的具体需求。你会发现有了AI的帮忙数据处理不再是苦差事而是一个能真正产生价值的环节。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。