带有 jsessionid 的 R 网络抓取工具
R web scraper with jsessionid
我正在 R 中测试一些网络抓取脚本。我已经阅读了很多教程、文档并尝试了不同的东西,但到目前为止没有成功。
我要抓取的 URL 是 this one。它有 public、政府数据,并且没有针对网络抓取工具的声明。虽然是葡萄牙语,但相信问题不大。
它显示了一个搜索表单,其中包含多个字段。我的测试是搜索来自特定州("RJ",在本例中字段为 "UF")和城市("Rio de Janeiro",在字段 "MUNICIPIO" 中)的数据。通过单击 "Pesquisar"(搜索),它显示以下输出:
使用Firebug,我发现它调用的URL(使用上面的参数)是:
http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam?buscaForm=buscaForm&codEntidadeDecorate%3AcodEntidadeInput=&noEntidadeDecorate%3AnoEntidadeInput=&descEnderecoDecorate%3AdescEnderecoInput=&estadoDecorate%3A**estadoSelect=33**&municipioDecorate%3A**municipioSelect=3304557**&bairroDecorate%3AbairroInput=&pesquisar.x=42&pesquisar.y=16&javax.faces.ViewState=j_id10
站点使用了一个jsessionid,使用如下可以看出:
library(rvest)
library(httr)
url <- GET("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/")
cookies(url)
知道它使用 jsessionid,我使用 cookies(url) 来检查此信息,并将其用于新的 URL,如下所示:
url <- read_html("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam;jsessionid=008142964577DBEC622E6D0C8AF2F034?buscaForm=buscaForm&codEntidadeDecorate%3AcodEntidadeInput=33108064&noEntidadeDecorate%3AnoEntidadeInput=&descEnderecoDecorate%3AdescEnderecoInput=&estadoDecorate%3AestadoSelect=org.jboss.seam.ui.NoSelectionConverter.noSelectionValue&bairroDecorate%3AbairroInput=&pesquisar.x=65&pesquisar.y=8&javax.faces.ViewState=j_id2")
html_text(url)
嗯,输出没有数据。事实上,它有一个错误信息。翻译成英文,它基本上是说会话已过期。
我认为这是一个基本错误,但我环顾四周,找不到克服这个问题的方法。
这个组合对我有用:
library(curl)
library(xml2)
library(httr)
library(rvest)
library(stringi)
# warm up the curl handle
start <- GET("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam")
# get the cookies
ck <- handle_cookies(handle_find("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam")$handle)
# make the POST request
res <- POST("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam;jsessionid=" %s+% ck[1,]$value,
user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:40.0) Gecko/20100101 Firefox/40.0"),
accept("*/*"),
encode="form",
multipart=FALSE, # this gens a warning but seems to be necessary
add_headers(Referer="http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam"),
body=list(`buscaForm`="buscaForm",
`codEntidadeDecorate:codEntidadeInput`="",
`noEntidadeDecorate:noEntidadeInput`="",
`descEnderecoDecorate:descEnderecoInput`="",
`estadoDecorate:estadoSelect`=33,
`municipioDecorate:municipioSelect`=3304557,
`bairroDecorate:bairroInput`="",
`pesquisar.x`=50,
`pesquisar.y`=15,
`javax.faces.ViewState`="j_id1"))
doc <- read_html(content(res, as="text"))
html_nodes(doc, "table")
## {xml_nodeset (5)}
## [1] <table border="0" cellpadding="0" cellspacing="0" class="rich-tabpanel " id="j_id17" sty ...
## [2] <table border="0" cellpadding="0" cellspacing="0">\n <tr>\n <td>\n <img alt="" ...
## [3] <table border="0" cellpadding="0" cellspacing="0" id="j_id18_shifted" onclick="if (RichF ...
## [4] <table border="0" cellpadding="0" cellspacing="0" style="height: 100%; width: 100%;">\n ...
## [5] <table border="0" cellpadding="10" cellspacing="0" class="dr-tbpnl-cntnt-pstn rich-tabpa ...
我使用 BurpSuite 检查发生了什么,并在命令行中使用 "Copy as cURL" 的输出进行了快速测试并添加 --verbose
我可以验证正在发生的事情sent/received。然后我模仿了 curl
参数。
从裸搜索页面开始,会话 ID 和 bigip 服务器的 cookie 已经预热(即,将随每个请求一起发送,因此您不必弄乱它们)但您仍然需要将其填写在 URL 路径中,因此我们必须检索它们,然后填写。
我正在 R 中测试一些网络抓取脚本。我已经阅读了很多教程、文档并尝试了不同的东西,但到目前为止没有成功。
我要抓取的 URL 是 this one。它有 public、政府数据,并且没有针对网络抓取工具的声明。虽然是葡萄牙语,但相信问题不大。
它显示了一个搜索表单,其中包含多个字段。我的测试是搜索来自特定州("RJ",在本例中字段为 "UF")和城市("Rio de Janeiro",在字段 "MUNICIPIO" 中)的数据。通过单击 "Pesquisar"(搜索),它显示以下输出:
使用Firebug,我发现它调用的URL(使用上面的参数)是:
http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam?buscaForm=buscaForm&codEntidadeDecorate%3AcodEntidadeInput=&noEntidadeDecorate%3AnoEntidadeInput=&descEnderecoDecorate%3AdescEnderecoInput=&estadoDecorate%3A**estadoSelect=33**&municipioDecorate%3A**municipioSelect=3304557**&bairroDecorate%3AbairroInput=&pesquisar.x=42&pesquisar.y=16&javax.faces.ViewState=j_id10
站点使用了一个jsessionid,使用如下可以看出:
library(rvest)
library(httr)
url <- GET("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/")
cookies(url)
知道它使用 jsessionid,我使用 cookies(url) 来检查此信息,并将其用于新的 URL,如下所示:
url <- read_html("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam;jsessionid=008142964577DBEC622E6D0C8AF2F034?buscaForm=buscaForm&codEntidadeDecorate%3AcodEntidadeInput=33108064&noEntidadeDecorate%3AnoEntidadeInput=&descEnderecoDecorate%3AdescEnderecoInput=&estadoDecorate%3AestadoSelect=org.jboss.seam.ui.NoSelectionConverter.noSelectionValue&bairroDecorate%3AbairroInput=&pesquisar.x=65&pesquisar.y=8&javax.faces.ViewState=j_id2")
html_text(url)
嗯,输出没有数据。事实上,它有一个错误信息。翻译成英文,它基本上是说会话已过期。
我认为这是一个基本错误,但我环顾四周,找不到克服这个问题的方法。
这个组合对我有用:
library(curl)
library(xml2)
library(httr)
library(rvest)
library(stringi)
# warm up the curl handle
start <- GET("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam")
# get the cookies
ck <- handle_cookies(handle_find("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam")$handle)
# make the POST request
res <- POST("http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam;jsessionid=" %s+% ck[1,]$value,
user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:40.0) Gecko/20100101 Firefox/40.0"),
accept("*/*"),
encode="form",
multipart=FALSE, # this gens a warning but seems to be necessary
add_headers(Referer="http://www.dataescolabrasil.inep.gov.br/dataEscolaBrasil/home.seam"),
body=list(`buscaForm`="buscaForm",
`codEntidadeDecorate:codEntidadeInput`="",
`noEntidadeDecorate:noEntidadeInput`="",
`descEnderecoDecorate:descEnderecoInput`="",
`estadoDecorate:estadoSelect`=33,
`municipioDecorate:municipioSelect`=3304557,
`bairroDecorate:bairroInput`="",
`pesquisar.x`=50,
`pesquisar.y`=15,
`javax.faces.ViewState`="j_id1"))
doc <- read_html(content(res, as="text"))
html_nodes(doc, "table")
## {xml_nodeset (5)}
## [1] <table border="0" cellpadding="0" cellspacing="0" class="rich-tabpanel " id="j_id17" sty ...
## [2] <table border="0" cellpadding="0" cellspacing="0">\n <tr>\n <td>\n <img alt="" ...
## [3] <table border="0" cellpadding="0" cellspacing="0" id="j_id18_shifted" onclick="if (RichF ...
## [4] <table border="0" cellpadding="0" cellspacing="0" style="height: 100%; width: 100%;">\n ...
## [5] <table border="0" cellpadding="10" cellspacing="0" class="dr-tbpnl-cntnt-pstn rich-tabpa ...
我使用 BurpSuite 检查发生了什么,并在命令行中使用 "Copy as cURL" 的输出进行了快速测试并添加 --verbose
我可以验证正在发生的事情sent/received。然后我模仿了 curl
参数。
从裸搜索页面开始,会话 ID 和 bigip 服务器的 cookie 已经预热(即,将随每个请求一起发送,因此您不必弄乱它们)但您仍然需要将其填写在 URL 路径中,因此我们必须检索它们,然后填写。