Python+selenium+Xpath爬取百度学术文章摘要


由于研究需要,想要用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篇文章,每篇文章给出了摘要、作者、被引量、来源等信息。1
我的目标是摘要,但是可以看到这个页面中文章摘要是不全的,超出的部分被省略了,所以这个页面的内容还达不到我的要求。需要进一步进入每篇文章的详情页面,点开一篇文章,可以看到文章信息如下图:
2对了,再看一下每篇文章对应的详情链接,等下会用到。
3
这下摘要就全部显示了,再来查看一下摘要对应的HTML元素在哪,F12查看一下。好了,就是这个

标签了,目标已经明确了,准备代码了。
4

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() # 关闭浏览器

说一下遇到的几个问题 :

  1. 翻页:搜索出的文章页面,每页只有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值得到后续页面。
  2. 摘要缺失:发现有些文章百度学术中没有给出摘要,直接提取会报错,因为这些文章没有摘要对应的HTML标签。所以在代码中捕获了selenium对应的异常,跳过异常继续提取。

参考

[1] selenium-python中文文档

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Growing_Snake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值