Python爬虫——爬取IEEE论文


说明:本文为个人解决问题过程记录,方法和理论不一定完全正确,如有错误,欢迎指出。


1 获取文章列表

1.1 问题

  IEEE是第3个爬的数据库,前两个Pubmed和ScienceDirect都直接用requests.get()可以直接返回一个Response对象,然后用Beautifulsoup解析Response的.content,最后用find和find_all找想要的信息就可以了,如下所示:

# 模板
res = requests.get(url, params=searchDic)           # 发送GET请求
s = BeautifulSoup(res.content, 'lxml')              # 解析html
amount = s.find('div', class_="results-amount")     # 获取文章总数量

  修改代码后程序报错,调试发现是find函数找不到类名

url = 'https://ieeexplore.ieee.org/search/searchresult.jsp? \
        newsearch=true&queryText=support'
IEEE_response = requests.get(url=url, verify=False)
response_text = IEEE_response.content
s = BeautifulSoup(response_text, 'lxml')
papers = s.find_all('div', class_="List-results-items")     # 找不到List-results-items

  问题就出在这,在浏览器里F12可以找到对应信息的标签,但是在程序里直接find却找不到,直接输出Beautifulsoup解析后的数据,发现问题。

  Beautifulsoup解析后的数据如下:

<div class="global-content-wrapper u-relative">
<xpl-root>
<div class="Spinner"></div>
</xpl-root>
</div>

  浏览器中html如下:
在这里插入图片描述
  论文列表就在红色箭头所指向的标签,但是get返回的信息中直接被“删除”了。

1.2 解决方法

  网上百度了一圈,找到了解决方法,最开始找到的是方法1,后来又找到了方法2.

1.2.1 创建浏览器对象进行模拟访问 [ 1 − 4 ] ^{[1-4]} [14]

  刷新网页,可以发现论文信息那部分是其它页面显示后过了一阵才刷出来的。这是因为IEEE用了ajax慢加载的方式来防止爬虫爬取页面,直接访问链接并不能得到任何东西。对于这种问题我们可以使用工具selenium来解决。selenium是一种自动化测试的工具,可以控制浏览器来自动完成一些动作,在这里正好能成为 ajax 防爬的克星。

  代码如下:

browser = webdriver.Chrome()
browser.get(url)
browser.implicitly_wait(10)       # 隐式等待
WebDriverWait(browser, 5, 0.5).until(lambda x:
                x.find_elements_by_class_name('List-results-items'))
amount = browser.find_element_by_xpath("//*[@id=\"xplMainContent\"] \
                /div[1]/div[2]/xpl-search-dashboard/section/div/div[1] \
                /span[1]/span[2]")

  通过创建浏览器对象,selenium会自动打开chrome,来模拟浏览器访问。通过WebDriverWait().until()来等待网页加载完成后,再用find_element_by_×××来获取数据。

  不过这样存在一定的问题,由于是模拟人去浏览网页以及浏览器启动,网页渲染等操作一个不落,所以无法发挥爬虫的机器高效性;另外即使是无界浏览模式,浏览器还是会占用大量的电脑内存资源。

1.2.2 POST请求 [ 5 ] ^{[5]} [5]

  参考[5]中搜索部分的代码可以正常运行,且获得正确数据,发现是用post请求进行访问的,于是研究了一番。

  浏览器中按F12看网址加载过程,方法如下:
在这里插入图片描述

如下图,点进Preview中发现,想要的信息都在这里
在这里插入图片描述

如下图,点击Headers,访问方式是POST
在这里插入图片描述

如下图,Headers信息
在这里插入图片描述

  因此确定要用POST方式来进行访问,Resoponse Headers中显示返回类型为json格式,知道这些信息后就可以开始写代码处理了。

# 请求头
headers = {
            'Accept': 'application/json,text/plain,*/*',
            'Accept-Encoding': 'gzip,deflate,br',
            'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
            'Connection': 'keep-alive',
            'Content-Length': '122',
            'Content-Type': 'application/json',
            'Referer': 'https://ieeexplore.ieee.org/search/searchresult.jsp? \
                        newsearch=true&queryText=mechanical',
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; \
                            rv:27.0) Gecko/20100101 Firefox/27.0'
    
        }
# 请求体
data = {
        'newsearch': 'true',
        'queryText': keyword,
        'pageNumber': page,
        'publicationYear': year_range,
        'rowsPerPage': 100
        }
# 返回结果处理
url = 'https://ieeexplore.ieee.org/rest/search'
IEEE_response = requests.post(url=url, data=json.dumps(data), \
                                headers=headers, verify=False)
response_text = IEEE_response.text
papers = json.loads(response_text)['records']
for paper in papers:
    paper_name = paper['articleTitle']
    journal_name = paper['publicationTitle']
    paper_date = paper['publicationDate']
    paper_abstract = paper['abstract']
    paper_doi = paper['doi']
    paper_num = paper['articleNumber']

  可以看出,第2种方式在进行数据处理时也比较简单明了,因此我采用了第2种方法。

2 获取完整摘要

2.1 问题

  通过上述步骤,就可以顺利的从IEEE检索结果中获取论文信息了,如论文题目、作者、会议/期刊名、日期、摘要、doi等。但是,获得的摘要是不完整的,因为在搜索结果列表状态下的论文摘要只显示了一部分,剩下的需要到文章的详情页才能看到。
在这里插入图片描述

  浏览器中F12后,定位到摘要位置也是不完整的。
在这里插入图片描述

2.2 解决方法

  首先在文章详情页中定位到摘要部分
在这里插入图片描述

  点Preview后发现预览里面并没有论文相关信息,如下图
在这里插入图片描述

  在Response中定位,发现是用Javascript写的,如下图
在这里插入图片描述

  复制最外侧{}括号之间内容,用JSON解析器解析一下,确实是完整的论文信息,如下图
在这里插入图片描述

  从Headers中找到访问相关的信息
在这里插入图片描述

  再次上百度大法,找到方法来获取HTML中的JavaScript内容 [ 6 − 8 ] ^{[6-8]} [68]。基本流程就是发送GET请求,用Beautifulsoup解析返回信息,然后用正则表达式来获取到json数据,最后将json数据转换为字典格式。

# 请求头
gheaders = {
    'Referer': 'https://ieeexplore.ieee.org/search/searchresult.jsp? \
    newsearch=true&queryText=support',
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:27.0) \
    Gecko/20100101 Firefox/27.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9, \
    image/avif,image/webp,image/apng,*/*;q=0.8,'
              'application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Connection': 'keep-alive'
}
# 请求链接
url = 'https://ieeexplore.ieee.org/document/4537113'
IEEE_response = requests.get(url=url, headers=gheaders)     # GET请求
soup = BeautifulSoup(IEEE_response.text, 'lxml')            # 解析
# 正则表达式 创建模式对象
pattern = re.compile(r'xplGlobal.document.metadata=(.*?);', re.MULTILINE | re.DOTALL)
script = soup.find("script", text=pattern)                  # 根据模式对象进行搜索
res_dic = pattern.search(script.string).group(1)            # 配合search找到字典
print(res_dic)
json_data = json.loads(res_dic)                             # 将json格式数据转换为字典
print(json_data['userInfo'])                                # 测试一下。。

参考资料

[1]IEEE 论文爬取

[2]python系列之网络爬虫

[3]selenium采用find_element_by方法识别页面元素

[4]Python selenium有多个class值时如何定位

[5]爬取ieee

[6]如何获取在Python中的JavaScript内容

[7]python 爬虫如何获取js里面的内容

[8]python中的search的group(0),group(1)的方法

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值