from flask import Flask, render_template, request, send_file
from bs4 import BeautifulSoup
import bs4 as bs4
from urllib.parse import urlparse
import requests
from collections import Counter
import pandas as pd
import os
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
from sklearn.model_selection import train_test_split
import spacy as sp
from spacy.language import Language # 新增:用于添加自定义管道
import jieba # 新增:导入Jieba中文分词库
import psutil
from sklearn.calibration import CalibratedClassifierCV
import joblib
from sklearn.svm import LinearSVC
# 加载spaCy英文模型(保留英文处理能力)
import en_core_web_sm
# -------------------------- 关键修改1:初始化spaCy并添加Jieba中文分词管道 --------------------------
# 加载spaCy英文基础模型
nlp = en_core_web_sm.load()
# 定义Jieba中文分词组件(作为spaCy的自定义管道)
@Language.component("jieba_tokenizer")
def jieba_tokenizer(doc):
"""
自定义spaCy分词管道:
- 对中文文本用Jieba分词
- 对英文文本保留spaCy原生分词(因Jieba对英文分词效果差)
"""
# 提取文档纯文本
text = doc.text
# 识别文本是否以中文为主(含中文字符则判定为中文文本)
has_chinese = any('\u4e00' <= char <= '\u9fff' for char in text)
if has_chinese:
# 中文文本:用Jieba精确分词(可根据需求调整cut参数,如cut_all=True为全模式)
words = jieba.lcut(text)
# 生成空格标记(spaCy需要知道词之间是否有空格,中文无空格故全为False)
spaces = [False] * len(words)
# 重新构建spaCy的Doc对象(用Jieba分好的词)
return sp.tokens.Doc(doc.vocab, words=words, spaces=spaces)
else:
# 英文文本:直接返回原Doc对象,使用spaCy原生分词
return doc
# 将Jieba分词管道添加到spaCy的最前端(在"parser"之前执行,确保分词优先)
nlp.add_pipe("jieba_tokenizer", before="parser")
# -------------------------- 原有代码保留,仅修改TF-IDF参数适配中文 --------------------------
# 加载预训练模型
m1 = joblib.load('linear_svc_model.joblib')
# -------------------------- 关键修改2:调整TF-IDF向量器参数(支持中文单字/词) --------------------------
tfidf = TfidfVectorizer(
sublinear_tf=True,
min_df=3, # 降低min_df:中文文本词频通常更低,避免过滤过多有效词
ngram_range=(1, 3), # 保留1-2元语法(中文1元是单字,2元是词组,如"自然语言")
stop_words='english', # 保留英文停用词过滤
token_pattern=r"(?u)\b\w+\b" # 放宽token匹配规则:支持中文单字/词(原规则对中文不友好)
)
class ScrapTool:
# 此类逻辑完全保留(网页爬取逻辑无需修改)
def visit_url(self, website_url):
try:
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',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
content = requests.get(website_url, headers=headers, timeout=60).content
soup = BeautifulSoup(content, "lxml")
result = {
"website_url": website_url,
"website_name": self.get_website_name(website_url),
"website_text": self.get_html_title_tag(soup) +
self.get_html_meta_tags(soup) +
self.get_html_heading_tags(soup) +
self.get_text_content(soup)
}
return pd.Series(result)
except Exception as e:
print(f"访问URL时出错: {str(e)}")
return None
def get_website_name(self, website_url):
return "".join(urlparse(website_url).netloc.split(".")[-2])
def get_html_title_tag(self, soup):
if soup.title and soup.title.contents:
return '. '.join(soup.title.contents)
return ""
def get_html_meta_tags(self, soup):
tags = soup.find_all(
lambda tag: (tag.name == "meta") &
(tag.has_attr('name') & tag.has_attr('content'))
)
content = [str(tag["content"]) for tag in tags
if tag["name"] in ['keywords', 'description']]
return ' '.join(content)
def get_html_heading_tags(self, soup):
tags = soup.find_all(["h1", "h2", "h3", "h4", "h5", "h6"])
content = [" ".join(tag.stripped_strings) for tag in tags]
return ' '.join(content)
def get_text_content(self, soup):
tags_to_ignore = ['style', 'script', 'head', 'title', 'meta',
'[document]', "h1", "h2", "h3", "h4", "h5", "h6", "noscript"]
tags = soup.find_all(string=True)
result = []
for tag in tags:
stripped_tag = tag.strip()
if (tag.parent.name not in tags_to_ignore and
not isinstance(tag, bs4.element.Comment) and
not stripped_tag.isnumeric() and
len(stripped_tag) > 0):
result.append(stripped_tag)
return ' '.join(result)
# 初始化爬虫工具
scrapTool = ScrapTool()
# 初始化Flask应用
app = Flask(__name__)
# -------------------------- 关键修改3:优化clean_text函数(适配中英文分词结果) --------------------------
def clean_text(doc):
'''清理文档:移除停用词、标点、数字,词形还原(英文),统一小写'''
if not doc:
return ""
# 用添加了Jieba管道的spaCy处理文本(自动区分中英文分词)
doc = nlp(doc)
tokens = []
exclusion_list = ["nan"]
for token in doc:
# 过滤规则:保留中英文有效词(调整判断逻辑,避免误过滤中文)
if (
token.is_stop # 过滤停用词(spaCy原生停用词库+Jieba可额外添加中文停用词)
or token.is_punct # 过滤标点
or token.text.isnumeric() # 过滤纯数字
or (token.text.isalnum() is False and not ('\u4e00' <= token.text <= '\u9fff')) # 过滤非字母数字且非中文的符号
or token.text in exclusion_list
):
continue
# 词形还原:英文用lemma_,中文直接用原词(spaCy对中文lemma_支持弱)
if '\u4e00' <= token.text <= '\u9fff':
cleaned_token = token.text.lower().strip() # 中文统一小写(若有大小写需求可删除)
else:
cleaned_token = str(token.lemma_.lower().strip()) # 英文词形还原
tokens.append(cleaned_token)
return " ".join(tokens)
# Flask路由逻辑完全保留
@app.route("/")
def hello_world():
return render_template('index.html')
@app.route('/submit', methods=['POST'])
def submit():
site = request.form['site']
print(f"处理网站: {site}")
try:
# 读取数据文件(若data.csv包含中文数据,需确保编码正确,如添加encoding='utf-8')
dir_path = os.path.dirname(os.path.realpath(__file__))
file_path = os.path.join(dir_path, 'data.csv')
df = pd.read_csv(file_path, low_memory=True, encoding='utf-8') # 新增encoding:避免中文乱码
df['category_id'] = df['Category'].factorize()[0]
# 训练TF-IDF向量器(若data.csv含中文,会自动适配中文词)
X_train, _ = train_test_split(
df['cleaned_website_text'],
test_size=0.20,
random_state=0
)

WWXXYYHRT
- 粉丝: 9
最新资源
- 基于Qt框架开发的智能家居综合管理系统-包含家居设备远程控制-音乐播放器-天气预报-视频监控四大功能模块-采用C编程语言实现-通过TCP协议进行客户端与服务端通信-使用QJso.zip
- HaoderO-Matlab-Simulink-27288-1755682206188.zip
- Flet共享数据存储多窗口管理自定义模板
- 语义与交互式图像检索
- 机械设计制造附自动化.doc
- 第3章-桩基础工程.ppt
- 我国中小企业网络营销的发展和对策浅析-.doc
- 地下室顶板梁钢筋绑扎施工技术交底.doc
- C语言循环控制.pptx
- C语言的实践实习心得.doc
- 小班音乐欣赏《大树妈妈》.doc
- 软件行业绩效管理实施方案.docx
- PCB手工焊接技术.ppt
- 接入电力线(PLC)宽带通信合作协议.doc
- 消费市场结构调查统计表-secret.docx
- 数学(江苏专用理科提高版)大一轮复习要点导学第十三章算法统计与概率-Word版含解析.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


