社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python: 批量爬取下载中国知网(CNKI) PDF论文

连享会 • 3 月前 • 548 次点击  


👇 连享会 · 推文导航 | www.lianxh.cn


🍓 课程推荐:连享会:2025生成式人工智能专题·网络直播
嘉宾:杨阳 (香港浸会大学)
时间:2025 年 9 月 13, 14, 20 日
咨询:王老师 18903405450(微信)



作者:左从江
邮箱:zuocj9700@163.com


温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:


目录


  • 1. 总体思路

  • 2. 解析前奏:获取页面的 html

  • 3. 解析

  • 4. 下载论文的代码





这篇文章介绍获取 PDF 格式的论文。

在知网页面的 html 中有下载链接,复制到搜索栏,确实是可以下载论文的,只需要获得作者,时间,题目以及下载链接就可以用循环结构批量下载论文。

当然前提是,您本来就可以下载论文,不管是用 VPN 还是校园网。

爬取网页后,只需要解析出来即可。我选择的方法是 正则搜索,虽然有点笨拙,但好在不管是什么信息,只要想搜索,总可以搜索到。


1. 总体思路

首先,获取源码,库:selenium,time ,用 webdriver 搜索按钮和输入栏,提交等等,遇到验证码手动输入即可,笔者输入了 8 次验证码,获取 6000 条论文
其次,从源码中解析出作者,时间,Title,下载链接,储存到 Excel 中留存,日后可能有用,用到 re,pandas
再次,利用 pandas,读取论文的链接,Title,用 requests 获取论文,利用 open 函数储存到 PDF 格式,在实践中发现,如果直接用解析的链接获取,下载得到的往往是 caj 格式文件,但是把 url 中的 ';' 换为 '&' 就可以正常下载 PDF 格式的文件了。用到 re,pandas
有了总的思路,相信各位也可以自己写出定制的爬虫


2. 解析前奏:获取页面的 html

from selenium import webdriver
import time
import pandas as pd

url = r'http://new.gb.oversea.cnki.net/kns/brief/result.aspx?dbprefix=CJFQ'#给出链接
driver = webdriver.Firefox()
driver.get(url)

blank_ISSN = driver.find_element_by_id('magazine_value1')
#找到输入框。  id是我手动打开html,查看输入框源代码找到的,想提交别的条件一样操作即可

blank_ISSN.send_keys('0577-9154'#输入内容,期刊得SSN号码
buttom_search = driver.find_element_by_id('btnSearch'#找到搜索按钮
buttom_search.click() #点击搜索

time.sleep(2#停一小会儿

driver.switch_to.default_content()  #找到子页面
driver.switch_to.frame('iframeResult')  #切换到iframe

#选择50个论文在一面显示
button_50=driver.find_element_by_xpath(r'/html/body/form/table/tbody/tr[1]/td/table/tbody/tr[1]/td/table/tbody/tr/td[2]/div[2]/a[3]')
button_50.click()

htmls = []  #遍历所有子页面,储存到这个列表
b = 1      #
whileTrue:
    try:
        soup = BeautifulSoup(driver.page_source,'html.parser')
        htmls.append(soup)
        #储存好,点击下一页
        time.sleep(random.randint(3,6))  #暂停一小会儿,这样封IP的概率会小一点,也少输入几次验证码
        button_next = driver.find_element_by_id('Page_next')
        button_next.click()

    except  :
        print('Error{}'.format(b))
        time.sleep(60)
        b = b+1


3. 解析

一个 tr 标签的结构如下,其包含了一篇文章的全部信息:

在这里插入图片描述
transfer_list=[]   #存储html源码的中转列表
for soups in htmls:
    text = str(soups)
    for i in soups.find_all( 'tr')[7:57]:   #在soup搜索出来的tr标签中,列表头尾都有冗余信息,删掉不要
        transfer_list.append(i)

len(htmls)  #看一下爬出来多少的html,我的结果是135个html页面

raw_paper_infos = []  #用re匹配的思路是,第一步先缩小范围,第二步,精确搜索并删除多余的字符,下面是第一步
for i in transfer_list:    #遍历transfer_list中的每一个tr标签,其结构:[[一个tr标签包含的源码],[].……]
    o=[]  #中转列表,储存第一步搜索出来的title,authors,发布时间,下载链接四个大致的匹配结果
    paper = str(i)   #下面正则的表达式,都是我自己试出来的,有更好的方法欢迎留言
    title = re.findall('target="_blank">.*',paper)
    authors = re.findall('target="knet">.*',paper)
    pub_year = re.findall('....-..-..',paper)
    download_url = re.findall('briefDl_D" href=".*PDFdown',paper)
    quoted_num1 = re.findall('scrollbars=yes.*,paper)
    download_num = re.findall('onclick="SubCountDownLoad.*',paper)
    o=[title,authors,pub_year,download_url,quoted_num1,download_num]
    raw_paper_infos.append(o)  #初步储存了全部的搜索信息

初步搜索出来的结果如下:

raw_paper_infos[7]   #结构:[[trs],[],……]
[['target="_blank">消费行为在个人信用风险识别中的信息含量研究'],
 ['target="knet">王正位; 周从意; 廖理; 张伟强'],
 ['2020-01-16'],
 ['briefDl_D" href="../download.aspx?filename=4kXaYNFW0VEa4UzTFZXdJVlSvB3cHdXWrU0cKZ0VXllatB3ZaZVeUdESlxEePJHV3clQuVneGNkQSRXSKdHMvklS6Vzbv9WVwQWaENTdXJ0aOpFd4FzUSRGd3okW0Z1dx90SGljM5JVRwczRTdnSVl3Z3ImMrlVM&tablename=CAPJLAST&dflag=PDFdown'],
 [],
 ['onclick="SubCountDownLoad(0,this)">264']]

接下来继续完成匹配工作:精确匹配和删除多余字符:

papers = []   #干净的匹配结果存放处
ilegal_word = ['/','\',''',':','|','?','*']   #考虑到后续下载时,保存文件会有一些非法字符导致文件名生成失败(windows不允许这些字符出现在文件名中)
for i in raw_paper_infos:
    ifnot i == [[], [], [], [], [], []]:   #初步搜索时候,会有一些tr标签不是我们的论文标签,不符合初步搜索的要求,其结果就是空列表,过滤掉
        raw_title = i[0][0].strip('target="_blank>~')
        chars = []
        for x in raw_title:
            ifnot x in ilegal_word:
                chars.append(x)
        title2 = ''.join(c for c in  chars)
        authors2 = ','.join(j for j in re.findall('[\u2E80-\u9FFF]+',str(i[1])))   #在join里面加一个符号就可以用这个符号链接加入进来的各个str了,nice try!
        pub_year2 = i[2][0]
        download_url2 = (i[3][0].strip('briefDl_D" href="..')).replace(';','&')   #按照';'连接就是caj格式的,'&'连接就是PDF格式的
        if i[4] == []:
            quoted_num2 = int(0)
        else:
            quoted_num2 = int(re.findall(r'>.*,str(i[4][0]))[0].strip('>))
            #被引次数对于发表不久的论文,可能没有这一项,所以对于没有这一项的给0

        download_num2 = int(re.findall(r'>.*,i[5][0])[0].strip('>))  #论文得下载次数
        papers.append([title2,authors2,pub_year2,download_url2,quoted_num2,download_num2])

#到此为止,我们有了全部的所需要的信息
#储存到excel,以待候用
pd.DataFrame(papers).to_excel(root+r'\JJYJ论文信息汇总.xlsx')

输出的 Excel 文档长这样:

:和代码部分有一点不一样,笔者自行输入了标题行,并且按照发表日期排序

在这里插入图片描述

注意: 下载链接不完整,下载时需要在前面加:http://new.gb.oversea.cnki.net/kns 。


4. 下载论文的代码

import pandas as pd
import requests,os

content = pd.read_excel(content_JJYJ)
#读取excel
content = content.drop(columns = ['Unnamed: 0','作者','被引次数','下载次数', '截止日期:2020-2-6',"要下载论文,链接前接:'http://new.gb.oversea.cnki.net/kns'"])
#只保留title和下载链接,其余删掉

for i in range(len(content['题目'])):   #这是DataFrame中列的访问方式
    title = content['题目'][i]  #第i篇论文的题目
    text = requests.get(content['下载链接'][i]) #下载第i个论文
    with open(root + '\\' + title + '.PDF' ,'wb'as f:  #给出保存地址以及open的模式是wb,写入字节
        #因为下载的是字节,所以写入字节:wb
        f.write(text.content)
        f.close()

    size = float(os.path.getsize(save_path))
                kb = size/1024                 #判断是不是下载成功了,小于7字节应该就是没下载到论文而是别的东西
                if kb<7:
                    os.remove(save_path) #如果是,删除,以备后面重新下载
                    print('封IP了,暂停10min')
                    exceptions.append(paper)
                    time.sleep(300)  #下载失败的原因是封ip了,这时候暂停5-10min比较好


下载论文的主体部分就是这些了,后面可以加入 try/except 结构、跳过已经下载的论文等功能,但是程序主体就是这些,文章已经很长,再长不大好,所以写到这里,更多功能请大家依据需求添加。



🍓 课程推荐:连享会:2025政策优化和机制分析专题
嘉宾:杨海生教授,中山大学
时间:2025 年 8 月 20-22 日
地点:东南大学榴园会议中心 (南京市玄武区进香河路38号)
咨询:王老师 18903405450(微信)

连享会微信小店上线啦!

Note:扫一扫进入“连享会微信小店”,你想学的课程在这里······

New! Stata 搜索神器:lianxh 和 songblGIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉  使用:
. lianxh DID 倍分法
. songbl all


🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下:连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/185580