每次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
| 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("帐号") driver.find_element_by_xpath('//*[@id="mat-input-1"]').clear() driver.find_element_by_xpath('//*[@id="mat-input-1"]').send_keys("密码") driver.find_element_by_xpath('//*[@id="signIn-btn"]').click()
time.sleep(10) cookies = driver.get_cookies() driver.close() cookie = {} for items in cookies: cookie[items.get("name")] = items.get("value") return cookie
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 = get_cookies()
for subjectName in subjectNameList: nameLower = subjectName.replace('%20', ' ').replace('%26', '&').replace('%2F', '_').replace('%2C',',').lower() dictLi = [] 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" try: search_response = requests.get(requestUrl, cookies=cookies) except: cookies = get_cookies()
if search_response.text == 'No results found': break
re_text = search_response.json() list = re_text.get("data") 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)
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
| import pandas as pd import os
files = os.listdir()
dfList = [] for file in files: if ( file != 'merge.py') & ( file != 'merge.xlsx') & ( file != 'esi_article_Info.py'): print(file + ' is processing')
df = pd.read_excel(file)
df.insert(df.shape[1], 'Subject', file.split('.')[0])
dfList.append(df)
print('start merging') alldata = pd.concat(dfList)
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两列可能都会出现用科学计数法表示的情况,如果想要改成用文本的形式显示,可以用数据“分列”的方法。
前两步可以直接点“下一步”,第三步选择列数据格式为“文本”,目标区域位置不用改,就是覆盖原来的数据。然后点击“完成”,数据就都会以“文本”的格式显示。