查看原文
其他

中国知网爬虫(CNKI) 批量下载PDF格式论文

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:左从江(投稿)

文字编辑:钱梦璇

技术总编:张   邯
本文介绍如何获取知网高级搜索后的论文详细信息。
在知网页面源码中包含下载链接,将之复制到搜索栏,确实能够下载论文,因此只需要获得作者、时间、题目以及下载链接就可以用循环结构批量下载论文。
需要注意的是,这里要求原本您就可以从知网下载论文,无论通过VPN还是校园网。

总思路



首先,获取源码,涉及库:selenium,time。通过webdriver搜索按钮和输入栏,通常用requests无法获得包含论文信息的源码,其原因是知网的查询页面嵌套了一个子页面(iframe),requests请求得到的只是父页面。

其次,从源码中解析出作者、时间、Title以及下载链接,并储存到Excel中留存,其中涉及库re和pandas.


获取网页源码 

 


from selenium import webdriverimport timeimport pandas as pdfrom bs4 import BeautifulSoupimport random
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是在源码中搜索而来blank_ISSN.send_keys('0577-9154') #输入内容,期刊的ISSN号码buttom_search = driver.find_element_by_id('btnSearch') #找到搜索按钮buttom_search.click() #点击搜索
time.sleep(2) #停一小会儿driver.switch_to.default_content() #找到iframe子页面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 while True: try: soup = BeautifulSoup(driver.page_source,'html.parser') htmls.append(soup) #储存完成,点击下一页 time.sleep(random.randint(3,6)) #暂停3~6s,这样封IP概率更小 button_next = driver.find_element_by_id('Page_next')        button_next.click()      except : print('Error{}'.format(b)) time.sleep(60) b = b+1

提交请求时,可能遇到输入验证码的情况,手动输入即可,笔者输入了8次验证码,获取到6000条论文信息。

需要注意的是,每次知网只能给出6000条信息,但如下,共检索到8129条结果。此时可以通过限定时间范围将检索结果数量限制在6000条以内,就可以保证获取到全部的结果了。


进行解析 

 


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

transfer_list=[] #存储html源码的中转列表for soups in htmls: for i in soups.find_all('tr')[7:57]: #在soup搜索出来的tr标签中,列表头尾都有冗余信息,删掉不要 transfer_list.append(i)
raw_paper_infos = [] #使用正则匹配的思路:第一步,缩小信息所在的范围;第二步,精确搜索并删除多余的字符。下面进行第一步for i in transfer_list: #遍历transfer_list中的每一个tr标签,其结构:[[一个tr标签包含的源码],[].……] paper = str(i) title = re.findall('target="_blank">.*</a>',paper) authors = re.findall('target="knet">.*</a>',paper) pub_year = re.findall('....-..-..',paper) download_url = re.findall('briefDl_D" href=".*pdfdown',paper) quoted_num1 = re.findall('scrollbars=yes.*</span',paper) download_num = re.findall('onclick="SubCountDownLoad.*</a>',paper)   raw_paper_infos.append([title,authors,pub_year,download_url,quoted_num1,download_num])  #储存了初步的匹配结果

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

papers = [] #用于存放最终干净的匹配结果illegal_word = ['/','\',''',':','|','?','*'] #考虑到后续下载时,保存文件时会有一些非法字符导致文件名生成失败(windows不允许这些字符出现在文件名中)for i in raw_paper_infos: if i!=[[], [], [], [], [], []]: #初步搜索时候,会有一些tr标签不是我们的论文标签,不符合初步搜索的要求,其结果就是空列表,通过判断过滤掉 title2 = i[0][0].strip('target="_blank>~</a>') for x in illegal_word: title2.replace(x,"") authors2 = ','.join(j for j in re.findall('[\u2E80-\u9FFF]+',str(i[1]))) 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'>.*</a',str(i[4][0]))[0].strip('></a')) #被引次数对于发表不久的论文,可能没有这一项的数据,因此对于匹配不到的赋值0
download_num2 = int(re.findall(r'>.*<',i[5][0])[0].strip('><')) #论文得下载次数 papers.append([title2,authors2,pub_year2,download_url2,quoted_num2,download_num2])

到此为止,我们有了全部所需要的论文信息。

#储存到excelpd.DataFrame(papers).to_excel(r'.\JJYJ论文信息汇总.xlsx')

上述结果的Excel截图:

(注:和代码部分略有不同,笔者自行输入了标题行,并且按照发表日期排序)

注意:如上图所示,Excel表中的下载链接是不完整的,下载时需要在前面加上:http://new.gb.oversea.cnki.net/kns.

到此为止,就得到了每篇文章的信息,可利用request库请求链接,下载论文,利用open函数储存到pdf格式。在实践中发现,如果直接用解析的链接获取,下载得到的往往是caj格式文件,但是把链接中的“;”换为“&”就可以正常下载pdf格式的文件了。






对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐

sencode命令介绍

Ftools命令组之fisid命令和fsort命令介绍

“抽丝剥茧”,层层下分——机器学习基本算法之决策树

爬取东方财富网当日股票交易情况

stata调用python爬取时间数据——借他山之石以攻玉

全国31省GDP排行强势登场!
接力《发哨子的人》Stata版
批量实现WORD转PDF

Stata有问必答环节

我听到了企业的哀鸣
“物以类聚”、“近朱者赤”——机器学习初探之KNN
SFI:Stata与Python的数据交互手册(二)

从流调数据中寻找感染真相

熟悉又陌生的reshape

NBA球员薪资分析——基于随机森林算法(二)

NBA球员薪资分析——基于随机森林算法(一)

高亮输出之唐诗作者

湖北省各市疫情数据爬取

关于我们



微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存