专栏首页庄闪闪的R语言手册R 爬虫|手把手带你爬取 800 条文献信息

R 爬虫|手把手带你爬取 800 条文献信息

开始

今天学习了一些关于 R 爬虫的知识,后续会陆续写一些笔记,当然对于爬虫有更好的一些工具来进行爬取数据,作为入门小白,我自己先从 R 语言尝试开始吧。

我们在浏览器中看到的网页很多都是有 HTML(Hyper Text Markup Language)超文本标记语言构成的树形结构,包括一系列标签,HTML 是一类标记语言而不是编程语言,当然要爬虫的话最好去了解一些最基本的 HTMLXML(Extensible Markup Language) 语言知识比较好。html 和 xml 有着类似的树形结构,都是一种标记语言。

今天学习了一下怎么爬取 NCBI 上的文献和基本信息,分享给大家。

试水

我们主要是使用 rvest 这个 R 包来爬取,这个主要应用于静态网页的数据爬取会实用一些,安装:

install.packages('rvest')

我们的目的是搜索感兴趣的关键词,然后对搜索的结果进行爬取。假如我想搜索 2021m6a 相关的所有文章,获取文章的标题作者网页链接摘要内容

首先我们打开 NCBI 的 pubmed 网页,筛选 2021 年的 m6a 文章:

可以看到总共有 811 篇文章,我这设置了每页显示 200 篇文献,大家可以自行设置,我们需要获取的该页面的文章标题和作者信息,首先我们爬取的网址就是当前页面的网址,因为显示的限制,所以需要对每个页面的数据进行爬取:

# 加载R包
library(xml2)
library(rvest)
library(tidyverse)

# 爬取2021年m6a文献,总共有811篇,显示200篇文献,爬取5次即可
url <- c('https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200',
         'https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200&page=2',
         'https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200&page=3',
         'https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200&page=4',
         'https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200&page=5')

# 或者这样也行
root <- 'https://pubmed.ncbi.nlm.nih.gov/?term=m6a&filter=years.2021-2021&size=200&page='
url <- paste(root,1:5,sep = '')

接下来使用 read_html 函数解析网址的内容,html 主要有 headbody 两个成分组成:

# 示例,read_html 返回html格式的内容
read_html(url[1],encoding = 'utf-8')
## {html_document}
## <html lang="en">
## [1] <head itemscope itemtype="http://schema.org/WebPage" prefix="og: http://ogp.me/ns#">\n<meta http-equiv ...
## [2] <body>\n\n  \n  \n    <noscript>\n  <div class="no-script-banner" id="no-script-banner">\n    <div cla ...

获取网址的 html 信息后就需要提取指定节点元素的内容了,需要使用 html_nodes/html_node 来获取节点信息,该函数只需要输入节点名称或者节点的路径(绝对路径或者相对路径)或者节点选择器

我们可以在网页上右键点击检查就可看到网页 html 格式的树形结构信息,再点击左上角箭头即可选中在网页中特定内容,右边就会自动定位到该内容的节点位置处:

选中页面特定内容:

接下来我们需要获取该节点的节点名称或者节点路径来提取该节点信息,首先点击我们选中的内容,然后在 3 位置上鼠标右键点击复制选项:

可以看到复制 selector复制 XPath复制完整的 XPath 三个选项,分别是节点选择器节点相对路径节点绝对路径,我们把复制的内容传到 html_nodes/html_node 函数里就可以得到节点的内容了。

这里我们尝试第一篇文章的标题节点信息获取:

# 节点选择器
read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('#search-results > section.search-results-list > div.search-results-chunks > div > article:nth-child(2) > div.docsum-wrap > div.docsum-content > a')
## {xml_nodeset (1)}
## [1] <a class="docsum-title" href="/32749190/" ref="linksrc=docsum_link&amp;article_id=32749190&amp;ordinalpos=1&amp;page=1" data-ga-category="result_ ...

可以看到返回的是完整的该位置处的节点信息,可以使用 html_text 函数从里面提取文本信息,去除 html 格式的标签等不必要信息:

read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('#search-results > section.search-results-list > div.search-results-chunks > div > article:nth-child(2) > div.docsum-wrap > div.docsum-content > a') %>%
  html_text()
## [1] "\n                Comprehensive analysis of the transcriptome-wide m6A methylome in colorectal cancer by MeRIP sequencing.\n              "
# 加上trim = T 参数简洁化内容
read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('#search-results > section.search-results-list > div.search-results-chunks > div > article:nth-child(2) > div.docsum-wrap > div.docsum-content > a') %>%
  html_text(trim = T)
## [1] "Comprehensive analysis of the transcriptome-wide m6A methylome in colorectal cancer by MeRIP sequencing."

同样的我们使用节点的相对路径和绝对路径也能得到相同的结果,此时需要用 xpath 参数指明:

# 相对路径
read_html(url[1],encoding = 'utf-8') %>%
  html_nodes(xpath = '//*[@id="search-results"]/section[1]/div[1]/div/article[1]/div[2]/div[1]/a') %>%
  html_text(trim = T)
## [1] "Comprehensive analysis of the transcriptome-wide m6A methylome in colorectal cancer by MeRIP sequencing."

# 绝对路径
read_html(url[1],encoding = 'utf-8') %>%
  html_nodes(xpath = '/html/body/main/div[9]/div[2]/section[1]/div[1]/div/article[1]/div[2]/div[1]/a') %>%
  html_text(trim = T)
## [1] "Comprehensive analysis of the transcriptome-wide m6A methylome in colorectal cancer by MeRIP sequencing."

此外我们可以使用 SelectorGadget 网页插件来获取节点名称,插件安装直接去官网:https://selectorgadget.com/,拉到最下面,把 SelectorGadget 拉到收藏夹就可以使用了:

来到我们爬取的网页,点击 SelectorGadget,选择特定要获取的网页内容,复制节点名称就可以了,这个也可以复制 xpath 相对路径:

尝试一下:

# 节点名称
read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('.docsum-title') %>%
  html_text(trim = T)
## [1] "Comprehensive analysis of the transcriptome-wide m6A methylome in colorectal cancer by MeRIP sequencing."
## [2] "RNA m6A methylation promotes the formation of vasculogenic mimicry in hepatocellular carcinoma via Hippo pathway."
...
## [199] "Main N6-Methyladenosine Readers: YTH Family Proteins in Cancers."
## [200] "FTO overexpression inhibits apoptosis of hypoxia/reoxygenation-treated myocardial cells by regulating m6A modification of Mhrt."

# 批量提取文章标题
title <- c()
for (i in url) {
  title <- c(title,read_html(i,encoding = 'utf-8') %>% html_nodes(".docsum-title") %>% html_text(trim = T))
}
# 查看数量
length(title)
## [1] 813

可以看到 .docsum-title 节点名称把该当前网页的所有文章标题都提取了出来,非常的方便。

接下来提取每篇文章的作者信息,同样的操作:

# 2、爬取文章作者
author <- c()
for (i in url) {
  author <- c(author,read_html(i,encoding = 'utf-8') %>%
                html_nodes('.full-authors') %>%
                html_text())
}
# 查看数量
length(author)
## [1] 813

爬取文章地址,其实每篇文章的标题都是一个链接,我们点击标题就可以进入另一个网址,所以只需要获取该标题的超链接地址就可以了,也就是这篇文章的地址,这时我们使用 html_attr 函数来提取标题节点的属性。

在 html 元素中可以看到 href 标识,就是链接地址的 id,我们进入该文章后,这篇文章的地址只是在上级网页地址后加了这个 id

网址地址:

我们用 html_attrs 获取所有属性:

read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('.docsum-title') %>%
  html_attrs() %>% head()
[[1]]
                                                                           class
                                                                  "docsum-title"
                                                                            href
                                                                    "/32749190/"
                                                                             ref
                   "linksrc=docsum_link&article_id=32749190&ordinalpos=1&page=1"
                                                                data-ga-category
                                                                  "result_click"
                                                                  data-ga-action
                                                                             "1"
                                                                   data-ga-label
                                                                      "32749190"
                                                           data-full-article-url
"from_term=m6a&from_filter=years.2021-2021&from_size=200&from_page=1&from_pos=1"
                                                                 data-article-id
                                                                      "32749190"
...

可以使用 html_attr 指定 name 参数来获取指定属性的内容:

read_html(url[1],encoding = 'utf-8') %>%
  html_nodes('.docsum-title') %>%
  html_attr(name = 'href') %>% head()
## [1] "/32749190/" "/32920668/" "/32821938/" "/33314339/" "/33070036/" "/33156926/"

## 批量获取文章链接
# 3、爬取文章地址,地址是https://pubmed.ncbi.nlm.nih.gov/加上爬取的编号
web <- c()
for (i in url) {
  web <- c(web,read_html(i,encoding = 'utf-8') %>% html_nodes('.docsum-title') %>% html_attr(name = 'href'))
}
# 查看数量
length(web)
## [1] 813
# 连接成网址
web_link <- paste('https://pubmed.ncbi.nlm.nih.gov',web,sep = '')
web_link
## [1] "https://pubmed.ncbi.nlm.nih.gov/32749190/" "https://pubmed.ncbi.nlm.nih.gov/32920668/" "https://pubmed.ncbi.nlm.nih.gov/32821938/"
## [4] "https://pubmed.ncbi.nlm.nih.gov/33314339/" "https://pubmed.ncbi.nlm.nih.gov/33070036/" "https://pubmed.ncbi.nlm.nih.gov/33156926/"

要获取文章的摘要就得进入该网址,在上一步我们已经获取了每篇文章的网址,就可以再次对其解析,然后获取摘要的内容了,基本上是同样的操作:

循环每篇文章,稍微花点时间,R 语言爬虫确实慢,哈哈:

# 4、爬取文章摘要
abstract <- list()
for (i in web_link) {
  # 根据节点相对路径提取
  # abstract[[i]] <- read_html(i,encoding = 'utf-8') %>% html_nodes(xpath = '//*[@id="enc-abstract"]/p') %>% html_text(trim = T)
  # 根据节点绝对路径提取
  # abstract[[i]] <- read_html(i,encoding = 'utf-8') %>% html_nodes(xpath = '/html/body/div[5]/main/div[2]/div[2]/p') %>% html_text(trim = T)
  # 根据节点名称提取
  abstract[[i]] <- read_html(i,encoding = 'utf-8') %>% html_nodes("#enc-abstract > p") %>% html_text(trim = T)
}
# 查看数量
length(abstract)
## [1] 813

爬取的摘要会有 \n 字符,此外有些文章的摘要并不是一个完整的部分,分类了好几点,这样的情况也需要处理一下:

# 去除\n
abstract_clean <- lapply(abstract, gsub,pattern = '\n',replacement = '')

# 连接为一个字符串对于多个部分的摘要
abs_res <- c()
for(i in 1:807){
  # 判断元素长度
  len = length(abstract_clean[[i]])
  if(len == 1){
    # 如果只有一个摘要就保存
    abs_res <- c(abs_res,abstract_clean[[i]])
  }else{
    # 如果摘要格式有多个,连接成一个
    abs_res <- c(abs_res,paste(abstract_clean[[i]],sep = '-',collapse = ' '))
  }
}
# 查看数量
length(abs_res)
## [1] 813

最后我们把所有爬取的内容整理保存为一个表格里并保存输出:

# 5、保存爬取数据
final_res <- data.frame(Title = title,Author = author,web = web_link,Abstract = abs_res)
# 6、保存爬取的数据
write.csv(final_res,file = 'C:/Users/admin/Desktop/m6a_Articles.csv',row.names = F)

我们打开看看:

可以可以,所以今天你学习了吗?

推荐: 可以保存以下照片,在b站扫该二维码,或者b站搜索【庄闪闪】观看Rmarkdown系列的视频教程。Rmarkdown视频新增两节视频(写轮眼幻灯片制作)需要视频内的文档,可在公众号回复【rmarkdown

R沟通|Rmarkdown教程(4)

R沟通|Rmarkdown教程(3)

R沟通|Rmarkdown教程(2)

R沟通|Rmarkdown教程(1)

本文分享自微信公众号 - 庄闪闪的R语言手册(Zss_R4ds)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 手把手带你Python爬虫 | 爬取起点小说网

    用python爬取一本仙侠类的小说下载并保存为txt文件到本地。本例为“大周仙吏”。

    快学Python
  • 从0到1掌握R语言网络爬虫

    引言 网上的数据和信息无穷无尽,如今人人都用百度谷歌来作为获取知识,了解新鲜事物的首要信息源。所有的这些网上的信息都是直接可得的,而为了满足日益增长的数据需求,...

    小莹莹
  • 手把手教你用Python网络爬虫获取头条所有好友信息

    大家好,我是黄伟。今日头条我发觉做的挺不错,啥都不好爬,出于好奇心的驱使,小编想获取到自己所有的头条好友,

    Python进阶者
  • 【重磅】微博终结者计划(WT Plan)启动

    原文链接:https://github.com/jinfagang/weibo_terminater 本文长度为2494字,阅读全文约需6分钟 本文为你解读刚刚...

    数据派THU
  • 教你用python制作一个爬虫软件,城市二手房信息一览无余。。(附源码)

    教你用python制作一个爬虫软件,城市二手房信息一览无余。。(附源码) ...

    Java架构师必看
  • 超级课程表APP爬虫,大学生都这么玩

    记得读大学时,看课程信息,查分数,看美女(嘘)都会使用超级课程表APP,当时这款APP非常火爆,今天,就带领大家回到大学,看看大学生都在干嘛? 该文涉及内容:

    罗罗攀
  • Python爬虫的法律边界(二)小爬怡情,大爬over!

    数据抓取的门槛越来越低,会点程序,或使用网络工具都可以薅点数据,新入行了不少爬虫选手,但是对抓取使用数据的法律风险可能缺少认识。尤其是从去年的《网络安全法》实施...

    一墨编程学习
  • Huginn 网友问答汇总

    huginn 中文网
  • 多种爬虫方式对比

    以安居客杭州二手房信息为爬虫需求,分别对比实验了三种爬虫框架、三种字段解析方式和三种数据存储方式,旨在全方面对比各种爬虫方式的效率高低。

    luanhz
  • 手把手教你使用Python网络爬虫获取菜谱信息

    今天教大家去爬取下厨房的菜谱 ,保存在world文档,方便日后制作自己的小菜谱。

    Python进阶者
  • 手把手教你使用Python网络爬虫获取招聘信息

    现在在疫情阶段,想找一份不错的工作变得更为困难,很多人会选择去网上看招聘信息。可是招聘信息有一些是错综复杂的。而且不能把全部的信息全部罗列出来,以外卖的58招...

    用户1564362
  • Python大佬开发了一个爬虫项目教你实现公众号文章的抓取和统计分析

    weixin_crawler从2018年6月份就开始利用业余时间开发,到今日正式问鼎江湖。在正式介绍weixin_crawler之前,我准备了两个问题,这...

    Python进阶者
  • 利用简易爬虫完成一道基础CTF题

      如果有想学习基础爬虫的同学,建议在中国大学MOOC上搜索嵩天老师的爬虫课程,讲的真的很细致,也很基础。

    KevinBruce
  • 对不起,我把APP也给爬了

    最近群里很多小伙伴对爬取手机app和小程序感兴趣,今天本厨师将给大家呈现这道菜,供小伙伴们品尝。

    朱小五
  • 手把手教你爬取研招网调剂信息

    这篇文章是去年我在博客上写的一篇基础爬虫,利用了简单的Python爬虫来定时收集目标专业的调剂信息,后面也确实帮助我成功上岸。

    老肥码码码
  • 手把手教你利用Python网络爬虫获取APP推广信息

    CPA之家app推广平台是国内很大的推广平台。该网址的数据信息高达数万条,爬取该网址的信息进行数据的分析。

    Python进阶者
  • 史上最恐怖爬虫来袭,可爬支付宝、微信、金融放贷信息!

    01爬虫凶猛 “同业爬虫?!” 第一次听到这个词,王浩一脸懵逼。 两个月前,王浩的公司转型现金贷,他在市面上四处寻找风控系统和数据源,此时,摩羯科技的商务人员,...

    BestSDK
  • 词云图:论一个精致猪猪男孩的数据修养

    “词云”就是对网络文本中出现频率较高的“关键词”予以视觉上的突出,形成“关键词云层”或“关键词渲染”,从而过滤掉大量的文本信息,使浏览网页者只要一眼扫过...

    用户1621951
  • RPA机器人和爬虫的区别,他们的边界在哪里?

    2019年越来越的企业关注到RPA,也有很多企业开始投入到RPA实施服务商的行业里面。RPA的热度之高,说是空前绝后可能有点夸张,但是说火到极致一点都没有错,R...

    RPA小葵

扫码关注云+社区

领取腾讯云代金券