首页 科技区

我在8月做了一项小工作,就是使用python对WoS导出的文献条目进行了批量处理。核心内容包括两个方面,一是批量查询了论文所在期刊的影响因子(Impact factor)——这可以帮助我补充影响因子这一维度,结合被引量一同筛选高质量文章;二是批量翻译了论文摘要——这可以帮助我以直观的方式快速把握文章的研究目标、研究方法与研究结论。

先提前把需要导入的库列出来:

import pandas as pd
import glob
import requests
import time
from bs4 import BeautifulSoup
from pygtrans import Translate

1、在WoS上导出检索文献的Full record

检索文献首先需要一定的文献检索式,并选定检索的数据库类型为 Web of Science Core Collection (Web of Science核心合集)。在导出界面,选择导出至Excel,WoS一次性只支持导出500个检索结果,因此如果检索到的文献较多的话还得记好编号多导出几次。格外需要注意在Record Content窗口里点选Full Record ,只有这样才能导出期刊的ISSN号、论文的DOI号等信息!

image-20210901161658513

2、批量查询影响因子

我无意间发现了一个期刊影响因子查询网站,于是尝试了使用python来爬取网页并提取数据。尽管这个网站的数据库中缺乏一些期刊,但在绝大多数情况下都能满足需求。

打开网站可以看到,其支持使用期刊名和ISSN号对期刊的影响因子进行查询。直接给出python代码:

def get_IF_from_name(name):
    # 从期刊名查询impact factor
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    name.replace(' ', '+')  # 在网址查询时把空格转为+号
    address = "http://sci.justscience.cn/?q=" + str(name) + "&sci=1"
    f = requests.get(address, headers = headers, timeout=(3,7)) # 加timeout防掉线
    soup = BeautifulSoup(f.text, features="lxml")
    tds = soup.find_all(height="30")
    for i in range(0, len(tds), 8):
        if tds[i+1].text.upper() == name.upper():  # 找到名称完全一样的期刊
            time.sleep(1)
            return tds[i+7].text

def get_IF_from_issn(issn):
    # 从期刊唯一的ISSN号查询impact factor 
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    address = "http://sci.justscience.cn/?q=" + str(issn) + "&sci=1"
    f = requests.get(address, headers = headers)
    soup = BeautifulSoup(f.text, features="lxml")
    return soup.find_all(height="30")[-1].text  # 结果唯一

在使用时,有以下几个需要注意的地方:

1、克制地使用接口,毕竟这是白嫖别人的服务,尽量加上time.sleep()

2、部分刊物无ISSN号(例如那些只有e-ISSN号的期刊)。这些期刊就得靠期刊名进行查询。

3、在按期刊名查询 IF 时,注意检索的结果包括了所有带有所查询名称的期刊。这个结果不是按照名称的相关性排序,而是按照影响因子倒序排列的!所以我在写get_IF_from_name()函数时确保了期刊名完全一致。

image-20210901160840562

3、批量翻译摘要

这里我是直接用轮子。使用了pygtrans库,高效稳定地调用谷歌翻译。使用方法很简单:

from pygtrans import Translate

client = Translate()
for i in range(nrows):  # 部分语句略去,仅展示大意,具体见下
        df.iloc[i, Trans_index] = client.translate(df['Abstract'][i]).translatedText

4、使用pandas处理Excel

经过我的一番对比,我发型 pandas 简直就是处理 Excel 的最优解,既可以同时对xls与xlsx做到读和写,也能使用 pandas 的一系列用法,比xlwings等库好用太多太多。

基于自己的需求,结合上述内容,我依次进行了如下处理:

1、保留所需列:

df = pd.read_excel(exl) # 读
max_column=67 # wos全导出后共67个字段
column_saved = ['Author Full Names', 'Article Title', 'Source Title', 'Document Type', 'Author Keywords', 'Keywords Plus', 'Abstract', 'Times Cited, WoS Core', 'ISSN', 'Publication Year', 'DOI']
        
# 保留所需列
for col in df.columns.values:
        if col not in column_saved:
                df.drop(labels=col, axis=1, inplace=True)

2、添加IF列与摘要翻译列:

# 添加所需列
df.insert(3, 'IF(2021)', value='', allow_duplicates=False)  # insert方法要写默认value值
df.insert(8, 'Translation', value='', allow_duplicates=False)

3、批量翻译与查询影响因子:

client = Translate()
nrows = df.shape[0] # 获取excel的真实行数

# 使用iloc函数需要先获取index,这是用pandas处理excel的小要求
IF_index = list(df.columns).index('IF(2021)')
Trans_index = list(df.columns).index('Translation')
        
for i in range(nrows):
        df.iloc[i, Trans_index] = client.translate(df['Abstract'][i]).translatedText
    
    if len(str(df['ISSN'][i]))==9:  # ISSN号都是8位数字加一个短横线
    # 这样写if-else语句是因为部分刊物无ISSN号
            try:
                df.iloc[i, IF_index] = get_IF_from_issn(df['ISSN'][i])
        except:
            df.iloc[i, IF_index] = "nan"
    else:
                try:
            df.iloc[i, IF_index] = get_IF_from_name(df['Source Title'][i])
        except:
            df.iloc[i, IF_index] = "nan"

df.to_excel(".\postprocessing\output_"+exl.split("\\")[-1].split(".")[0]+".xlsx") # 写

后续就可以在Excel中进行进一步的筛选,大致的结果如下:

image-20210901165913789

如果有多个excel需要处理,就统一放在一个文件夹里,使用glob.glob()获取所有的文件名,然后一个 for 循环就可轻松搞定。




文章评论

目录