每次ESI数据更新之后,有些文章是热点文章,有些文章是研究前沿,就如下图中的红框标示出来的一样。但这部分数据,主要是研究前沿的文章,在ESI导出的数据中看不到。所以需要想办法获取这部分数据。

获取数据

  观察发现,每次翻页,都会有下面这样的一个请求包被发送,并获得json格式的数据,因此我们只要照着它的请求方式发送请求,就能获得相应的数据。

  直接发请求是拿不到数据的,需要带上cookies。所以我用selenium模拟浏览器登录,然后获取cookies。在用requests发请求的时候,带上这个cookies就可以拿到json格式的数据。具体代码如下,需要输入自己的ESI帐号和密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# esi_article_info.py
import requests
import time
import pandas as pd
from selenium import webdriver

def get_cookies():
driver = webdriver.Edge()
driver.get("https://access.clarivate.com/login?app=esi")

driver.find_element_by_xpath('//*[@id="mat-input-0"]').clear()
driver.find_element_by_xpath('//*[@id="mat-input-0"]').send_keys("帐号") # 输入自己的ESI帐号
driver.find_element_by_xpath('//*[@id="mat-input-1"]').clear()
driver.find_element_by_xpath('//*[@id="mat-input-1"]').send_keys("密码") # 输入自己的ESI密码
driver.find_element_by_xpath('//*[@id="signIn-btn"]').click()

# 等待窗口响应
time.sleep(10)
# 获取登录后的cookies
cookies = driver.get_cookies()
# 关闭浏览器
driver.close()
# print(cookies)
cookie = {}
# 将cookies保存成字典格式
for items in cookies:
cookie[items.get("name")] = items.get("value")

return cookie

# 学科列表,每个列表项用于添加到url中
subjectNameList = [
'CLINICAL%20MEDICINE',
'MULTIDISCIPLINARY',
'CHEMISTRY',
'MATERIALS%20SCIENCE',
'ENGINEERING',
'BIOLOGY%20%26%20BIOCHEMISTRY',
'PHYSICS',
'MOLECULAR%20BIOLOGY%20%26%20GENETICS',
'NEUROSCIENCE%20%26%20BEHAVIOR',
'ENVIRONMENT%2FECOLOGY',
'SOCIAL%20SCIENCES%2C%20GENERAL',
'PLANT%20%26%20ANIMAL%20SCIENCE',
'GEOSCIENCES',
'PSYCHIATRY%2FPSYCHOLOGY',
'PHARMACOLOGY%20%26%20TOXICOLOGY',
'IMMUNOLOGY',
'AGRICULTURAL%20SCIENCES',
'COMPUTER%20SCIENCE',
'MICROBIOLOGY',
'ECONOMICS%20%26%20BUSINESS',
'SPACE%20SCIENCE',
'MATHEMATICS'
]

# 先获取一次cookies
cookies = get_cookies()

for subjectName in subjectNameList:
# 把学科名字转换成小写,用于文件名以及输出当前正在处理的学科
nameLower = subjectName.replace('%20', ' ').replace('%26', '&').replace('%2F', '_').replace('%2C',',').lower()
# 字典列表,用于存放获取的数据,每一个条目以字典形式保存,作为其中一个列表项
dictLi = []
# cnt 用于记录当前处理进度
cnt = 1

page = 0
while True:
start = page * 50
page = page + 1
requestUrl = "https://esi.clarivate.com/IndicatorsDataAction.action?type=documents&author=&researchField="+subjectName+"&institution=&journal=&territory=&article_UT=&researchFront=&articleTitle=&docType=Top&year=&page="+str(page)+"&start="+str(start)+"&limit=50&sort=%5B%7B%22property%22%3A%22citations%22%2C%22direction%22%3A%22DESC%22%7D%5D"

# 尝试发送get请求,有时候如果cookies过期,可能会请求不到,所以需要重新获取cookies
try:
search_response = requests.get(requestUrl, cookies=cookies)
except:
cookies = get_cookies()

# 如果页码超出了上限,会收到‘No results found’的响应,然后就可以退出while循环
if search_response.text == 'No results found':
break

# 解析json格式数据
re_text = search_response.json()
list = re_text.get("data")
# 保存这一页的数据到字典indDict中
for item in list:
indDict = {}
for key, value in item.items():
indDict[key] = value
print(nameLower + ' ' + str(cnt)+" finished")
cnt = cnt + 1
dictLi.append(indDict)
time.sleep(1)

# dict转换成DataFrame并保存到excel里
df = pd.DataFrame(dictLi)
df.to_excel(nameLower + '.xlsx', index=False)

  用上面的脚本获取的每个学科的信息是单独存放的,一个学科一个文件。后面想把这些文件汇总成一个excel。为了区分每个文件的内容,我就新加了一列“subject”,用来记录学科名称,但后来发现这一步是多余的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# merge.py
import pandas as pd
import os

# 列出当前目录下的所有文件
files = os.listdir()
# dfList是一个用于存放DataFrame的列表,一个DataFrame对应一个excel文件
dfList = []
for file in files:
# 排除当前目录下的一些文件
if ( file != 'merge.py') & ( file != 'merge.xlsx') & ( file != 'esi_article_Info.py'):
print(file + ' is processing')

# 读取excel文件
df = pd.read_excel(file)

# 在excel的最后一列加上表头为‘subject’的一列,并把当前学科的名字填进去
# 这一步在这里其实是多余的
# 获取的原始数据里有一个条目就是researchFieldName
# 和这里添加的内容是相同的
df.insert(df.shape[1], 'Subject', file.split('.')[0])

# 把修改后的DataFrame加入到dfList列表中
dfList.append(df)

# 开始合成DataFrame
print('start merging')
alldata = pd.concat(dfList)
# 讲DataFrame的数据写入合成的excel
print('start writing')
alldata.to_excel('merge.xlsx', index=False, encoding='utf-8')

后续处理

  再来看一下我们获取的数据的信息:

  • highimpact
  • addresses
  • sourceOfBIB
  • articleId
  • researchFieldName
  • docTitle
  • countries
  • articleUT
  • institutions
  • researchFieldCode
  • citations
  • journal
  • rowSeq
  • DOI
  • authors
  • PMID
  • researchFrontName
  • hotpaper

  和我们从ESI直接导出的数据相比,这里的articleID实际上可以转换成Accession Number;这里的docTitle就是Article Name;这里的journal和sourceOfBIB构成了Source,sourceOfBIB里还包含了这篇文章发布的年份。所以用这种方式获取的数据能够完全包含直接从ESI导出的数据,并且还会多一些表征这篇文章是否是hot paper的信息和researchFrontName。
  最后导出的数据articleId和articleUT两列可能都会出现用科学计数法表示的情况,如果想要改成用文本的形式显示,可以用数据“分列”的方法。

  前两步可以直接点“下一步”,第三步选择列数据格式为“文本”,目标区域位置不用改,就是覆盖原来的数据。然后点击“完成”,数据就都会以“文本”的格式显示。