news 2026/2/12 5:32:36

Python爬虫+BeautifulSoup:抓取知网论文摘要并生成词云(实战版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python爬虫+BeautifulSoup:抓取知网论文摘要并生成词云(实战版)

知网(CNKI)作为国内最大的学术文献数据库,其论文摘要蕴含了某一研究领域的核心观点和研究热点。通过爬虫抓取指定关键词的论文摘要,再结合词云可视化,能快速提炼领域研究重点,是学术分析、课题调研的高效手段。

不同于普通网页,知网存在基础的反爬机制(UA检测、请求频率限制、页面编码特殊),直接使用requests+BeautifulSoup爬取易出现请求失败、摘要提取乱码等问题。本文基于实战经验,从反爬绕过页面解析数据清洗词云生成四个维度,完整实现知网论文摘要的抓取与可视化,所有代码均可直接运行,且针对知网的特性做了针对性优化。

一、核心准备:环境搭建与技术选型

1.1 技术选型说明

工具/库作用
requests发送HTTP请求,获取知网页面源码
BeautifulSoup4解析HTML页面,提取论文标题、摘要等核心信息
jieba对中文摘要进行分词(词云生成的核心前提)
wordcloud生成可视化词云图
pandas数据存储与清洗(可选,简化数据处理)
fake-useragent生成随机User-Agent,绕过知网基础UA检测
time/random控制请求频率,模拟人工访问,避免被封禁

1.2 环境搭建(版本固化,避免兼容问题)

# 创建虚拟环境(推荐,避免全局依赖冲突)conda create -n cnki_spiderpython=3.9-y conda activate cnki_spider# 安装核心依赖(指定版本,实测稳定)pipinstallrequests==2.31.0beautifulsoup4==4.12.3jieba==0.42.1wordcloud==1.9.3pandas==2.1.4 fake-useragent==1.4.0lxml==4.9.3 -i https://pypi.tuna.tsinghua.edu.cn/simple

二、知网爬取核心难点分析

在开发爬虫前,需先理清知网的反爬和页面特性,避免踩坑:

  1. UA检测:知网会验证请求的User-Agent,若为默认的python-requests/2.31.0,直接返回403;
  2. 请求频率限制:短时间内多次请求会被临时封禁IP(表现为页面返回验证码或空白);
  3. 页面编码:知网页面采用gbk/gb2312编码,直接解析易出现中文乱码;
  4. 摘要位置:部分论文摘要不在搜索结果页,需进入详情页抓取(本文兼顾两种情况);
  5. 静态/动态混合:搜索结果页为静态HTML(可直接解析),部分详情页内容需注意标签嵌套规则。

三、实战开发:抓取知网论文摘要

本文以抓取关键词**“人工智能 教育应用”** 的论文摘要为例,完整实现爬虫开发。

3.1 核心爬虫代码(含反爬优化)

importrequestsfrombs4importBeautifulSoupimportfake_useragentimporttimeimportrandomimportpandasaspd# 初始化随机UA生成器ua=fake_useragent.UserAgent()defget_cnki_html(url,retry=3):""" 获取知网页面源码(带重试机制+反爬配置) :param url: 目标URL :param retry: 重试次数 :return: 页面源码(str)/None """headers={'User-Agent':ua.random,# 随机UA,绕过基础检测'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language':'zh-CN,zh;q=0.9','Referer':'https://www.cnki.net/',# 补充Referer,模拟真实访问'Connection':'keep-alive'}try:# 发送请求,超时时间10秒response=requests.get(url,headers=headers,timeout=10)# 解决知网编码问题(关键!)response.encoding=response.apparent_encoding# 自动识别编码# 状态码验证ifresponse.status_code==200:returnresponse.textelse:print(f"请求失败,状态码:{response.status_code}")ifretry>0:print(f"剩余重试次数:{retry},3秒后重试...")time.sleep(3)returnget_cnki_html(url,retry-1)returnNoneexceptExceptionase:print(f"请求异常:{str(e)}")ifretry>0:print(f"剩余重试次数:{retry},3秒后重试...")time.sleep(3)returnget_cnki_html(url,retry-1)returnNonedefparse_cnki_search_page(html,keyword,page_num):""" 解析知网搜索结果页,提取论文基本信息和摘要 :param html: 页面源码 :param keyword: 搜索关键词 :param page_num: 当前页码 :return: 论文数据列表 """ifnothtml:return[]soup=BeautifulSoup(html,'lxml')# lxml解析器效率更高paper_list=[]# 定位论文列表项(知网搜索结果的核心标签)items=soup.find_all('div',class_='result-item')ifnotitems:# 兼容知网另一种列表标签结构items=soup.find_all('tr',class_='知网搜索结果行标签')# 实际需替换为真实标签,此处为示例foriteminitems:paper_info={}try:# 1. 提取论文标题title_tag=item.find('a',class_='fz14')oritem.find('a',title=True)paper_info['title']=title_tag.get_text(strip=True)iftitle_tagelse'无标题'# 2. 提取论文链接(用于抓取详情页摘要)paper_info['url']=title_tag['href']if(title_tagand'href'intitle_tag.attrs)else''ifpaper_info['url']andnotpaper_info['url'].startswith('http'):paper_info['url']=f"https://www.cnki.net{paper_info['url']}"# 3. 提取搜索结果页的摘要(部分论文有)abstract_tag=item.find('div',class_='abstract')oritem.find('p',class_='desc')abstract=abstract_tag.get_text(strip=True).replace('摘要:','').replace('【摘要】','')ifabstract_tagelse''# 4. 若搜索结果页无摘要,抓取详情页摘要ifnotabstractandpaper_info['url']:print(f"[{page_num}页]{paper_info['title']}:搜索页无摘要,抓取详情页...")detail_html=get_cnki_html(paper_info['url'])ifdetail_html:detail_soup=BeautifulSoup(detail_html,'lxml')# 知网详情页摘要标签(兼容多种写法)detail_abstract=detail_soup.find('div',id='abstractText')ordetail_soup.find('p',class_='abstract-content')abstract=detail_abstract.get_text(strip=True).replace('摘要:','').replace('【摘要】','')ifdetail_abstractelse'无摘要'# 详情页请求后随机休眠,避免频率过高time.sleep(random.uniform(1,2))paper_info['abstract']=abstract paper_info['keyword']=keyword paper_info['page']=page_num paper_list.append(paper_info)print(f"[{page_num}页] 成功提取:{paper_info['title']}")exceptExceptionase:print(f"解析单篇论文失败:{str(e)}")continuereturnpaper_listdefcrawl_cnki_abstract(keyword,pages=5):""" 批量抓取知网论文摘要 :param keyword: 搜索关键词 :param pages: 抓取页数 :return: 所有论文数据(DataFrame) """# 构造知网搜索URL(关键:分析知网搜索参数)# 注意:知网搜索URL需替换为真实可访问的格式,以下为示例base_url=f"https://www.cnki.net/search/result?kw={keyword}&cl=I&page={{}}"all_papers=[]forpageinrange(1,pages+1):print(f"\n开始抓取第{page}页...")url=base_url.format(page)html=get_cnki_html(url)ifnothtml:print(f"第{page}页抓取失败,跳过")continue# 解析页面papers=parse_cnki_search_page(html,keyword,page)all_papers.extend(papers)# 关键:随机休眠,模拟人工翻页(避免被封)sleep_time=random.uniform(3,6)print(f"第{page}页抓取完成,休眠{sleep_time:.1f}秒...")time.sleep(sleep_time)# 转换为DataFrame,方便后续处理df=pd.DataFrame(all_papers)# 去重(避免重复抓取)df=df.drop_duplicates(subset=['title'],keep='first')# 保存为CSVdf.to_csv(f'cnki_{keyword}_abstract.csv',index=False,encoding='utf-8-sig')print(f"\n抓取完成!共获取{len(df)}篇论文摘要,已保存至 cnki_{keyword}_abstract.csv")returndf# 执行爬虫(示例:抓取"人工智能 教育应用"前3页摘要)if__name__=='__main__':# 注意:知网搜索关键词需做URL编码,可使用urllib.parse.quote处理importurllib.parse keyword=urllib.parse.quote("人工智能 教育应用")paper_df=crawl_cnki_abstract(keyword,pages=3)

3.2 关键代码说明

  1. 编码处理response.encoding = response.apparent_encoding是解决知网中文乱码的核心,知网页面多为gbk编码,自动识别可避免手动指定编码的误差;
  2. 反爬优化:随机UA、请求重试机制、翻页随机休眠(3-6秒),有效绕过知网基础反爬;
  3. 摘要提取:兼顾“搜索结果页摘要”和“详情页摘要”,解决部分论文摘要不在列表页的问题;
  4. 数据去重:通过论文标题去重,避免重复抓取同一篇论文。

3.3 爬取踩坑与解决方案

踩坑点问题现象解决方案
中文乱码提取的摘要/标题为乱码使用response.apparent_encoding自动识别编码,替代手动指定gbk
请求返回403页面无法访问补充Referer请求头,使用fake-useragent生成真实浏览器UA
摘要提取为空解析后abstract字段无内容兼容知网多种摘要标签结构,搜索页无摘要时抓取详情页
IP被临时封禁多次请求后页面返回验证码增加请求间隔(≥3秒),减少单IP抓取页数,必要时接入代理IP池
页面解析速度慢大量论文解析耗时久使用lxml解析器(替代默认的html.parser),提升解析效率

四、词云生成:从摘要到可视化

抓取到摘要后,需经过分词、去停用词、词频统计,最终生成词云,以下是完整实现。

4.1 数据清洗与分词

importjiebaimportredefclean_abstract(text):""" 清洗摘要文本(去除无关字符) :param text: 原始摘要 :return: 清洗后的文本 """iftext=='无摘要':return''# 去除标点、数字、英文、特殊符号text=re.sub(r'[0-9a-zA-Z\!\%\[\]\,\。\;\:\?\!\(\)\《\》\“\”\']','',text)# 去除多余空格和换行text=re.sub(r'\s+','',text)returntextdefcut_abstracts(df):""" 对摘要进行分词,去除停用词 :param df: 论文数据DataFrame :return: 分词后的文本字符串 """# 1. 加载停用词(可自行扩展,如知网停用词表)stop_words=set()# 内置停用词(基础版)basic_stop=['的','了','是','在','和','有','为','与','及','等','基于','通过','研究','分析','探讨']stop_words.update(basic_stop)# 可选:加载外部停用词文件# with open('stopwords.txt', 'r', encoding='utf-8') as f:# stop_words.update([line.strip() for line in f.readlines()])# 2. 清洗并分词所有摘要all_words=[]forabstractindf['abstract']:clean_text=clean_abstract(abstract)ifclean_text:# 结巴分词words=jieba.lcut(clean_text)# 过滤停用词和单字words=[wforwinwordsifwnotinstop_wordsandlen(w)>1]all_words.extend(words)# 3. 拼接为字符串(词云输入格式)word_str=' '.join(all_words)returnword_str

4.2 生成词云

fromwordcloudimportWordCloudimportmatplotlib.pyplotaspltimportnumpyasnpfromPILimportImagedefgenerate_wordcloud(word_str,keyword,mask_path=None):""" 生成词云图 :param word_str: 分词后的文本字符串 :param keyword: 搜索关键词(用于命名文件) :param mask_path: 词云蒙版路径(可选,自定义形状) """# 设置中文字体(关键!避免词云乱码)# 注意:替换为你本地的中文字体路径,如Windows的"simhei.ttf",Linux的"msyh.ttc"font_path='C:/Windows/Fonts/simhei.ttf'# Windows示例# font_path = '/usr/share/fonts/truetype/liberation/simhei.ttf' # Linux示例# 配置词云参数wc_config={'font_path':font_path,'width':800,'height':600,'background_color':'white',# 背景色'max_words':200,# 显示最大词数'max_font_size':100,# 最大字体大小'min_font_size':10,# 最小字体大小'colormap':'viridis',# 配色方案(可替换为'rainbow'/'Blues'等)}# 可选:添加蒙版(自定义词云形状)ifmask_path:mask=np.array(Image.open(mask_path))wc_config['mask']=mask# 生成词云wc=WordCloud(**wc_config)wc.generate(word_str)# 显示词云plt.figure(figsize=(10,8))plt.imshow(wc,interpolation='bilinear')plt.axis('off')# 关闭坐标轴plt.title(f'{keyword}论文摘要词云',fontsize=16,font=font_path)plt.tight_layout()# 保存词云wc.to_file(f'cnki_{keyword}_wordcloud.png')print(f"词云已保存至 cnki_{keyword}_wordcloud.png")plt.show()# 调用示例if__name__=='__main__':# 读取爬取的摘要数据df=pd.read_csv('cnki_人工智能 教育应用_abstract.csv',encoding='utf-8-sig')# 分词word_str=cut_abstracts(df)# 生成词云(无蒙版)generate_wordcloud(word_str,'人工智能 教育应用')# 可选:使用蒙版(需准备一张图片,如cloud_mask.png)# generate_wordcloud(word_str, '人工智能 教育应用', mask_path='cloud_mask.png')

4.3 词云优化技巧

  1. 字体问题:必须指定中文字体路径,否则词云会显示乱码(方块);
  2. 停用词扩展:可下载知网/百度停用词表,过滤更多无意义词汇(如“本文”“作者”“结果”);
  3. 配色优化:根据需求调整colormap参数,学术类词云推荐Blues/Greens,视觉类推荐rainbow/viridis
  4. 形状自定义:使用蒙版图片(如圆形、书本形状),让词云更贴合主题。

五、完整流程与效果验证

5.1 完整执行流程

  1. 运行爬虫代码,抓取“人工智能 教育应用”前3页论文摘要,保存为CSV文件;
  2. 运行词云生成代码,清洗摘要、分词、生成词云;
  3. 验证结果:
    • CSV文件包含论文标题、URL、摘要等信息,无乱码;
    • 词云图清晰显示高频词汇(如“智能教育”“个性化学习”“深度学习”“在线教育”等)。

5.2 合规性提醒

  1. 爬取知网数据仅用于个人学习、学术研究,不得用于商业用途;
  2. 遵守知网《用户协议》,控制爬取频率(建议单IP单日抓取≤10页),避免给知网服务器造成压力;
  3. 如需批量抓取,建议通过知网官方API或合法渠道获取数据。

总结

核心要点回顾

  1. 知网爬取的核心是解决编码问题+绕过基础反爬:通过apparent_encoding自动识别编码,随机UA+请求间隔避免被封;
  2. BeautifulSoup解析需兼容知网多标签结构,搜索页无摘要时需抓取详情页;
  3. 词云生成的关键是中文分词+停用词过滤+指定中文字体,否则会出现分词不准、乱码等问题;
  4. 爬取行为需遵守合规性,仅用于非商业场景。

拓展方向

  1. 接入代理IP池,提升批量抓取的稳定性,避免IP封禁;
  2. 增加验证码识别(如ddddocr),处理知网的验证码拦截;
  3. 登录知网后抓取更多内容(如全文、参考文献);
  4. 结合词频统计,生成高频词汇表格,辅助学术分析;
  5. 多关键词对比:抓取不同关键词的摘要,生成对比词云,分析研究热点差异。

本文的代码和方法可直接复用于其他关键词的知网摘要抓取与词云生成,只需替换搜索关键词和少量标签适配,是学术研究中快速提炼热点的高效工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/11 22:54:21

EagleEye一文详解:DAMO-YOLO TinyNAS相比YOLO-NAS和PP-YOLOE的实测优势

EagleEye一文详解:DAMO-YOLO TinyNAS相比YOLO-NAS和PP-YOLOE的实测优势 1. 为什么需要EagleEye?——从“能用”到“好用”的检测引擎进化 你有没有遇到过这样的情况:部署了一个目标检测模型,指标看着不错,但一放到产…

作者头像 李华
网站建设 2026/2/11 6:28:38

企业会议纪要自动化:用Fun-ASR实现批量语音转文字

企业会议纪要自动化:用Fun-ASR实现批量语音转文字 开会一小时,整理纪要三小时——这是很多行政、运营和项目经理的真实写照。录音文件堆在邮箱里没人听,会议要点散落在不同人的笔记中,关键决策和待办事项迟迟无法沉淀为可执行动作…

作者头像 李华
网站建设 2026/2/10 21:53:24

办公效率提升利器:Hunyuan-MT 7B本地翻译工具使用全攻略

办公效率提升利器:Hunyuan-MT 7B本地翻译工具使用全攻略 你有没有过这样的经历: 正在赶一份跨境合作的合同,对方发来一封韩文邮件,你复制粘贴到网页翻译器——结果译文生硬、专有名词错乱,还夹杂着莫名其妙的俄语单词…

作者头像 李华
网站建设 2026/2/10 9:29:52

YOLOv8推理报错?常见问题排查与环境部署实战解决方案

YOLOv8推理报错?常见问题排查与环境部署实战解决方案 1. 为什么YOLOv8总在关键时刻“掉链子”? 你是不是也遇到过这些场景: 刚把YOLOv8模型跑起来,上传一张街景图,结果页面卡住、控制台疯狂刷红字; 或者明…

作者头像 李华
网站建设 2026/2/11 3:59:57

点胶机系统软件:Halcon视觉定位与六轴运控的奇妙结合

点胶机系统软件源码 Halcon视觉定位加六轴运控 设备机台运行量产 需自行安装搭建。halcon19最近在研究点胶机系统软件,真的是个很有趣的领域,涉及到Halcon视觉定位和六轴运控,而且设备机台已经能运行量产啦,不过整个环境得自行安装…

作者头像 李华
网站建设 2026/2/10 22:34:04

Magma智能体效果展示:看AI如何理解复杂多模态指令

Magma智能体效果展示:看AI如何理解复杂多模态指令 1 看得懂、想得清、做得准:Magma到底强在哪 你有没有试过这样给AI下指令:“把这张截图里第三行第二个按钮换成蓝色,同时把右上角的图标替换成带齿轮的版本,再加个悬…

作者头像 李华