R - 使用 rvest 进行网页抓取

R - form web scraping with rvest

首先,我想花点时间感谢 SO 社区, 您过去曾多次帮助我,而我什至不需要创建帐户。

我目前的问题涉及使用 R 进行网页抓取。这不是我的强项。

我要报废http://www.cbs.dtu.dk/services/SignalP/

我尝试过的:

    library(rvest)
    url <- "http://www.cbs.dtu.dk/services/SignalP/"
    seq <- "MTSKTCLVFFFSSLILTNFALAQDRAPHGLAYETPVAFSPSAFDFFHTQPENPDPTFNPCSESGCSPLPVAAKVQGASAKAQESDIVSISTGTRSGIEEHGVVGIIFGLAFAVMM"

    session <- rvest::html_session(url)
    form <- rvest::html_form(session)[[2]]
    form <- rvest::set_values(form, `SEQPASTE` = seq)
    form_res_cbs <- rvest::submit_form(session, form)
    #rvest prints out:
    Submitting with 'trunc'

rvest::html_text(rvest::html_nodes(form_res_cbs, "head")) 
#ouput:
"Configuration error"

rvest::html_text(rvest::html_nodes(form_res_cbs, "body"))

#ouput:
"Exception:WebfaceConfigErrorPackage:Webface::service : 358Message:Unhandled #parameter 'NULL' in form "

我不确定未处理的参数是什么。 问题出在提交按钮上吗?我好像不能给力:

form_res_cbs <- rvest::submit_form(session, form, submit = "submit")
#rvest prints out
Error: Unknown submission name 'submit'.
Possible values: trunc

问题是 submit$name 是 NULL 吗?

form[["fields"]][[23]] 

我尝试按照此处的建议定义伪造的提交按钮:

运气不好。

我愿意接受使用 rvest 或 RCurl/httr 的解决方案,我想避免使用 RSelenium

编辑:感谢 hrbrmstr 的精彩回答,我能够为此任务构建一个函数。它在包 ragp 中可用:https://github.com/missuse/ragp

嗯,这是可行的。但这将需要肘部润滑脂。

这部分:

library(rvest)
library(httr)
library(tidyverse)

POST(
  url = "http://www.cbs.dtu.dk/cgi-bin/webface2.fcgi",
  encode = "form",
  body=list(
    `configfile` = "/usr/opt/www/pub/CBS/services/SignalP-4.1/SignalP.cf",
    `SEQPASTE` = "MTSKTCLVFFFSSLILTNFALAQDRAPHGLAYETPVAFSPSAFDFFHTQPENPDPTFNPCSESGCSPLPVAAKVQGASAKAQESDIVSISTGTRSGIEEHGVVGIIFGLAFAVMM",
    `orgtype` = "euk",
    `Dcut-type` = "default",
    `Dcut-noTM` = "0.45",
    `Dcut-TM` = "0.50",
    `graphmode` = "png",
    `format` = "summary",
    `minlen` = "",
    `method` = "best",
    `trunc` = ""
  ),
  verbose()
) -> res

提出您提出的要求。我把 verbose() 留在了里面,所以你可以看看会发生什么。它缺少 "filename" 字段,但您指定了字符串,因此它很好地模仿了您所做的。

现在,棘手的部分是它使用中间重定向页面,让您有机会输入电子邮件地址以在查询完成时收到通知。它确实会定期(每隔 10 秒左右)检查查询是否已完成,如果是,则会快速重定向。

该页面具有可通过以下方式提取的查询 ID:

content(res, as="parsed") %>% 
  html_nodes("input[name='jobid']") %>% 
  html_attr("value") -> jobid

现在,我们可以模拟最终请求,但我会在这样做之前添加 Sys.sleep(20) 以确保报告已完成。

GET(
  url = "http://www.cbs.dtu.dk/cgi-bin/webface2.fcgi",
  query = list(
    jobid = jobid,
    wait = "20"
  ),
  verbose()
) -> res2

即抓取最终结果页面:

html_print(HTML(content(res2, as="text")))

您可以看到图像丢失,因为 GET 仅检索 HTML 内容。您可以使用 rvest/xml2 中的函数来解析页面并抓取表格和 URL,然后您可以使用它们来获取新内容。

为了做到这一切,我使用 burpsuite to intercept a browser session and then my burrp R 包来检查结果。您还可以在 burpsuite 中目视检查并更手动地构建东西。