【发布时间】:2015-03-20 12:36:01
【问题描述】:
我正在尝试在 R 中完成以下任务。 该网站提供印度农业数据的分区级统计数据(表格):http://agcensus.dacnet.nic.in/tehsilsummarytype.aspx 我的理解是,这被称为动态表单,因为选项会根据所做的条目而变化。具体来说,我想下载以下表格:
- 州 = 安得拉邦
- 地区 = 阿迪拉巴德、阿南塔普尔、卡达帕、...(共 8 个)
- Tahsil = Mancherial、Kasipet(这只是 District = Adilabad 的 2 个示例;总共 158 个)
然后我想要所有社会群体、所有性别和总数的“按规模平均持有量”。
基于这篇文章What if I want to web scrape with R for a page with parameters? 我认为要走的路是使用getHTMLFormDescription()。但是,由于我的表单是动态的,因此我无法遵循另一篇文章中建议的路线。 createFunction() 行返回错误: "*writeFunction(formDescription, character(), url, con, verbose = verbose, 中的错误:您应该在此处提供表单描述。请参阅 getFormDescription()。"
在可以从omegahat网页下载的RHTMLForms包中, 有这个功能(顾名思义)应该做我需要的:
function function(desc, omit = character(), drop = TRUE, ..., verbose = FALSE) {
# Discard the elements that we are omitting.
if(length(omit)) {
idx = match(omit, names(desc$elements), 0)
k = class(desc$elements)
desc$elements <- desc$elements[-idx]
class(desc$elements) = k }
# If no more elements left as a result of omitting them, just return the description
# as there are definitely no more dynamic components left.
if(length(desc$elements) == 0)
return(desc)
# Now find the dynamic components.
dyn = sapply(desc$elements, inherits, "DynamicHTMLFormElement")
if(!any(dyn))
return(desc)
pivot = desc$elements[[min(which(dyn))]]
# We will need to submit the form for each value of this dynamic element, so
# get the URI. If the URI changes depending on the value, we are out of luck!!
url = mergeURI(URI(desc$formAttributes["action"]), URI(desc$url))
# Prepare the return value with the pivot information and we will build up
# the branches by looping over the possible values.
descriptions = list(elementName = pivot$name,
description = pivot,
values = list())
omit = c(omit, pivot$name)
for(i in names(pivot$options)) {
# Create the arguments for the submission. We may need to include them all.
args = list(i)
names(args)[1] = pivot$name
if(verbose)
cat("Checking ", pivot$name, " - option", i, "\n")
#XX we may need to provide all the arguments rather than just this one.
# or perhaps cumulate them for the elements we have already deal with.
# We have the defaults and the possible values from the original description.
page = formQuery(args, toString(url), desc, .checkArgs = FALSE, ...)
# Make certain that we turn the checkDynamic off here to avoid recursively.
tmp = getHTMLFormDescription(page, asText = TRUE, handlers = multiFormElementHandlers(url, checkDynamic = FALSE))
tmp = getDynamicHTMLFormDescription(tmp, omit = omit)
# Now remove the elements that we are omitting. This leaves a subset of the form.
if(drop) {
idx = match(omit, names(tmp$elements), 0)
if(any(is.na(idx))) {
k = class(tmp$elements)
tmp$elements = tmp$elements[is.na(idx)]
class(tmp$elements) = k
}
class(tmp) <- c("HTMLFormSubset", class(tmp))
}
descriptions$values[[i]] = tmp
}
class(descriptions) <- c("DynamicFormElementPath")
descriptions
}
但是,我也无法让它工作 - 调用 getDynamicHTMLFormDescription("http://agcensus.dacnet.nic.in/tehsilsummarytype.aspx") 给出“desc$elements 中的错误:$ 运算符对原子向量无效”。
有人对如何解决这个问题提出建议吗?一旦我有办法填写表格并访问每个分区 (tahsil) 的表格,我就知道如何获得数据。这实际上只是让 R 填写这个(特定的)表格。
欢迎任何帮助! 迈克尔·凯撒 (加州大学圣地亚哥分校研究助理)
【问题讨论】:
-
选择“Andhra Pradesh”时,“Dirich”下拉菜单显示23个条目,而不是您上面提到的8个条目。这是一个错字还是您对这 23 个区域中的 8 个特定区域感兴趣?
-
对此感到抱歉 - 我应该更具体一些。是的,我对这 23 个区中的 8 个区感兴趣。
标签: html asp.net r dynamic web-scraping