今天使用python来爬取百度学术的论文信息,并且增加了简单的可视化功能,主要内容有:
- 1、爬取百度学术上论文信息(主要用到requests库,bs4库中BeautifulSoup模块,pandas,re等)
- 2、使用tkinter构建GUI,显示爬取的论文信息
- 3、对爬取的数据进行可视化,进行词云展示
可以在小窗口中输入检索信息(这里输入了检索词:图像重建、深度学习,没有选择输入作者和机构):
GUI图像如下(界面很丑,只能靠初音撑颜值了):
使用词云(用的一只小狗,应该还挺可爱)展示的关键词:
对爬取到的论文的发表时间进行了统计,使用柱状图展示:
一、爬取论文
爬取思路:
主要使用了requests库、bs4里面的BeautifulSoup和re模块
- 准备工作(剩下的关注后续博文)
- 获取数据
- 解析数据
- 保存数据
个人认为思路很简单,就是和我们手动去网上找信息类似(找到网址->进入网页->查找信息):
a. 给定一个url,使用req = requests.get()函数获取网页信息,然后使用req.text返回解码后的网页信息(如果使用requests.get().content返回的是字节)
b. 使用正则表达式对获取的网页信息进行匹配,获取自己需要的内容。
c. 保存数据
(1)准备工作
在这一部分先弄清楚准备爬取的网页以及需要在网页上寻找哪些信息!
百度学术的网址为:https://xueshu.baidu.com
进行高级检索时(假设只使用三个信息进行检索):检索词+作者+机构名称
url可以写为:https://xueshu.baidu.com/s?wd=关键词+author作者+affs%3A%28机构名称%29 (这个东西怎么得到的?很简单)
1) 进入百度学术页面
首先打开百度学术的页面,发现最上面的网址是https://xueshu.baidu.com。
2)进入检索后的页面
然后我们选择高级检索,在全部检索词、作者、机构三个位置分别输入图像重建、陈达、南京航空航天大学,如下图所示:
3) 点击搜索后会跳转页面,如下图所示,关注一下最上面的https://那一行,观察一下和最开始https://xueshu.baidu.com的区别,可以发现就是在后面加了一点内容,可以换几个检索词试试,很快就能找到规律,https://xueshu.baidu.com/s?wd=关键词+author作者+affs%3A%28机构名称%29,也可以自己把这一串东西里面的关键词、作者、机构改了,然后用浏览器搜索,试试能不能跳转到百度学术的页面。
我们需要爬取的页面是 https://xueshu.baidu.com/s?wd=关键词+author作者+affs%3A%28机构名称%29 这个,而不是https://xueshu.baidu.com/s。
4)输入检索词后跳转的页面有很多论文,然后我们需要点击标题,进入每一个论文的界面,如果是使用爬虫的话,我们就需要知道每一个论文页面的链接是什么
在上一个图的界面中,可以使用快捷键(Ctrl+Shift+I),然后出现下面这个图的界面。
然后可以在右边找到下面红色框里的这个,在这个页面要做的就是找到每一个论文页面的链接,可以使用下面的方法获取每一个论文页面的链接,其中content是使用requests.get().text()返回的网页内容。
# 获取每一个文章的链接
soup = BeautifulSoup(markup=content, features='lxml')
urls_list = soup.find_all('a', href=re.compile('^//xueshu.baidu.com/usercenter/paper'))
通过上一步得到的链接(需要在前面加上https:),我们可以进入每一个论文的界面,如下所示:
我们需要从界面中爬取的信息有:标题、作者、摘要、关键词、DOI、被引量、年份。同样使用Ctrl+Shift+I进入开发者工具,选择元素一项,然后在里面找到要爬取的信息,如需要寻找标题,使用正则表达式对content进行匹配即可,具体操作后续再讲。
B站上有个爬虫实战的教程,把爬虫的流程讲的很详细:https://www.bilibili.com/video/BV12E411A7ZQ?p=16
累了…
先直接贴出代码吧,后续再进行分析。
主要分为3个模块,一个是爬虫模块,一个是构建GUI模块,一个是数据可视化模块。爬虫模块中导入了GUI模块和可视化模块,在爬虫模块中运行三个模块。
(一)爬虫模块代码
# -*- codeing = utf-8 -*-
# @Time :2021/6/28 22:03
# @Author: wangyuhan
# @File :BaiduScholar.py
# @Software: PyCharm
'''
一、
检索通式:
百度学术网址:https://xueshu.baidu.com
高级检索:检索词+作者+机构名称
https://xueshu.baidu.com/s?wd=关键词+author作者+affs%3A%28机构名称%29
二、
匹配规则:使用bs4.BeautifulSoup, lxml库进行解析
匹配href=re.compile('^//xueshu.baidu.com')
三、
分析页面:(需要注意:可能有些资料是图书,没有摘要,则跳过)
作者:re.compile('"{\'button_tp\':\'author\'}">(.*?)</a>')
摘要:re.compile('<p class="abstract" data-sign="">(.*?)</p>')
关键词:re.compile('target="_blank" class="">(.*?)</a></span>')
DOI: re.compile('data-click="{\'button_tp\':\'doi\'}">\s+(.*?)\s+</p>')
被引量:re.compile('"{\'button_tp\':\'sc_cited\'}">\s+(\d+)\s+</a>')
年份:re.compile('<p class="kw_main" data-click="{\'button_tp\':\'year\'}">\s+(\d+)\s+</p>')
标题:re.compile('"{\'act_block\':\'main\',\'button_tp\':\'title\'}"\s+>\s+(\S+)\s+</a>')
四、
不爬取图书,若匹配不到摘要,则放弃该文献
爬虫思路:
1、爬取网页
2、解析数据
3、保存数据
'''
from bs4 import BeautifulSoup
import re
import requests
import os
import pandas as pd
import sys
import random
import time
# 导入自定义模块(GUI组件)
import WindowShow
import DataVis
class Crawler_Paper():
'''百度学术爬虫类'''
def __init__(self):
self.base_url = 'https://xueshu.baidu.com'
self.header = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
self.paper_num = 1
self.data = pd.DataFrame() # 用于保存文献信息
def input_message(self, url):
'''
输入检索信息,并且修改url
:param url: 待爬网址
:return x_url: 返回修改后的url,进行了关键词、作者和机构检索
'''
try:
s = input('是否输入检索词(y/n,不区分大小写)>')
if s == 'y' or s =='Y':
keyword = input('检索词>')
x_url = url + '/s?wd=' + keyword
elif s !='n' and s != 'N':
print('Input Error!')
sys.exit('Goodbye!')
a = input('是否输入作者(y/n,不区分大小写)>')
if a == 'y' or a == 'Y':
author = input('作者>')
x_url = x_url + 'author' + author
elif a !='n' and a != 'N':
print('Input Error!')
sys.exit('Goodbye!')
af = input('是否输入机构(y/n,不区分大小写)>')
if af == 'y' or af =='Y':
affs = input('机构>')
x_url = x_url + 'affs%3A%28' + affs + '%29'
elif af != 'n' and af != 'N':
print('Input Error!')
sys.exit('Goodbye!')
# 返回修改后的url
return x_url
# 增强程序的容错率,若没有输入,则退出程序
except:
print('No input!')
sys.exit('Goodbye!')
def get_page(self, url, params=None):
'''
获取网页信息函数,发送请求,获取响应内容
:param url: 需要进入的网址
:return req.text: 返回解码后的网页信息
'''
# 休眠,避免被对方反爬到
time.sleep(random.randint(1,5))
req = requests.get(url, headers=self.header, params=params)
# 返回解码后的内容:requests.get().text
# 返回字节:requests.get().content
return req.text
def analyze_paper(self, url):
'''
对每一个文章的网页进行检索,获取信息
:param url: 需要检索的文章的url
:return: msg: 包含文章的标题、作者、DOI、摘要、被引量、年份、关键词信息,若返回None,则表示不为期刊论文,跳过该文献
'''
content = self.get_page(url)
# 匹配结果均为一个列表,关键词、作者、需要保留为List,其余需要转换为str
# 关键词
keyword = re.findall('target="_blank" class="">(.*?)</a></span>'