python爬取谷歌学术参考文献的BibTex格式——基于selenium
背景进行Latex写作时,当要引用文献,需要根据文章名,一个一个去谷歌学术搜索,找到BibTex,再复制进bib文件里,耗费大量时间和精力。图1.传统方法,通过搜索谷歌学术引用参考文献这样枯燥重复的工作完全可以交给机器。网络上搜索“谷歌学术bib参考文献爬虫”,只有被引数量统计、根据关键词寻找文章等方案,并没有针对该问题的方法,故有此文。爬虫由于某种原因,我们用镜像代替谷歌学术:熊猫学术分析原网页
1.背景
进行Latex写作时,当引用文献,需要根据文章名,一个一个去谷歌学术搜索,找到BibTex,再复制进bib文件里,耗费大量时间和精力。
这样枯燥重复的工作完全可以交给机器。
网络上搜索“谷歌学术bib参考文献爬虫”,只有被引数量统计、根据关键词寻找文章等方案,并没有针对该问题的方法,故有此文。
2.思路
机器本质上是模仿人的行为,人为查找参考文献的流程:
因此,我们需要一个具有点击功能的爬虫,把弹窗点出来,再根据弹窗中的链接获取新窗口的文本。
搜索得知python的selenium库具有点击功能。
3.实验
由于某种人尽皆知的原因,我们用镜像代替谷歌学术:熊猫学术
但这个网址很不稳定,经常会失败,有更好的可以替换之,本文仅作示例。
3.1搜索
从最基本的一篇文章开始。当我们搜索文章:
From Arguments to Key Points: Towards Automatic Argument Summarization
发现网址格式如下:
https://sc.panda321.com/scholar?q=From+Arguments+to+Key+Points%3A+Towards+Automatic+Argument+Summarization
文章名的空格被替换成了+号,冒号则是%3A,这种替换方式可以使用urllib的parse。
from urllib import parse
url = 'https://sc.panda321.com/'
q = 'From Arguments to Key Points: Towards Automatic Argument Summarization'
params = {
'q':q
}
params = parse.urlencode(params)
urlNow = "https://sc.panda321.com/scholar?" + params
urlNow 就是这篇文章的网址。
3.2点击
pip好selenium以及相应的驱动,详见Selenium+Firefox/Chrome及驱动的安装和使用(注意:anaconda用户需把驱动放在anaconda的根目录)
以Firefox为例,得到该文章的网页:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('-headless')
driver = webdriver.Firefox(options=options)
driver.get(urlNow)
引用标志右键检查,是一个svg格式的图片,而它的js动作被写在上一行class
名为gs_or_cit gs_nph
的a标签里:
根据class名找元素,用到find_element_by_class_name方法,点他!:
#空格需要用.代替
driver.find_element_by_class_name('gs_or_cit.gs_nph').click()
3.3获取链接
我们先看看人为会点出来什么:
Yes!bib的网址就在这个class
名为gs_citi
的href
里,马上成功了!
看一下机器点出来的:
#查找gs_citi
driver.find_element_by_class_name('gs_citi')
What?居然没有?
在怀疑和自我怀疑当中,我体会到了生命的短暂,时间的流逝。对,就是时间。注意到点击时加载非常慢,等待很久才显示弹窗,那我们试试主动模拟等待时间:
time.sleep(4)
再找找,出现了!有四个gs_citi
,我们只需要BibTeX的href:
s = driver.find_element_by_class_name('gs_citi')
if s.text == 'BibTeX':
hr = s.get_attribute('href')
3.4获得BibTeX
根据上面得到的href,再获取页面显示的全部内容就可以了:
driver.get(hr)
bib = driver.find_element_by_xpath("//*").text
driver.quit()
记得.quit()退出驱动,不然数据量大的时候吃内存。
4.总结
抽象成方法以便循环利用,整体代码如下:
from urllib import parse
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
def paperUrl(name):
q = name
params = {
'q':q
}
params = parse.urlencode(params)
url = "https://sc.panda321.com/scholar?" + params
return url
def getBib(url):
options = Options()
options.add_argument('-headless')
driver = webdriver.Firefox(options=options)
driver.get(url)
driver.find_element_by_class_name('gs_or_cit.gs_nph').click()
time.sleep(4)
s = driver.find_element_by_class_name('gs_citi')
if s.text == 'BibTeX':
hr = s.get_attribute('href')
driver.get(hr)
bib = driver.find_element_by_xpath("//*").text
driver.quit()
return bib
if __name__ == '__main__':
q = 'From Arguments to Key Points: Towards Automatic Argument Summarization'
url = paperUrl(q)
bib = getBib(url)
当有多篇文章需要查,则q可为一个列表,再一个循环把得到的bib添加到列表中即可。
作为初学者,代码本身还有很多不足,欢迎各位大佬指教!
更多推荐
所有评论(0)