由于研究需要,想要用Glove训练一些自己的领域语料,可是没有现成的语料,所以想着找一些相关文献的摘要作为语料,但总不能自己去找吧~带着万分的不情愿,硬着头皮学着爬一下百度学术吧(观察了几个网站发现这个最好爬,对不住了)…接触爬虫不多,大佬们有好的建议请不吝赐教
1. selenium简介
据官网介绍,Selenium 直接在浏览器中运行,就像真实用户所做的一样。Selenium 测试可以在 Windows、Linux 和 Macintosh上的 Internet Explorer、Chrome和 Firefox 中运行。
使用Selenium通过编写模仿用户操作的测试脚本,可以从终端用户的角度来测试应用程序。通过在不同浏览器中运行测试,更容易发现浏览器的不兼容性。Selenium 的核心,也称browser bot,是用 JavaScript 编写的。这使得测试脚本可以在受支持的浏览器中运行。browser bot 负责执行从测试脚本接收到的命令,测试脚本要么是用 HTML 的表布局编写的,要么是使用一种受支持的编程语言编写的。
当然,这些对我们来说没啥意思,看看就好。在爬虫这里,我觉得最大的好处就是自动化运行。
1.1 安装
不用多说,python中直接pip就好
pip install selenium
浏览器我使用的是Chrome,驱动下载链接Chrome驱动 可以找对应自己Chrome版本的驱动下载。
另外,提供几个常用浏览器的驱动下载地址:
Firefox浏览器驱动:Firefox驱动下载
Edge浏览器驱动:Edge驱动下载
1.2 基本操作
首先通过浏览器驱动打开所需的链接;然后,根据自己的需求获取网页的信息,selenium-python提供了多种方式,包括根据id、name、classname等方式,另外还有根据xpath获取的方式,可以根据需求使用不同的方式获取网页信息。下面是一个简单的示例,详细操作这里提供一篇别人写的中文文档[1],这篇文档里也提供了不同浏览器驱动的API。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome() # 此处的浏览器驱动可以根据自己的浏览器类型替换,下载相应的浏览器驱动就好
driver.get("http://www.python.org") # 打开想要爬取的网页链接,这里会自动通过浏览器打开页面
assert "Python" in driver.title
elem = driver.find_element_by_id("q") # 根据id获取标签元素
elem.text # 获取标签的文本
assert "No results found." not in driver.page_source
driver.close()
2. 爬取百度学术文章摘要
2.1 爬取页面分析
先来看一下,以某一关键字搜索后的文章列表页面如下图所示,每页有10篇文章,每篇文章给出了摘要、作者、被引量、来源等信息。
我的目标是摘要,但是可以看到这个页面中文章摘要是不全的,超出的部分被省略了,所以这个页面的内容还达不到我的要求。需要进一步进入每篇文章的详情页面,点开一篇文章,可以看到文章信息如下图:
对了,再看一下每篇文章对应的详情链接,等下会用到。
这下摘要就全部显示了,再来查看一下摘要对应的HTML元素在哪,F12查看一下。好了,就是这个
标签了,目标已经明确了,准备代码了。
2.2 Python+selenium爬取
直接点,给出我的完整代码,因为需求比较简单明了,所以代码也写的简单,能完成我需要的功能就行。
'''
@File : baiduxueshu_crawl.py
@Contact : nc514819873@qq.com
@Desciption: 爬取百度学术文章摘要
@Modify Time @Author @Version @Desciption
------------ ------- -------- -----------
2019/11/20 15:12 NiuChen 1.0 None
'''
import time
import pandas as pd
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
options = webdriver.ChromeOptions()
options.add_argument('User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36')
def page_url_list(page=40):
"""
:param page: 要爬取的页数(大于1)
:return: 要爬取的所有页面的链接地址列表
"""
fir_page = browser.find_element_by_xpath('//a[@class="n"]').get_attribute('href') # 搜索后的第一页文章列表的链接
urls_list = []
for i in range(page):
next_page = fir_page.replace("pn=10", "pn={:d}".format(i * 10)) # 替换链接中的pn值
urls_list.append(next_page)
return urls_list
def get_abstract():
"""
获取每篇文章的摘要
:return: 所有文章摘要组成的列表
"""
article_links = []
for i in browser.find_elements_by_xpath('//h3[@class="t c_font"]/a'):
# print(i.get_attribute('href'))
article_links.append(i.get_attribute('href')) # 将搜索的文章列表页面中的每篇文章的详情链接加入到列表中
# ActionChains(browser).click(i).perform() # 模拟点击,进入一篇文章的详情页面
# time.sleep(3) # 等待3秒页面加载
abstracts = []
for i in article_links:
browser.get(i)
browser.implicitly_wait(5)
try:
abstract = browser.find_element_by_xpath("//p[@class='abstract']") # 找到摘要对应的标签
if abstract:
abstracts.append(abstract.text) # 取出摘要标签对应的内容
# 将提取到的摘要存入txt文件中
with open('abstracts_test.txt', 'a', encoding='utf8') as abs_doc:
abs_doc.write(abstract.text)
print('获取到一篇摘要')
except NoSuchElementException:
print("该文章没有摘要")
pass
continue
return abstracts
browser = webdriver.Chrome('D:\\chromedriver.exe') # 使用浏览器驱动打开浏览器
# 打开要爬取的页面
browser.get('http://xueshu.baidu.com/s?wd=AlSi%20alloy&'
'tn=SE_baiduxueshulib_9r82kicg&sc_f_para=sc_tasktype%3D%7BfirstSimpleSearch%7D&'
'sc_hit=1&sc_as_para=sc_lib%3Akmust&bcp=2&ie=utf-8&sc_from=kmust&filter=sc_type%3D%7B1%7D')
browser.implicitly_wait(5) # 等待页面加载完成
urls_list = page_url_list()
abstracts = []
count = 0
# 循环获取每页所有文章的摘要
for i in urls_list:
browser = webdriver.Chrome('D:\\chromedriver.exe')
browser.get(i)
browser.implicitly_wait(10)
abstract = get_abstract()
count += 1
print("----------------完成第 %d 页-----------------" % count)
abstracts.append(abstract)
time.sleep(5)
# 下面使用pandas将获取到的摘要保存到csv格式文件中,方便后续处理
csv = []
for i in abstracts:
for j in i:
csv.append(j)
pd_abstract = pd.DataFrame(csv, columns=['abstract'])
pd_abstract.to_csv('abstracts.csv', encoding='utf8')
print('当前页面全部获取完成')
print('摘要篇数:', len(csv))
time.sleep(5)
browser.close() # 关闭浏览器
说一下遇到的几个问题 :
- 翻页:搜索出的文章页面,每页只有10篇,肯定是不够的,所以需要想办法获取后续页面的链接。观察页面的链接,可以看到百度学术的每页链接只有一个参数不一样,那就是pn值(如:http://xueshu.baidu.com/s?wd=AlSi%20alloy&pn=10&tn=SE_baiduxueshu_c1gjeupa&ie=utf-8&sc_f_para=sc_tasktype%3D%7BfirstSimpleSearch%7D&sc_hit=1),模拟点击翻页比较麻烦,所以我直接通过替换pn值得到后续页面。
- 摘要缺失:发现有些文章百度学术中没有给出摘要,直接提取会报错,因为这些文章没有摘要对应的HTML标签。所以在代码中捕获了selenium对应的异常,跳过异常继续提取。