一键爬取在Sustainability上发文最多的国家

257 阅读5分钟

导读

Sustainability(以下简称Sus)是由出版商MDPI2009年创立的一家开源期刊(Open Access Journal)。从2009年到2020年,Sus不过12岁,从最初的季刊,发展至如今的半月刊,并在刊文数量和收稿范围方面轻松超越诸位“老前辈”。为了让大家更深入地了解Sus,我们通过网络爬虫抓取了该刊自创刊以来的所有文献目录及其作者单位。下面,就让我们一起来看看如何实现吧~

20000余篇!

 首先,通过分析源网页,我们发现需要抓取的文章链接和题目位于(<a class="title-link" href="标签所在的行")。  

图片1

其次,使用copy爬虫命令、字符串函数和正则表达式抓取并保留我们需要的内容。

clear all
copy "https://www.mdpi.com/2071-1050/1/1" temp.txt,replace
infix strL v 1-100000 using temp.txt,clear
keep if strpos(v,`""title-link" href=""')
**使用正则表达式提取文章题目和链接**
gen title = ustrregexs(1) if ustrregexm(v,`"(?<=">)(.*?)(?=</a>)"')  
replace title = ustrregexra(title,"<.*?>","")
gen title_link = ustrregexs(1) if ustrregexm(v,`"(?<=href=")(.*?)(?=">)"')
replace title_link = "https://www.mdpi.com" + title_link
drop v
save v1_part1,replace

最后,根据URL的规律,借助一个三 层 大 循 环就能把所有的文章链接和题目抓取下来以备二次爬虫(抓取作者单位)使用啦~

clear all
cap mkdir "D:/Sus"
cd "D:/Sus"
local a = 1
forvalues v = 1/12{
    forvalues i =1/24{
        forvalues p = 0(15)1500{
            clear
            cap copy "https://www.mdpi.com/2071-1050/`v'/`i'/default/`p'/15" temp.txt,replace
            if _rc == 601{
                continue,break
            }
            infix strL v 1-100000 using temp.txt
            if v[1] == "" & v[2] == "" & v[3] == ""{
                continue,break
            }
            keep if strpos(v,`""title-link" href=""')
            gen title = ustrregexs(1) if ustrregexm(v,`"(?<=">)(.*?)(?=</a>)"')
            replace title = ustrregexra(title,"<.*?>","")
            gen title_link = ustrregexs(1) if ustrregexm(v,`"(?<=href=")(.*?)(?=">)"')
            replace title_link = "https://www.mdpi.com" + title_link
            drop v
            **第一层循环:保存每一期所有页面的文章URL**
            save v`v'_is`i'_p`a',replace
            local a = `a' + 1
        }
         **第二层循环:合并每一期的所有文章URL**
        clear
        openall v`v'_is`i'*,directory(D:/Sus/)
        **为防止空数据集无法保存导致报错,此处应使用capture命令。**
        **在两层以上的循环中一定要特别注意!**
        cap save v`v'_is`i'_url,replace   
        if _rc == 111{
            continue,break
        }
    }
    **第三层循环:合并每一卷所有期的文章URL**
    clear
    openall v`v'_is*_url,directory(D:/Sus/)  
    save v`v'_urlall,replace
}

 运行结果如下所示:

 图片2    经过整理,我们发现:     Sus在创刊当年仅刊发79篇文章,次年改为月刊,刊文量翻倍至199篇。2016年刊发量大增,为1346篇。其后四年,Sus的发文量暴增,连年翻倍,2019年达到7200余篇。   

图片3

再来看看发文量前10

我们已经拿到总共12卷所有文章的URL,下面我们就利用这些链接来爬取文章的作者、国籍及其所属机构。

cap mkdir "D:/Sus/top"
cd "D:/Sus/top"
clear all
forvalues v = 1/12{
        use "D:/Sus/v`v'_urlall",clear
        levelsof title_link,local(title_link)
        local a = 1
            foreach url in `title_link'{
                clear
                cap copy `"`url'"' temp.txt,replace
                while _rc != 0{
                    sleep 5000
                    cap copy `"`url'"' temp.txt,replace
                }
                infix strL v 1-100000 using temp.txt,clear
                keep if ustrregexm(v,`"affiliation-item|affiliation-name| </h1>"')
                replace v = ustrregexra(v,`"<.*?>"',"")
                **信息过于繁杂,此处采用删除各种备注标识(eg.*、‡)所在的行及其后一行的处理方法**
                drop if v[_n-1] == "*" | v[_n-1] == "†" | v[_n-1] == "‡" | v[_n-1] == "#" | v[_n-1] == "§" | v[_n-1] == "||"
                drop if v == "*" | v == "†" | v == "‡" | v == "#" | v == "§" | v == "||"
                gen title = v[1],before(v)
                drop in 1
                gen inname = v[_n+1]
                replace inname = v if inname == ""
                keep if mod(_n,2)
                rename v inid
                gen title_link = `"`url'"'
                **第一层循环:爬取并保存每一篇文章的作者信息**
                save v`v'_artins_`a',replace
                local a = `a' + 1
            }
**第二层循环:将每一卷所有的作者信息进行合并**
        clear
        openall v`v'_artins_*,directory(D:/Sus/top/) 
        save v`v'_artinsall,replace
 }
**循环外:合并全部12卷的作者信息**
clear all
openall v*_artinsall,directory(D:/Sus/top/)
save artinsall,replace

通过分类汇总等操作,我们发现:由中国大陆各类学术机构署名的文章有12923篇,高居榜首,第二名的美国有3600余篇,韩国和西班牙不甘示弱,紧随其后,末位的澳大利亚和荷兰也有800余篇。

图片4

国内高校哪家强?

为了对国内高校(大陆)发文量进行排序,我们首先利用利用正则表达式或字符串函数保留机构名称(inname)中含China的观测值,并进一步剔除非高校发表的作者信息:

use "D:/Sus/top/artinsall.dta",clear
replace inid = "1" if inid[_n] == inname[_n] 
drop if ustrregexm(inid,"\D")  //剔除机构id为非数字的观测值
replace inname = subinstr(inname,"amp;","",.)
keep if strpos(inname,"China")  
keep if ustrregexm(inname,"School|Institute|University|Academy|College")

由于作者信息较繁杂,包含作者姓名、所属机构(包括学院、研究院、学校等)、作者地址、邮编、国籍等,然而这些条目并没有严格的、一致的顺序,因此要精准地提取出作者所属的机构并不是一件容易的事。笔者的思路是:先将作者信息按英文逗号拆分,再将含有SchoolInstituteUniversityAcademyCollege的变量合并。

split inname,p(",")
drop inname
qui des inname*,varlist   //使用describe命令以获得以inname开头的变量名
gen inname = ""
foreach v in `r(varlist)'{  //r(varlist)即为上述des命令的返回值之一
    replace inname = inname+","+`v' if          ustrregexm(`v',"School|Institute|University|Academy|College")   ///
                             & !ustrregexm(`v',"Rd.|Road|Town")
    drop `v'
}

为保留最大级别的机构名称,比如一篇文章署名为:School of Finance, Zhongnan University of Economics and Law,我们要将Zhongnan University of Economics and Law保留下来,而最大级别的机构名称一般位于末尾,我们采用逆向查找匹配的方法。

**逆向查找匹配**
gen len = strlen(inname)
qui sum len
forval i = `r(max)'(-1)1{
    **逆向查找第一个(最后一个)英文逗号**
    replace inname = substr(inname,`i',.) if ustrregexm(substr(inname,`i',.),"(?<!\d),\s+(?!\d)") 
}
replace inname = subinstr(inname,",","",1)
drop len
**清洗、分组汇总**
replace inname = trim(inname)  //剔除字符串两边的空格
replace inname = subinstr(inname,"&","and",.)  
replace inname = subinstr(inname,`"´"',`"'"',.)   //替换英文撇号为英文单引号
bysort inname:egen sum = count(inname)
bysort inname:keep if _n == 1
gsort -sum
save institute_en,replace

经过整理,我们就能拿到国内高校在Sus上发文的排行榜啦~限于篇幅,本文仅展示发文量大于等于10的大陆高校。

图片5

以上就是小编今天带来的内容,小编本身就是一名python开发工程师,我自己花了三天时间整理了一套python学习教程,从最基础的python脚本到web开发,爬虫,数据分析,数据可视化,机器学习,等,这些资料有想要的小伙伴 点击 即可领取