python 在当前网页中 搜索关键字并点击_asp抓取网页某个标签内的


在学术研究中,经常需要了解某个领域的最新发展趋势,比如说,发掘最热门、上升速度最快的几个关键词。有些学术服务网站,比如Web of Science,提供类似的服务,但一些院校并没有订购这些服务,而且使用中难免会遇到各种问题,比如定制化不足等。在这篇文章中,我们来探讨如何利用python及免费资源,进行基于论文关键词的研究趋势分析。

选定期刊

我想要了解国际商务(international business)领域近年来发表的文章,在google中搜索“google scholar journal ranking international business”,点开第一个链接,得到如下页面:


python 在当前网页中 搜索关键字并点击_CSV_02


这里以排名第一的Journal of International Business Studies为例,示意如何抓取近年来发表的所有文章的信息。

找到文章列表

经过一番搜寻,我找到了自2013年以来发表的全部442篇文章的列表:


python 在当前网页中 搜索关键字并点击_css_03


点击图中红框中的按钮,可以将全部442篇文章的信息导出到CSV文件。


python 在当前网页中 搜索关键字并点击_CSV_04


然而,文件中只有每篇文章的篇名(item title)、作者(authors)和链接(URL),没有关键词(key words)和摘要(abstract)这些重要信息。

接下来,我们用python编写一个循环,打开每一篇文章的链接,抓取关键词和摘要。

抓取网页元素

首先,我们定义一个get_keywords_abstract()函数,用来抓取给定网页中的相关元素,代码如下:


import requests
from scrapy import Selector

def get_keywords_abstract(url):
    r = requests.get(url) #打开网页
    if r.status_code != 200: #如果网页连接错误,就返回空字符串
        print("Connection error: {}".format(url))
        return "", ""
    selector = Selector(text=r.text) 
    keywords = selector.css('.Keyword::text').extract()
    abstract = selector.css('#Abs1 p::text').extract_first()
    return keywords, abstract


值得说明的是,我使用了scrapy库里面的Selector类来解析网页。之所以这么做,是因为与Beautiful Soup、Pyquery等库相比,我比较熟悉scrapy下的css选择器的使用方法。

为了验证以上代码是否正确,我在命令行中执行以下测试代码:


test_url = 'https://link.springer.com/article/10.1057%2Fs41267-019-00235-7'
keywords, abstract = get_keywords_abstract(test_url)
print(keywords)
print(abstract)


结果有点出人意表:


>>> print(keywords)
['entry modexa0', 'deviation from predictionxa0', 'internalization theoryxa0', 'bounded rationalityxa0', 'cognitive biasxa0']
>>> print(abstract)
'We explore when and why decision makers choose international entry modes (e.g., hierarchies or markets) that deviate from internalization theory’s predictions. By applying a cognitive perspective on entry mode decision making, we propose that the performance of prior international activities influences decision makers’ behavior in different ways than assumed in internalization theory. More specifically, due to a'


关键词末尾有多余的字符,这个问题不大,可以在后续处理中批量删除。真正的问题在于,摘要不完整。

在浏览器中打开测试网页,点击右键查看源代码,发现摘要中有一些html标签,比如:


...due to a <em class="EmphasisTypeItalic ">representativeness bias</em> , underperforming ...


正是这些html标签,干扰了正常的文本抓取。

为了解决这个问题,我修改了一下get_keywords_abstract()函数:


import requests
from scrapy import Selector

def get_keywords_abstract(url):
    r = requests.get(url) #打开网页
    if r.status_code != 200: #如果网页连接错误,就返回空字符串
        print("Connection error: {}".format(url))
        return "", ""
    selector = Selector(text=r.text) 
    keywords = selector.css('.Keyword::text').extract()
    abstracts = selector.css('#Abs1 p::text').extract() #把extract_first()改成extract(),抓取所有的文本片段
    abstract = ''.join(abstracts) #把文本片段连接起来
    return keywords, abstract


重跑测试代码,发现问题解决了。

导入CSV文件

接下来就要导入CSV文件中的URL列表,循环抓取关键词和摘要了。

导入CSV文件要用到pandas库:


import pandas as pd

articles = pd.read_csv('../data/jibs_articles.csv', sep=',')
type(articles) # <class 'pandas.core.frame.DataFrame'>
articles.shape # (442, 10)
articles.columns # 列名
articles.head() # 打印前5行


For循环

确定一切无误之后,就要开始循环了:


urls = articles['URL']
keywords = pd.Series(index=articles.index)
abstract = pd.Series(index=articles.index)

for i, url in enumerate(urls):
    keywords[i], abstract[i] = get_keywords_abstract(url)
    print("Finish article: {}".format(i)) # 抓完一个网页就报一个数字,等的时候心里好过一些


等了20分钟左右,终于抓完了,只有一篇文章打开错误。

保存到CSV文件

接下来,我们把关键词和摘要整合到数据表格中,然后保存到CSV文件。


articles['keywords'] = keywords
articles['abstract'] = abstract
articles.columns # 数据表中增加了keywords和abstract两列
articles.to_csv('../data/jibs_keywords_abstract.csv', sep=',', header=True)


为了方便下次使用,我们把数据“腌制”起来:


import pickle
with open("../data/articles.pickle", "wb") as f:
    pickle.dump(articles, f)


下次,我们再讲基于关键词的研究趋势分析。