电子商务网站开发方案网站关键词选取的步骤
电子商务网站开发方案,网站关键词选取的步骤,杭州电子商务网站建设,苏州网站开发建设制作StructBERT模型数据预处理实战#xff1a;Python爬虫文本清洗与格式化
如果你正在为StructBERT这类预训练语言模型准备数据#xff0c;可能会发现一个头疼的问题#xff1a;网上的文本五花八门#xff0c;直接拿来用根本不行。广告、乱码、重复内容、格式不统一……这些“…StructBERT模型数据预处理实战Python爬虫文本清洗与格式化如果你正在为StructBERT这类预训练语言模型准备数据可能会发现一个头疼的问题网上的文本五花八门直接拿来用根本不行。广告、乱码、重复内容、格式不统一……这些“脏数据”喂给模型效果肯定会大打折扣。别担心这篇文章就是来解决这个问题的。我会带你走一遍完整的流程从用Python爬虫把数据“抓”下来到一步步把它清洗、整理成模型能“吃”得下的干净格式。整个过程就像给食材做预处理洗菜、切配最后才能下锅炒出好菜。我们会用到requests、BeautifulSoup这些工具还会处理中文特有的繁简转换、停用词过滤等问题。跟着做下来你不仅能得到一份高质量的数据集更能掌握一套可复用的数据预处理方法论。1. 准备工作搭建你的数据“厨房”工欲善其事必先利其器。在开始爬取和清洗之前我们需要先把“厨房”——也就是Python环境——收拾好把必要的“厨具”准备齐全。1.1 安装必要的工具库打开你的终端或命令提示符用pip安装以下几个核心库。它们各自扮演着不同的角色pip install requests beautifulsoup4 jieba langconv opencc-python-reimplemented简单解释一下它们都是干什么的requests相当于你的“网络小手”负责去网站上把网页内容抓取回来。BeautifulSoup是个“网页解析器”。网页代码HTML像一团乱麻它帮你从中精准地找到并提取出你想要的文字内容。jieba中文分词“利器”。它能把连续的中文句子按照词语的意思切割成一个个独立的词这是中文文本处理的基础步骤。langconv或opencc中文“翻译官”专门负责繁体字和简体字之间的转换确保文本格式统一。1.2 找个合适的“菜市场”数据源为了演示我们需要一个目标网站。请务必遵守目标网站的robots.txt协议并控制爬取速度和频率避免对对方服务器造成压力。这里我们以一个假设的、结构清晰的新闻文章列表页和详情页为例。假设我们的目标页面结构如下列表页https://example-news.com/list 每篇文章的链接在a classarticle-link href...标签里。详情页文章的正文主要位于div classarticle-content标签内。在实际操作中你需要用浏览器的“开发者工具”按F12仔细查看目标网站的真实结构并替换掉这些示例选择器。2. 第一步用爬虫获取原始文本现在我们开始第一步把网上的原始文本“抓”下来。这个过程就像去市场采购原材料。2.1 抓取文章链接列表我们首先从列表页获取所有文章的详细页面地址。import requests from bs4 import BeautifulSoup import time def fetch_article_links(list_url, max_pages3): 从列表页抓取文章详情页的链接。 参数: list_url: 列表页的URL基础格式用于翻页 max_pages: 计划爬取的列表页数量避免过量请求 返回: 文章详情页链接的列表 all_links [] headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } for page in range(1, max_pages 1): # 构造每一页的URL根据网站实际翻页规则调整 if page 1: current_url list_url else: current_url f{list_url}?page{page} # 示例翻页格式 try: print(f正在抓取列表页: {current_url}) response requests.get(current_url, headersheaders, timeout10) response.raise_for_status() # 检查请求是否成功 response.encoding response.apparent_encoding # 自动识别编码 soup BeautifulSoup(response.text, html.parser) # 根据实际网页结构找到文章链接这里是示例 link_elements soup.find_all(a, class_article-link) for link in link_elements: article_url link.get(href) # 处理相对链接 if article_url and not article_url.startswith(http): article_url requests.compat.urljoin(list_url, article_url) if article_url: all_links.append(article_url) print(f第{page}页找到 {len(link_elements)} 个链接。) time.sleep(1) # 礼貌性延迟避免请求过快 except requests.RequestException as e: print(f抓取列表页 {current_url} 时出错: {e}) continue # 去重 unique_links list(set(all_links)) print(f总共获取到 {len(unique_links)} 个唯一文章链接。) return unique_links # 使用示例 if __name__ __main__: news_list_url https://example-news.com/list article_urls fetch_article_links(news_list_url, max_pages2)2.2 抓取单篇文章正文拿到链接后我们逐个访问提取出干净的正文内容。def fetch_article_content(article_url): 抓取单篇文章的标题和正文内容。 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36} try: response requests.get(article_url, headersheaders, timeout10) response.raise_for_status() response.encoding response.apparent_encoding soup BeautifulSoup(response.text, html.parser) # 提取标题根据实际结构调整选择器 title_elem soup.find(h1, class_article-title) title title_elem.get_text(stripTrue) if title_elem else 无标题 # 提取正文根据实际结构调整选择器 content_elem soup.find(div, class_article-content) if content_elem: # 移除可能存在的脚本、样式等无用标签 for tag in content_elem([script, style, nav, footer, aside]): tag.decompose() content content_elem.get_text(separator\n, stripTrue) else: content return {url: article_url, title: title, content: content} except requests.RequestException as e: print(f抓取文章 {article_url} 时出错: {e}) return None # 批量抓取文章内容 def batch_fetch_contents(article_urls, delay2): 批量抓取多篇文章内容并加入延迟以遵守爬虫礼仪。 articles_data [] for idx, url in enumerate(article_urls): print(f正在处理 ({idx1}/{len(article_urls)}): {url}) article_data fetch_article_content(url) if article_data and article_data[content]: # 只保留有内容的文章 articles_data.append(article_data) time.sleep(delay) # 每次请求后等待非常重要 return articles_data # 使用示例 if __name__ __main__: # 假设我们已经有了 article_urls all_articles batch_fetch_contents(article_urls[:5], delay2) # 先试5篇 print(f成功抓取 {len(all_articles)} 篇文章。)3. 第二步深度清洗与格式化文本抓下来的文本还很“粗糙”充满了HTML残留、广告、无关字符等“杂质”。这一步就是精细加工。3.1 基础清洗去掉明显的“杂质”我们先处理掉那些一眼就能看出来的无用内容。import re def basic_text_clean(text): 执行基础文本清洗。 if not text: return # 1. 移除多余的空白字符换行、制表符、连续空格 text re.sub(r\s, , text) # 2. 移除常见的网页垃圾如“展开全文”、“”等 garbage_patterns [ r展开全文, r, r点击查看详情, r关注我们的微信公众号, r本文来自.*?专栏, # 非贪婪匹配 r版权归.*?所有, ] for pattern in garbage_patterns: text re.sub(pattern, , text, flagsre.IGNORECASE) # 3. 移除URL链接 text re.sub(rhttps?://\S|www\.\S, , text) # 4. 移除邮箱地址 text re.sub(r\S*\S*\s?, , text) # 5. 移除纯数字、特殊字符序列但保留句子中的标点 # 保留中文标点和基本英文标点用于断句 text re.sub(r[^\w\s\u4e00-\u9fff。“”‘’、【】《》…—\-.,!?;:], , text) return text.strip() # 应用到所有文章 cleaned_articles [] for article in all_articles: cleaned_content basic_text_clean(article[content]) if cleaned_content: # 清洗后内容不为空 article[cleaned_content] cleaned_content cleaned_articles.append(article) print(f基础清洗后剩余 {len(cleaned_articles)} 篇有效文章。)3.2 中文文本特殊处理中文文本有其独特性我们需要专门处理。from langconv import Converter def traditional_to_simplified(text): 将繁体中文转换为简体中文。 使用 langconv 库适用于大多数情况。 try: converter Converter(zh-hans) return converter.convert(text) except Exception as e: print(f繁简转换时出错: {e}) return text # 如果出错返回原文本 def remove_stopwords(text, stopwords_filepathstopwords.txt): 去除中文停用词。 需要准备一个停用词文件每行一个词。 # 加载停用词表 try: with open(stopwords_filepath, r, encodingutf-8) as f: stopwords set([line.strip() for line in f if line.strip()]) except FileNotFoundError: print(f未找到停用词文件 {stopwords_filepath}跳过此步骤。) return text # 使用jieba分词 import jieba words jieba.lcut(text) # 过滤停用词并重新组合成文本 filtered_words [word for word in words if word not in stopwords and word.strip()] return .join(filtered_words) # 用空格连接或直接连接 def chinese_specific_clean(article_dict): 对单篇文章进行中文特殊处理。 content article_dict.get(cleaned_content, ) if not content: return article_dict # 1. 繁简统一转换为简体 content traditional_to_simplified(content) # 2. 全角字符转半角针对英文和数字 # 此步骤可根据需要添加这里提供函数 def strQ2B(ustring): 全角转半角 rstring for uchar in ustring: inside_code ord(uchar) if inside_code 12288: # 全角空格 inside_code 32 elif 65281 inside_code 65374: # 全角字符除空格 inside_code - 65248 rstring chr(inside_code) return rstring content strQ2B(content) # 3. 去除停用词注意对于BERT类模型有时保留停用词更好需根据任务决定 # content remove_stopwords(content) # 此步骤非必须注释掉 article_dict[processed_content] content return article_dict # 应用中文处理 final_articles [chinese_specific_clean(article) for article in cleaned_articles]3.3 文本去重与质量过滤最后我们去掉重复或质量太低的内容。def remove_duplicate_articles(articles_list, content_keyprocessed_content): 基于内容哈希值去除重复文章。 seen set() unique_articles [] for article in articles_list: content article.get(content_key, ) if not content: continue # 生成内容的简单哈希也可用simhash处理近似重复 content_hash hash(content[:500]) # 取前500字符哈希可根据情况调整 if content_hash not in seen: seen.add(content_hash) unique_articles.append(article) print(f去重后剩余 {len(unique_articles)} 篇唯一文章。) return unique_articles def filter_by_length(articles_list, min_length100, content_keyprocessed_content): 过滤掉内容过短的文章。 filtered [] for article in articles_list: content article.get(content_key, ) if content and len(content) min_length: filtered.append(article) print(f长度过滤{min_length}字符后剩余 {len(filtered)} 篇文章。) return filtered # 执行去重和过滤 unique_articles remove_duplicate_articles(final_articles) quality_articles filter_by_length(unique_articles, min_length150)4. 第三步为StructBERT准备最终格式清洗干净的数据现在需要转换成模型认识的格式。StructBERT通常接受的是分好词或字的序列。4.1 分词与格式化这里我们演示两种常见输入格式的准备一种是用于预训练或句子分类的[CLS]句子格式另一种是用于如问答、自然语言推理任务的句子对格式。def format_for_bert_single(sentence, tokenizer, max_len512): 将单个句子格式化为BERT输入。 格式: [CLS] tokens [SEP] # 这里使用BertTokenizer作为示例你需要根据实际使用的StructBERT具体tokenizer初始化 # from transformers import BertTokenizer # tokenizer BertTokenizer.from_pretrained(your-model-path) tokens tokenizer.tokenize(sentence) # 截断到最大长度-2为[CLS]和[SEP]留位置 if len(tokens) max_len - 2: tokens tokens[:max_len-2] # 添加特殊标记 tokens [[CLS]] tokens [[SEP]] # 将token转换为id input_ids tokenizer.convert_tokens_to_ids(tokens) # 创建attention mask (1 for real tokens, 0 for padding) attention_mask [1] * len(input_ids) # 填充到最大长度 while len(input_ids) max_len: input_ids.append(tokenizer.pad_token_id or 0) attention_mask.append(0) return { input_ids: input_ids, attention_mask: attention_mask, original_text: sentence # 保留原文方便检查 } def format_for_bert_pair(sentence_a, sentence_b, tokenizer, max_len512): 将句子对格式化为BERT输入。 格式: [CLS] tokens_a [SEP] tokens_b [SEP] tokens_a tokenizer.tokenize(sentence_a) tokens_b tokenizer.tokenize(sentence_b) # 处理长度为三个特殊标记预留位置 max_len_a_b max_len - 3 if len(tokens_a) len(tokens_b) max_len_a_b: # 一种简单的策略按比例截断 excess (len(tokens_a) len(tokens_b)) - max_len_a_b cut_a min(len(tokens_a), excess // 2 excess % 2) cut_b min(len(tokens_b), excess // 2) tokens_a tokens_a[:-cut_a] if cut_a else tokens_a tokens_b tokens_b[:-cut_b] if cut_b else tokens_b # 组合token并添加特殊标记 tokens [[CLS]] tokens_a [[SEP]] tokens_b [[SEP]] input_ids tokenizer.convert_tokens_to_ids(tokens) token_type_ids [0] * (len(tokens_a) 2) [1] * (len(tokens_b) 1) # 区分句子A和B attention_mask [1] * len(input_ids) # 填充 while len(input_ids) max_len: input_ids.append(tokenizer.pad_token_id or 0) token_type_ids.append(0) attention_mask.append(0) return { input_ids: input_ids, token_type_ids: token_type_ids, attention_mask: attention_mask, original_text_a: sentence_a, original_text_b: sentence_b } # 示例将清洗后的文章内容转换为单个句子列表这里简单按句号分割 def prepare_sentences_from_articles(articles_list, content_keyprocessed_content): 从文章内容中提取句子。 这是一个简单的示例实际中可能需要更健壮的句子分割。 all_sentences [] for article in articles_list: content article.get(content_key, ) # 简单按中文句号、问号、感叹号分割 sentences re.split(r[。], content) for sent in sentences: sent sent.strip() if sent and len(sent) 5: # 过滤掉过短的片段 all_sentences.append(sent) return all_sentences # 假设我们有了tokenizer # tokenizer AutoTokenizer.from_pretrained(alibaba-pai/structbert-base-zh) # sentences prepare_sentences_from_articles(quality_articles) # formatted_data [format_for_bert_single(sent, tokenizer) for sent in sentences[:10]] # 处理前10句示例4.2 保存预处理结果最后将处理好的数据保存下来供模型训练或推理使用。import json import pandas as pd def save_data_to_json(data, filepath): 保存数据为JSON格式 with open(filepath, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) print(f数据已保存至 {filepath}) def save_data_to_csv(articles_list, filepath, fields[title, processed_content]): 保存数据为CSV格式 df_data [] for article in articles_list: row {field: article.get(field, ) for field in fields} df_data.append(row) df pd.DataFrame(df_data) df.to_csv(filepath, indexFalse, encodingutf-8-sig) print(f数据已保存至 {filepath}) # 保存清洗后的原始文本用于后续不同任务 save_data_to_csv(quality_articles, cleaned_articles.csv, fields[title, url, processed_content]) # 如果需要也可以保存格式化后的token id序列数据量较大 # save_data_to_json(formatted_data, bert_formatted_data.json)5. 总结走完这一整套流程你应该对如何为StructBERT这样的模型准备数据有了清晰的体会。核心其实就三步抓取、清洗、格式化。爬虫负责把“生食材”弄回来清洗步骤则像细致的摘菜和洗菜去泥、去烂叶、统一规格。最后的格式化就是按菜谱要求切好、码盘让模型“厨师”能够直接下锅。实际操作中有几个点特别值得注意一是爬虫要“礼貌”加延迟、看robots.txt二是清洗规则要针对你的数据源量身定制多观察、多调试三是中文处理繁简、分词要根据下游任务灵活选择做或不做。这套方法不仅适用于StructBERT对于其他需要纯文本输入的NLP模型也同样有效。你可以把代码当作一个模板根据自己遇到的实际网站和数据特点进行调整和扩展。数据处理是个需要耐心的活儿但高质量的数据绝对是模型效果好坏的基石。希望这篇实战指南能帮你打好这个基础。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。