查看原文
其他

R 爬虫之爬取文献影响因子

JunJunLab 老俊俊的生信笔记 2022-08-15


点击上方关注我们




起源



之前写的几篇文章里关于爬取文献的信息没有涉及到 影响因子 ,我们知道 scholarscope 这款插件能够在 NCBI pubmed 的每篇文献旁显示影响因子,根据影响因子的高低以 不同颜色 区分,是个非常好用的插件,对于根据筛选影响因子高低来选择阅读非常的友好。

火狐、谷歌和 win10 自带的浏览器都可以安装这款插件,之前为什么没有顺便爬取 影响因子呢?插件显示的内容 是基于在原生网页之上的,即使我们在网页元素里也是能看见的:

但是在你网络请求成功后(状态码 200 )和服务器发送给你的内容确不会显示出来:

预览面板 为服务器发送给你在网页上显示的内容:

可以看到并没有显示插件需要显示的内容,然后我在其它返回的内容里也没有找到相关的内容。

我们把页面滑倒最下面:

我们点击 show more 就可以继续浏览后面的文章了,但是网址是没有变的:

这里有两个概念:

1、静态网页: 在网站设计中,纯粹 HTML(标准通用标记语言下的一个应用)格式的网页通常被称为“静态网页”,静态网页是标准的 HTML 文件,它的文件扩展名是.htm、.html,可以包含文本、图像、声音、FLASH 动画、客户端脚本和 ActiveX 控件及 JAVA 小程序等。静态网页是网站建设的基础,早期的网站一般都是由静态网页制作的。静态网页是相对于动态网页而言,是指没有后台数据库、不含程序和不可交互的网页。

2、动态网页: 所谓的动态网页,是指跟静态网页相对的一种网页编程技术。静态网页,随着 html 代码的生成,页面的内容和显示效果就基本上不会发生变化了,除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。

我的理解是静态网页有点像我们点击下一页就进入了另外一个网址,动态的像直接在当前页面刷新出内容。我不是专业的,大家感兴趣可以去研究一下。动态网页好像都要用到 AJAX 异步加载 技术,全名:Asynchronous Javascript And XML(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。

这个技术的作用是可以使网页实现 异步的更新 ,用通俗的话来讲就是在不需要重新加载整个页面内容的情况下,也可以对网页的部分内容进行更新操作,也可以理解局部刷新操作。

我猜测对于 scholarscope 这个插件的内容显示可能跟这个动态加载啥的有关,可能与 js 加载有关,插件内容可能被隐藏起来了,所以看不到。

更多信息见:

正题



rvest 包对于爬取 静态网页 是一个很好的选择,但对于动态网页的话就有点鸡肋了,rvest 在网页请求上非常的脆弱,没有任何伪装措施和报头信息,很容易爬取失败或者被封掉。我们可以使用 httr 或者 Rcurl 进行请求获取网页内容,然后使用rvest 进行网页解析和提取内容。

也可以使用 RSelenium 包在模拟浏览器中尝试,Selenium 是一个用于 Web 应用程序测试的工具。Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。

准备:

1、首先我们需要在电脑上安装 java,并且加入环境变量里。

  • Java 环境变量设置[1]

2、下载对应浏览器的驱动程序(谷歌、火狐)

  • 火狐:https://github.com/mozilla/geckodriver/releases
  • 谷歌:http://chromedriver.storage.googleapis.com/index.html

注意:下载谷歌时注意浏览器版本和驱动版本要一致,不然会报错!

查看 chrome 版本在浏览器 设置关于 chrome 选项:

可以看到我的是 92.0.4515.107 版本的,然后我们下载驱动也下载一样版本的:

下载 win32 的,然后解压即可:

3、下载 selenium

  • 官网:http://www.seleniumhq.org/download/
  • 其它网址:http://selenium-release.storage.googleapis.com/index.html

进入第二个网址下载 4.0 的:

下载后把前面的浏览器驱动一起放在一个文件夹里,文件夹我放在桌面了:



上手



接下来我们打开 cmd,输入 javac 看是否能够输出参考文档,可以就说明你 java 已经配置好了:

Microsoft Windows [版本 10.0.19042.1110]
(c) Microsoft Corporation。保留所有权利。

C:\Users\admin>javac
用法: javac <options> <source files>
其中, 可能的选项包括:
  @<filename>                  从文件读取选项和文件名
  -Akey[=value]                传递给注释处理程序的选项
  --add-modules <模块>(,<模块>)*
        除了初始模块之外要解析的根模块; 如果 <module>
                为 ALL-MODULE-PATH, 则为模块路径中的所有模块。
  --boot-class-path <path>, -bootclasspath <path>
        覆盖引导类文件的位置
  --class-path <path>, -classpath <path>, -cp <path>
        指定查找用户类文件和注释处理程序的位置
  -d <directory>               指定放置生成的类文件的位置
  -deprecation                 输出使用已过时的 API 的源位置
  --enable-preview             启用预览语言功能。要与 -source 或 --release 一起使用。
  -encoding <encoding>         指定源文件使用的字符编码
  -endorseddirs <dirs>         覆盖签名的标准路径的位置
  -extdirs <dirs>              覆盖所安装扩展的位置
  -g                           生成所有调试信息
  -g:
{lines,vars,source}       只生成某些调试信息
  -g:none                      不生成任何调试信息
  -h <directory>               指定放置生成的本机标头文件的位置
  --help, -help, -?            输出此帮助消息
  --help-extra, -X             输出额外选项的帮助
...

然后进入我们存放驱动的文件夹:

C:\Users\admin>cd Desktop\动态爬虫

C:\Users\admin\Desktop\动态爬虫>

运行代码,这里我们使用谷歌驱动:

# 谷歌驱动
C:\Users\admin\Desktop\动态爬虫> java -Dwebdriver.chrome.driver="chromedriver.exe"  -jar selenium-server-standalone-4.0.0-alpha-2.jar

# 火狐驱动
C:\Users\admin\Desktop\动态爬虫> # java -Dwebdriver.chrome.driver="geckodriver.exe" -jar selenium-server-standalone-4.0.0-alpha-2.jar

运行状态:

C:\Users\admin\Desktop\动态爬虫>java -Dwebdriver.chrome.driver="chromedriver.exe"  -jar selenium-server-standalone-4.0.0-alpha-2.jar
15:26:29.905 INFO [GridLauncherV3.parse] - Selenium server version: 4.0.0-alpha-2, revision: f148142cf8
15:26:29.982 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
15:26:30.281 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
15:26:30.462 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444

命名提示符窗口 不要关闭,然后我们需要在 Rstudio 里进行操作了,首先安装 R 包:

# 安装R包
install.packages('RSelenium')

# 加载R包
library(rvest)
library(RSelenium)

加载浏览器驱动并打开浏览器:

# 加载浏览器驱动
remDr <- remoteDriver(
  browserName = "chrome"# chrome、firefox
  remoteServerAddr = "localhost",
  port = 4444L)

# 打开浏览器
remDr$open()

然后就会自动打开一个谷歌浏览器:

这时浏览器里面是什么都没有的,我们需要定位到我们要爬取的网址,我们还是搜索 m6A 相关的文献:

# 打开爬取的网页
url <- c('https://pubmed.ncbi.nlm.nih.gov/?term=m6a&page=1')

# 导航
remDr$navigate(url)

这时我们再打开浏览器可以看到已经打开了 m6A 的 pubmed 页面,还有受到自动测试软件的控制提示

但是这个页面没有 scholarscope 这个插件的,我们安装一下和 SelectorGadget ,然后刷新一下:

获取网页内容:

# 获取页面内容
remDr$getPageSource()
[[1]]
[1"<html lang=\"en\"><head itemscope=\"\" itemtype=\"http://schema.org/WebPage\" prefix=\"og: http://ogp.me/ns#\">\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n\n    <!-- Mobile properties -->\n
...

返回了一个 list ,应该是 html 的内容,我们取出来解析一下:

# 取出解析
remDr$getPageSource()[[1]][1] %>%
  read_html()

{html_document}
<html lang="en">
[1] <head itemscope="" itemtype="http://schema.org/WebPage" prefix="og: http://ogp.me/ns#">\n<m ...
[2] <body>\n\n  \n  \n    <noscript>\n  <div class="no-script-banner" id="no-script-banner">\n  ...

可以看到和我们解析静态网页是一样的内容,由 headbody 两个部分组成。

尝试提取文章的 期刊影响因子发表时间 试试哈:

提取文章期刊:

# 提取文章期刊
journal <- remDr$getPageSource()[[1]][1] %>%
  read_html() %>%
  html_nodes('.Scholarscope_Journal') %>%
  html_text()

journal
[1"Biomed Pharmacother"     "Front Bioeng Biotechnol" "Mol Cancer"
[4"Stem Cells"              "Microrna"                "Int J Mol Med"
[7"Cancer Med"              "J Neurochem"             "Nucleic Acids Res"
[10"Cell Death Dis"

提取文章影响因子:

# 提取文章影响因子
IF <- remDr$getPageSource()[[1]][1] %>%
  read_html() %>%
  html_nodes('.Scholarscope_Factor') %>%
  html_text()

IF
[1"6.521"     "5.894"     "27.400"    "6.271"     "Not Found" "4.103"     "4.451"
[8"5.372"     "16.970"    "8.463"

提取文章发表时间:

# 提取文章发表时间
time_up <- remDr$getPageSource()[[1]][1] %>%
  read_html() %>%
  html_nodes('.Scholarscope_Year') %>%
  html_text()

time_up
[1"2019" "2018" "2020" "2020" "2017" "2020" "2019" "2018" "2020" "2020"

可以可以,顺便把文章标题也提一下:

# 提取文章标题
title <- remDr$getPageSource()[[1]][1] %>%
  read_html() %>%
  html_nodes('.docsum-title') %>%
  html_text(trim = T)

title
[1"The role of m6A RNA methylation in cancer."
[2"Link Between m6A Modification and Cancers."
[3"The emerging roles of N6-methyladenosine (m6A) deregulation in liver carcinogenesis."
...

合并成表格:

# 合并成表格
df <- data.frame(title = title,
                 time_up = time_up,
                 journal = journal,
                 IF = IF)


批量爬取



如果批量爬取,我们构造批量网页链接放在循环里就行了,这里我们加入爬取前 2 页内容测试:

# 构造网页
url <- c()
for (i in 1:2) {
  url <- c(url,paste('https://pubmed.ncbi.nlm.nih.gov/?term=m6a&page=',i,sep = ''))
}

开始批量测试:

# 批量提取

# 创建储存内容变量
journal <- c()
IF <- c()
time_up <- c()
title <- c()

for(i in 1:length(url)){
  # 导航
  remDr$navigate(url[i])
  # 获取页面内容
  remDr$getPageSource()
  # 提取文章期刊
  journal <- c(journal,remDr$getPageSource()[[1]][1] %>% read_html() %>% html_nodes('.Scholarscope_Journal') %>% html_text())
  # 提取文章影响因子
  IF <- c(IF,remDr$getPageSource()[[1]][1] %>% read_html() %>% html_nodes('.Scholarscope_Factor') %>% html_text())
  # 提取文章发表时间
  time_up <- c(time_up,remDr$getPageSource()[[1]][1] %>% read_html() %>% html_nodes('.Scholarscope_Year') %>% html_text())
  # 提取文章标题
  title <- c(title,remDr$getPageSource()[[1]][1] %>% read_html() %>% html_nodes('.docsum-title') %>% html_text(trim = T))
}

# 合并内容
df <- data.frame(title = title,
                 time_up = time_up,
                 journal = journal,
                 IF = IF)

查看内容:

验证一下:

是对应的上的,爬取结束后可以使用一下命令关掉网页,或者直接手动关掉也行:

# 关闭网页
remDr$closeWindow()

# 直接退出
remDr$quit()

# close用于关闭当前会话,也可以用作关闭浏览器
remDr$close()

结合我之前文章里的爬取文章的摘要文章链接下载链接、最后汇总为一个表格就完美了,大家自己去试试吧!

今天终于把这个问题解决了!后面也会出关于爬取 httr 爬取动态网页的文章。

参考资料

[1]

Java 环境变量设置: https://blog.csdn.net/badboy2008/article/details/41316253


所以今天你学习了吗?

发现更多精彩

关注公众号

欢迎小伙伴留言评论!

今天的分享就到这里了,敬请期待下一篇!

最后欢迎大家分享转发,您的点赞是对我的鼓励肯定

如果觉得对您帮助很大,赏杯快乐水喝喝吧!

推 荐 阅 读




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存