首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从结果页面下载CSV文件并从下拉菜单中选择

从结果页面下载CSV文件并从下拉菜单中选择
EN

Stack Overflow用户
提问于 2019-07-12 17:03:20
回答 2查看 1.5K关注 0票数 4

我是一个网络刮R的新手,我被困在这个问题上:我想使用R向PubMed提交一个搜索查询,然后从结果页面下载一个CSV文件。可以通过单击“Send”来访问CSV文件,这将打开一个下拉菜单,然后我需要选择“file”单选按钮,将“Format”选项更改为“CSV”(选项6),最后单击“Create”按钮开始下载。

几个注意事项:

  1. 是的,这种类型的远程搜索和下载符合NCBI的策略。
  2. 为什么不使用easyPubMed包呢?我已经试过了,并且正在用它做我的另一部分工作。但是,使用此包检索搜索结果时,遗漏了CSV下载中包含的一些文章元数据。

我看过这些相关的问题:在提交表格后,从网页下载csv文件,使用R中的rvest软件包下载与输入框和“单击”按钮相关联的.csv文件使用R“单击”网页上的下载文件按钮

我觉得前面由@hrbrmstr提供的解决方案包含了答案,但我不能把这些部分放在一起下载CSV文件。

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

代码语言:javascript
复制
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“搜索返回以下URL:https://www.ncbi.nlm.nih.gov/pubmed/?term=%22hello+world%22。因此,如果有必要,我可以从这里推断,并根据我的搜索查询构建结果URL。

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

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

或者,我可以在上面的表单选项中展开URL吗?就像..。

代码语言:javascript
复制
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'))

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

任何帮助都是非常感谢的!谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-08 05:46:24

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

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

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

代码语言:javascript
复制
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有您需要的信息,只是格式不同(我是通过视觉检查验证的)。

然而,为了符合您最初问题的精神(通过从NCBI中提取,给我一个CSV,使用R ),下面是一些步骤,您可以使用这些步骤来复制您可以从PubMed Web中获得的完全相同的CSV。

代码语言:javascript
复制
# 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包并不熟悉,但是我受到了代码使用NCBI的启发。您完全有可能修复/修改一些easyPubMed代码,以提取您希望从一堆CSV中获得的额外元数据。)那里没有太多东西。只有500行代码定义了8个函数。)

见鬼,如果您确实能够修改easyPubMed代码来提取额外的元数据,我建议将您的更改返回给作者,这样他们就可以改进他们的包了!

票数 1
EN

Stack Overflow用户

发布于 2019-08-09 02:40:00

使用easyPubMed包:

代码语言:javascript
复制
library(easyPubMed)
out <- batch_pubmed_download(pubmed_query_string = "hello world")
DF <- table_articles_byAuth(pubmed_data = out[1])
write.csv(DF, "helloworld.csv")

有关更多信息,请参见easyPubMed中的vignette和帮助文件。

其他的软件包有pubmed.mineR、rentrez和RISmed在CRAN上,在生物导体上有注释,在github上有小蛋糕。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57011279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档