使用下拉菜单中的选项从结果页面下载 CSV 文件

炖肉

我是使用 R 进行网络抓取的新手,但我遇到了这个问题:我想使用 R 向PubMed提交搜索查询,然后从结果页面下载 CSV 文件。可以通过单击“发送到”访问 CSV 文件,这会打开一个下拉菜单,然后我需要选择“文件”单选按钮,将“格式”选项更改为“CSV”(选项 6),最后单击“创建文件”按钮开始下载。

一些注意事项:
1. 是的,这种远程搜索和下载符合 NCBI 的政策。
2.你为什么不使用这个easyPubMed包?我已经尝试过这个,并将它用于我工作的另一部分。但是,使用此包检索搜索结果会遗漏 CSV 下载包含的一些文章元数据。

我已经查看了这些相关问题:使用 R 中的 rvest 包从下拉列表提交表单后从网页下载 csv 文件R 下载绑定到输入框和“单击”按钮的 .csv 文件使用 R“单击”上的下载文件按钮一个网页

我觉得@hrbrmstr 提供的以前的解决方案包含答案,但我无法将这些部分放在一起下载 CSV 文件。

我认为这个问题的优雅解决方案是一个两步过程:1)POST对 PubMed 和GET结果的搜索请求,以及 2) 向POST结果页面提交第二个请求(或以某种方式在其中导航),并选择下载所需的选项CSV 文件。我已经尝试了以下玩具搜索查询(“hello world”,带引号,目前返回 6 个结果)...

query <- '"hello world"'
url <- 'https://www.ncbi.nlm.nih.gov/pubmed/'

html_form(html_session(url)) # enter query using 'term'
# post search and retrieve results
session <- POST(url,body = list(term=query),encode='form')

# scrape results to check that above worked
content(session) %>% html_nodes('#maincontent > div > div:nth-child(5)') %>% 
  html_text()
content(session) %>% html_nodes('#maincontent > div > div:nth-child(5)') %>% 
  html_nodes('p') %>% html_text()

# view html nodes of dropdown menu -- how to 'click' these via R?
content(session) %>% html_nodes('#sendto > a')
content(session) %>% html_nodes('#send_to_menu > fieldset > ul > li:nth-child(1) > label')
content(session) %>% html_nodes('#file_format')
content(session) %>% html_nodes('#submenu_File > button')

# submit request to download CSV file
POST(session$url, # I know this doesn't work, but I would hope something similar is possible
     encode='form',
     body=list('EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.SendTo'='File',
               'EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.FFormat'=6,
               'EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.SendToSubmit'=1),
     write_disk('results.csv'))

上面的最后一行失败——下载了一个 CSV 文件,但它包含来自 POST 请求的 html 结果。理想情况下,如何编辑最后一行以获得所需的 CSV 文件?

***一个可能的黑客是直接跳到结果页面。换句话说,我知道提交“hello world”搜索会返回以下 URL:https://www.ncbi.nlm.nih.gov/pubmed/?term=%22hello+world%22因此,如有必要,我可以从这里推断并根据我的搜索查询构建结果 URL。

我已尝试将此 URL 插入到上面的行中,但它仍然没有返回所需的 CSV 文件。我可以使用以下命令查看表单字段...

# view form options on the results page
html_form(html_session('https://www.ncbi.nlm.nih.gov/pubmed/?term=%22hello+world%22'))

或者,我可以在知道上述表单选项的情况下扩展 URL 吗?就像是...

url2 <- 'https://www.ncbi.nlm.nih.gov/pubmed/?term=%22hello+world%22&EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.SendTo=File&EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.FFormat=6&EntrezSystem2.PEntrez.PubMed.Pubmed_ResultsPanel.Pubmed_DisplayBar.SendToSubmit=1'
POST(url2,write_disk('results2.csv'))

我希望下载包含文章元数据的 6 个结果的 CSV 文件,但是,我正在获取结果页面的 html。

任何帮助是极大的赞赏!谢谢你。

D.伍兹

如果我将您的问题重新定义为:“我想使用 R 向 PubMed 提交搜索查询,然后下载与结果页面上的CSV 下载选项中提供的信息相同的信息。”

然后,我认为您可以跳过抓取和 Web UI 自动化,直接转到NIH 为此目的提供API

此 R 代码的第一部分执行相同的搜索(“hello world”)并以 JSON 格式获得相同的结果(随意将search_url链接粘贴到浏览器中以进行验证)。

library(httr)
library(jsonlite)
library(tidyverse)

# Search for "hello world"
search_url <- "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=%22hello+world%22&format=json"

# Search for results
search_result <- GET(search_url)

# Extract the content
search_content <- content(search_result, 
                          type = "application/json",
                          simplifyVector = TRUE)

# search_content$esearchresult$idlist
# [1] "29725961" "28103545" "27567633" "25955529" "22999052" "19674957"

# Get a vector of the search result IDs
result_ids <- search_content$esearchresult$idlist

# Get a summary for id 29725961 (the first one).
summary_url <- "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&version=2.0&id=29725961&format=json" # 

summary_result <- GET(summary_url)

# Extract the content
summary_content <- content(summary_result, 
                          type = "application/json")

据推测,您可以从这里获取它,因为列表summary_content包含您需要的信息,只是格式不同(我通过目视检查进行了验证)。

但是,为了符合您原始问题的精神(给我一个 CSV,使用 R,从 NCBI 中提取),以下是您可以用来重现与 PubMed 完全相同的 CSV 的一些步骤面向人类的 Web UI。

# Quickie cleanup (thanks to Tony ElHabr)
# https://www.r-bloggers.com/converting-nested-json-to-a-tidy-data-frame-with-r/
summary_untidy <- enframe(unlist(summary_content))

# Get rid of *some* of the fluff...
summary_tidy <- summary_untidy %>% 
  filter(grepl("result.29725961", name)) %>% 
  mutate(name = sub("result.29725961.", "", name))

# Convert the multiple author records into a single comma-separated string.
authors <- summary_tidy %>% 
  filter(grepl("^authors.name$", name)) %>% 
  summarize(pasted = paste(value, collapse = ", "))

# Begin to construct a data frame that has the same information as the downloadable CSV
summary_csv <- tibble(
  Title = summary_tidy %>% filter(name == "title") %>% pull(value),
  URL = sprintf("/pubmed/%s", summary_tidy %>% filter(name == "uid") %>% pull(value)),
  Description = pull(authors, pasted),
  Details = "... and so on, and so on, and so on... "
)

# Write the sample data frame to a csv.
write_csv(summary_csv, path = "just_like_the_search_page_csv.csv")

我不熟悉easyPubMed你提到包,但我通过挖掘easyPubMed代码受到启发使用 NCBI API 您完全有可能修复/调整一些easyPubMed代码以提取您希望从提取一堆 CSV 中获得的额外元数据。(那里没有很多。只有 500 行代码定义了 8 个函数。)

哎呀,如果您确实设法调整 easyPubMed 代码以提取额外的元数据,我建议将您的更改返回给作者,以便他们改进他们的包!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章