#爬取人民网新闻
import requests
from bs4 import BeautifulSoup
import openpyxl
# 创建Excel表格
wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(["title", "link", "date", "content"])
# 爬取网页标题和链接的函数
def get_news_links(url):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
links = []
# 从 ul.list_16 中提取每个 li 的新闻标题和链接
for li in soup.select('ul.list_16 li'):
a_tag = li.find('a') # 获取新闻链接和标题
title = a_tag.get_text().strip()
link = a_tag.get('href') # 提取相对链接
if not link.startswith('http'):
link = "http://finance.people.com.cn" + link # 补全相对链接
# 获取新闻日期
date_tag = li.find('em')
date = date_tag.get_text().strip() if date_tag else "未知日期"
links.append((title, link, date))
return links
# 爬取每篇新闻的正文内容
def get_news_content(link):
response = requests.get(link)
soup = BeautifulSoup(response.content, 'html.parser')
# 查找正文,定位到 div.rm_txt_con 并提取所有 p 标签内容
article = soup.find('div', class_='rm_txt_con') # 根据HTML结构提取内容
if article:
paragraphs = article.find_all('p')
content = "\n".join([p.get_text().strip() for p in paragraphs if p.get_text().strip()])
else:
content = "无正文内容"
return content
# 爬取多个新闻标题和链接
url = "http://finance.people.com.cn/GB/70846/index1.html"
news_links = get_news_links(url)
# 将数据写入Excel
for title, link, date in news_links:
print(f"正在处理: {title}")
# 获取每篇新闻的正文内容
content = get_news_content(link)
# 将标题、链接、发布时间和正文写入Excel
sheet.append([title, link, date, content])
正在处理: 油价调整!5月19日24时起汽、柴油价格每吨分别降低230元和220元 正在处理: 业界:把握人工智能发展趋势 以用促建赋能高质量发展 正在处理: 深化区域交流合作 第26届青洽会将在青海西宁举办 正在处理: 张于喆 郑腾飞:加快构建多层次数据流通交易体系 正在处理: 市场监管总局公布首批商品过度包装检验检测机构名单 正在处理: “数据要素产业服务平台(深圳试点)暨数据要素×应用场景生态实验室”合作签约仪式举行 正在处理: “三驾马车”协同发力 国民经济发展质量稳步提升 正在处理: 黄琦:数字技术是全面绿色转型的“催化剂” 正在处理: 国家统计局:部分工业行业价格有所改善 正在处理: 九部门部署科技服务业高质量发展 明确十大重点领域 正在处理: 国家统计局:我国经济有条件、有能力、有底气应对各种风险挑战 正在处理: 国资央企提升品牌建设效能 凸显功能价值 正在处理: 结构性减税降费政策现成效 我国创新动能增势良好 正在处理: 国家统计局:多项指标稳定增长 展现经济强大韧性 正在处理: 1至4月国家铁路发送货物12.99亿吨 日均装车18万车 正在处理: 4月份我国国民经济顶住压力稳定增长 正在处理: 逾六成专精特新中小企业营收较上年实现增长或持平 正在处理: 水利部:中国愿同各方携手合作推动生态大坝技术研发与应用 正在处理: 人工智能为知识产权保护注入新动能 正在处理: 走近钱学森、郭永怀……一场与“力学”的亲密接触 正在处理: 研究所变身“游园会”:遇见哪吒,探秘理化 正在处理: 12306团队:“每行代码都是承诺” 正在处理: 公众科学日沉浸式漫游“物理世界” 正在处理: 分子工具能精准“开关”大脑回路 正在处理: 去年我国卫星导航产业产值达5758亿元 正在处理: “鲲龙”批生产首架机完成生产试飞 正在处理: “三体计算星座”为啥把计算送上天 正在处理: 中小银行改革化险提速 多家村镇银行被吸收合并 正在处理: “硬本领”“软实力”已成中国品牌全球化的底色 正在处理: 双边本币互换的积极作用正不断显现 正在处理: 年内REITs发行规模超113亿元 险资战投身份是亮点 正在处理: 共探开放包容金融体系 解码全球经济新未来 正在处理: 以高质量并购驱动产业升级 更好发挥资本市场枢纽功能 正在处理: 完善城市更新顶层设计 打造宜居、韧性、智慧城市 正在处理: 八大行动全力释放数据要素价值 新质生产力得以不断壮大 正在处理: 天问二号探测器已转入发射区 计划5月底择机发射 正在处理: 江苏启东:多举措助力民营企业高质量发展 正在处理: 微塑料“入侵”:真相、争议与行动 正在处理: 甘肃张掖“太空信使”划破苍穹 正在处理: 共建“一带一路”国家青年聚浙江绍兴 共话科技人文交流 正在处理: 工程机械迎电动化新潮流 中国企业抢先机 正在处理: 第34届哈洽会启幕 1500余家企业参展 正在处理: 2025世界雷达博览会开幕 李德仁院士冀推进和实现时空智能 正在处理: 先行指标透射经济发展动能强劲 中国高质量发展“枝繁叶茂” 正在处理: 中国东部小县城撬动全球轮胎市场
# 保存Excel文件
wb.save("news_data.xlsx")
print("爬取完成并保存到 news_data.xlsx")
爬取完成并保存到 news_data.xlsx
# %pip install jieba
#清洗文本
import pandas as pd
import os
import numpy as np
import re
import jieba
new_data = pd.DataFrame()
# 定义文件路径
input_file_path = r"news_data.xlsx"
news_data = pd.read_excel(input_file_path)
#文本预处理
def clean_content(text):
if pd.isna(text):
return text
text = str(text)
# 1. 清除日期格式
date_patterns = [
r"\d{4}[-年/.]\d{1,2}[-月/.]\d{1,2}[日]?", # 2023年12月31日, 2023-12-31, 2023/12/31
r"\d{1,2}[-/.]\d{1,2}(?!\d)", # 12/31, 12-31
r"\d{4}年", # 2023年
r"\d{1,2}月\d{1,2}日", # 12月31日
r"\d{1,2}月", # 12月
r"\d{1,2}日", # 31日
r"\d{4}" # 单独年份
]
for pattern in date_patterns:
text = re.sub(pattern, '', text)
# 2. 删除“(记者XXX)”类文本
text = re.sub(r'(记者[^)]*)', '', text)
# 3. 删除“人民网××电”类地点标签
text = re.sub(r'人民网.{1,4}电\s*', '', text)
# 4. 删除百分比数字(如 57%)
text = re.sub(r'\d+%+', '', text)
return text
news_data['content'] = news_data['content'].apply(clean_content)
# 加载停用词列表
stop_words_path = r"cn_stopwords.txt"
with open(stop_words_path, 'r', encoding='gbk') as f:
stop_words = [line.strip() for line in f.readlines()]
# 定义去除停用词的函数
def remove_stopwords(text):
words = jieba.cut(text) # 使用 jieba 进行分词
return ' '.join([word for word in words if word not in stop_words])
# 对 content 列进行分词并去除停用词,将处理后的文本存入新列 'cleaned_content'
news_data['cleaned_content'] = news_data['content'].apply(remove_stopwords)
news_data['cleaned_title'] = news_data['title'].apply(remove_stopwords)
news_data.to_excel( r".\cleaned_news_data.xlsx",index = False)
print(news_data.head())
Building prefix dict from the default dictionary ... Loading model from cache /tmp/jieba.cache Loading model cost 0.403 seconds. Prefix dict has been built successfully.
title \ 0 油价调整!5月19日24时起汽、柴油价格每吨分别降低230元和220元 1 业界:把握人工智能发展趋势 以用促建赋能高质量发展 2 深化区域交流合作 第26届青洽会将在青海西宁举办 3 张于喆 郑腾飞:加快构建多层次数据流通交易体系 4 市场监管总局公布首批商品过度包装检验检测机构名单 link date \ 0 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 1 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 2 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 3 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 4 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 content \ 0 制图:罗知之\n据国家发展改革委网站消息,根据近期国际市场油价变化情况,按照现行成品油价格形... 1 当前,人工智能作为引领新一轮科技革命和产业变革的技术,改变着人类的生产生活方式。如何抢抓人工... 2 “第26届中国·青海绿色发展投资贸易洽谈会(以下简称青洽会)将于至在西宁举办。”青海省人民政... 3 推动数字技术与实体经济深度融合,是建设现代化产业体系的必然要求,是践行高质量发展的重要途径。... 4 据国家市场监管总局网站消息,近日,市场监管总局印发通知,公布首批获得总局资质认定的具有商品过... cleaned_content \ 0 制图 罗知 \n 国家 发展 改革 委 网站 消息 近期 国际 市场 油价 变化 情况 现行... 1 当前 人工智能 引领 新一轮 科技 革命 产业 变革 技术 改变 人类 生产 生活 方式 抢... 2 26 届 中国 · 青海 绿色 发展 投资 贸易 洽谈会 以下 简称 青洽会 西宁 举办 青... 3 推动 数字 技术 实体 经济 深度 融合 建设 现代化 产业 体系 必然 要求 践行 高质量... 4 国家 市场监管 总局 网站 消息 近日 市场监管 总局 印发 通知 公布 首批 获得 总局 ... cleaned_title 0 油价 调整 月 19 日 24 时起汽 柴油 价格 每吨 降低 230 元 220 元 1 业界 把握 人工智能 发展趋势 以用 促建 赋能 高质量 发展 2 深化 区域 交流 合作 26 届 青洽会 青海 西宁 举办 3 张于 喆 郑 腾飞 加快 构建 多层次 数据 流通 交易 体系 4 市场监管 总局 公布 首批 商品 过度 包装 检验 检测 机构 名单
#生成词云图全流程
#对文本词组计数
content = news_data.content.values.tolist()
content_S = []
for line in content:
current_segment = jieba.lcut(line)
if len(current_segment) > 1 and current_segment !='\r\n':
content_S.append(current_segment)
# print(content_S)
#转化成列表格式
df_content = pd.DataFrame({'content_S': [' '.join(row) for row in content_S]})
df_stop_words = pd.DataFrame({'stopwords':[' '.join(row) for row in stop_words]})
# 停用词清理函数
def drop_stopwords(contents, stopwords):
contents_clean = []
all_words = []
for line in contents:
line_clean = []
for word in line:
if word in stopwords:
continue
line_clean.append(word)
all_words.append(str(word))
contents_clean.append(line_clean)
return contents_clean, all_words
contents_clean, all_words = drop_stopwords(content_S, stop_words)
# 正确词频统计
df_all_words = pd.DataFrame({'all_words': all_words})
words_count = df_all_words.groupby(by='all_words').size().reset_index(name='count')
words_count = words_count.sort_values(by='count', ascending=False).reset_index(drop=True)
words_count = words_count.drop(index=words_count.index[:2]) # 可视需要调整删除前两位
# %pip install wordcloud
#词云图生成
from wordcloud import WordCloud
import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib
matplotlib.rcParams['figure.figsize'] = (10.0, 5.0)
wordcloud = WordCloud(font_path = r"/usr/share/fonts/truetype/SimHei/SimHei.ttf",background_color = "white",max_font_size=80)
word_frequence = {x[0]:x[1] for x in words_count.head(100).values}
wordcloud = wordcloud.fit_words(word_frequence)
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
#提取新闻文本关键词——TF-IDF
import pandas as pd
# 重新加载并处理数据
file_path = r"cleaned_news_data.xlsx"
news = pd.read_excel(file_path)
# 提取 content 列中的文本内容
documents = news['cleaned_content'].tolist()
# 初始化 TfidfVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vectorizer = TfidfVectorizer(max_df=0.85, min_df=2, use_idf=True, ngram_range=(1,2))
# 计算TF-IDF矩阵
tfidf_matrix = tfidf_vectorizer.fit_transform(documents)
# 获取词汇表
feature_names = tfidf_vectorizer.get_feature_names_out()
# 提取每篇文档的关键词
def get_top_keywords(tfidf_matrix, feature_names, top_n=5):
top_keywords = []
for i in range(tfidf_matrix.shape[0]):
row = tfidf_matrix[i].toarray()[0]
sorted_indices = row.argsort()[::-1][:top_n]
keywords = [feature_names[index] for index in sorted_indices]
top_keywords.append(keywords)
return top_keywords
# 获取每篇文章的前5个关键词
news['main_words'] = get_top_keywords(tfidf_matrix, feature_names, top_n=5)
# 保存新的表格
new_file_path =r".\news_data_keywords_expanded.xlsx"
news.to_excel(new_file_path, index=False)
print(news.head())
title \ 0 业界:把握人工智能发展趋势 以用促建赋能高质量发展 1 深化区域交流合作 第26届青洽会将在青海西宁举办 2 张于喆 郑腾飞:加快构建多层次数据流通交易体系 3 市场监管总局公布首批商品过度包装检验检测机构名单 4 “数据要素产业服务平台(深圳试点)暨数据要素×应用场景生态实验室”合作签约仪式举行 link date \ 0 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 1 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 2 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 3 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 4 http://finance.people.com.cn/n1/2025/0519/c100... 2025-05-19 content \ 0 当前,人工智能作为引领新一轮科技革命和产业变革的技术,改变着人类的生产生活方式。如何抢抓人工... 1 “第26届中国·青海绿色发展投资贸易洽谈会(以下简称青洽会)将于至在西宁举办。”青海省人民政... 2 推动数字技术与实体经济深度融合,是建设现代化产业体系的必然要求,是践行高质量发展的重要途径。... 3 据国家市场监管总局网站消息,近日,市场监管总局印发通知,公布首批获得总局资质认定的具有商品过... 4 近日,人民网旗下人民数据公司与深圳市社会组织总会、深圳市企业联合会、会邦数据科技(深圳)有限... cleaned_content \ 0 当前 人工智能 引领 新一轮 科技 革命 产业 变革 技术 改变 人类 生产 生活 方式 抢... 1 26 届 中国 · 青海 绿色 发展 投资 贸易 洽谈会 以下 简称 青洽会 西宁 举办 青... 2 推动 数字 技术 实体 经济 深度 融合 建设 现代化 产业 体系 必然 要求 践行 高质量... 3 国家 市场监管 总局 网站 消息 近日 市场监管 总局 印发 通知 公布 首批 获得 总局 ... 4 近日 人民网 旗下 人民 数据 公司 深圳市 社会 组织 总会 深圳市 企业 联合会 会邦 ... cleaned_title main_words 0 业界 把握 人工智能 发展趋势 以用 促建 赋能 高质量 发展 [人工智能, 发展, 产业, 革命, 模型] 1 深化 区域 交流 合作 26 届 青洽会 青海 西宁 举办 [主宾, 签约, 展区, 本届, 对接] 2 张于 喆 郑 腾飞 加快 构建 多层次 数据 流通 交易 体系 [数据, 交易, 价值, 实体, 突出] 3 市场监管 总局 公布 首批 商品 过度 包装 检验 检测 机构 名单 [过度, 商品, 检验, 检测, 检验 检测] 4 数据 要素 产业 服务平台 深圳 试点 暨 数据 要素 × 应用 场景 生态 实验室 合作 ... [数据, 数据 要素, 深圳, 要素, 人民]
## LDA模型
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
import matplotlib.pyplot as plt
from matplotlib import font_manager
# 1. Sample documents in English
docs = [
"The economy is showing improvement and growth.",
"Stocks and bonds are popular investment options.",
"Economic cycles can affect the business outlook.",
"Company profits are a sign of good business health.",
"News outlets often report on market trends and cycles.",
]
# 2. Convert the documents into a document-term matrix
vectorizer = CountVectorizer(stop_words='english')
X = vectorizer.fit_transform(docs)
# 3. Fit LDA with 2 topics
lda = LatentDirichletAllocation(n_components=2, random_state=0)
lda.fit(X)
# 4. Display top words per topic
def display_topics(model, feature_names, no_top_words):
for topic_idx, topic in enumerate(model.components_):
message = "Topic %d: " % (topic_idx + 1)
message += " ".join([feature_names[i] for i in topic.argsort()[:-no_top_words - 1:-1]])
print(message)
# Print out the results
display_topics(lda, vectorizer.get_feature_names_out(), 5)
# 5. Visualize topic distribution for each document
topic_values = lda.transform(X)
# 6. Load user-provided font
# font_path = "/mnt/data/file-ngwyeoEN29l1M3O1QpdxCwkj"
# font_prop = font_manager.FontProperties(fname=font_path)
# 7. Plot
# for i, doc in enumerate(topic_values):
# plt.figure() # Each chart must be a distinct plot
# plt.bar(range(1, len(doc)+1), doc, tick_label=[f"Topic {j+1}" for j in range(len(doc))])
# plt.title(f"Document {i+1} Topic Distribution", fontproperties=font_prop)
# plt.xlabel("Topics", fontproperties=font_prop)
# plt.ylabel("Proportion", fontproperties=font_prop)
# plt.xticks(fontproperties=font_prop)
# plt.yticks(fontproperties=font_prop)
# plt.tight_layout()
# plt.show()
for i, doc in enumerate(topic_values):
plt.figure() # Each chart must be a distinct plot
plt.bar(range(1, len(doc)+1), doc, tick_label=[f"Topic {j+1}" for j in range(len(doc))])
plt.title(f"Document {i+1} Topic Distribution")
plt.xlabel("Topics")
plt.ylabel("Proportion")
# plt.xticks(fontproperties=font_prop)
# plt.yticks(fontproperties=font_prop)
plt.tight_layout()
plt.show()
Topic 1: business health sign good profits Topic 2: cycles trends report news outlets
import pandas as pd
import os
import numpy as np
import jieba
import time
from gensim import corpora
#创建文档-词矩阵 词袋模型
from gensim import corpora
from gensim.models import LdaModel
from gensim.corpora import Dictionary
merged_df = pd.read_excel("cleaned_text_xwlb.xlsx")
# 创建词典
train_set = merged_df['text'].astype(str).apply(lambda x: x.split())
# 将文本字符串转换为列表
dictionary = corpora.Dictionary(train_set)
# 创建文档-词矩阵 词袋模型
corpus = [dictionary.doc2bow(text) for text in train_set]
# 将 token2id 转换为 DataFrame
token_id_df = pd.DataFrame(list(dictionary.token2id.items()), columns=['Token', 'ID'])
print(token_id_df.head())
Token ID 0 。 0 1 一国两制 1 2 一处 2 3 一道 3 4 万众一心 4
# 保存为 Excel 文件
#token_id_df.to_excel(r"C:\Users\10283\Desktop\token_to_id_mapping.xlsx", index=False)
#print("Token to ID mapping 已保存到 token_to_id_mapping.xlsx")
from gensim.models.coherencemodel import CoherenceModel
import matplotlib.pyplot as plt
# 尝试不同的主题数量
num_topics_range = range(2, 6)
perplexity_scores = []
coherence_scores = []
for num_topics in num_topics_range:
print(f"\nTrying with {num_topics} topics:")
# 训练 LDA 模型
lda_model = LdaModel(corpus, num_topics=num_topics, id2word=dictionary, passes=20, random_state=1)
# 计算困惑度
perplexity_score = lda_model.log_perplexity(corpus)
perplexity_scores.append(perplexity_score)
# 计算一致性
coherence_model = CoherenceModel(model=lda_model, texts=train_set, dictionary=dictionary, coherence='c_v')
coherence_score = coherence_model.get_coherence()
coherence_scores.append(coherence_score)
Trying with 2 topics: Trying with 3 topics: Trying with 4 topics: Trying with 5 topics:
# 绘制曲线图
plt.figure(figsize=(10, 5))
<Figure size 1000x500 with 0 Axes>
<Figure size 1000x500 with 0 Axes>
# 绘制困惑度曲线
plt.subplot(1, 2, 1)
plt.plot(num_topics_range, perplexity_scores, marker='o')
plt.title('Perplexity vs. Number of Topics')
plt.xlabel('Number of Topics')
plt.ylabel('Perplexity')
plt.grid(True)
# 绘制一致性曲线
plt.subplot(1, 2, 2)
plt.plot(num_topics_range, coherence_scores, marker='o', color='orange')
plt.title('Coherence vs. Number of Topics')
plt.xlabel('Number of Topics')
plt.ylabel('Coherence')
plt.grid(True)
plt.tight_layout()
plt.show()
#提取主题词
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import pandas as pd
merged_df = pd.read_excel(r"cleaned_text_xwlb.xlsx")
# 假设 merged_df['text'] 包含分词后的文本数据
# 使用 CountVectorizer 创建文档-词矩阵
stop_words = ['。', '一道', '中央', '中', '中国', '今年','佳节']
vectorizer = CountVectorizer(max_df=0.95, min_df=2, stop_words=stop_words) # 可根据需求设置更多参数
X = vectorizer.fit_transform(merged_df['text'].astype(str))
# 创建 LDA 模型,提取6个主题
lda = LatentDirichletAllocation(n_components=5, random_state=42)
lda.fit(X)
LatentDirichletAllocation(n_components=5, random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
LatentDirichletAllocation(n_components=5, random_state=42)
# 提取每个主题的前200个关键词
feature_names = vectorizer.get_feature_names_out()
topic_keywords = {}
for topic_idx, topic in enumerate(lda.components_):
topic_keywords[f"Topic {topic_idx + 1}"] = [feature_names[i] for i in topic.argsort()[:-201:-1]] # 每个主题的前200个关键词
# 转换为 DataFrame 以便查看
topic_keywords_df = pd.DataFrame(dict([(k, pd.Series(v)) for k, v in topic_keywords.items()]))
topic_keywords_df
Topic 1 | Topic 2 | Topic 3 | Topic 4 | Topic 5 | |
---|---|---|---|---|---|
0 | 美国 | 发展 | 发展 | 人民 | 我国 |
1 | 表示 | 合作 | 建设 | 社会主义 | 全国 |
2 | 病例 | 经济 | 改革 | 精神 | 企业 |
3 | 俄罗斯 | 推动 | 问题 | 时代 | 增长 |
4 | 国际 | 关系 | 推进 | 同志 | 北京 |
... | ... | ... | ... | ... | ... |
195 | 连续 | 造福 | 引导 | 优秀 | 陕西 |
196 | 谴责 | 时代 | 精准 | 英雄 | 利用 |
197 | 遭到 | 致力于 | 村民 | 坚决 | 海南 |
198 | 航班 | 带来 | 需要 | 能力 | 环境 |
199 | 接种 | 开幕式 | 城乡 | 历史性 | 演出 |
200 rows × 5 columns