【问题标题】:Scraping table from ASP.NET webpage with JavaScript buttons using R使用 R 从带有 JavaScript 按钮的 ASP.NET 网页中抓取表格
【发布时间】:2014-03-04 08:14:23
【问题描述】:

我已经倾注了相关的问题,但无济于事。我需要根据我指定的日期和时间从 ASP.NET 网页 (http://www.spp.org/LIP.asp) 中抓取价格信息表。我很喜欢并想使用 R。我的基本绊脚石是 URL 不反映搜索参数,它是静态的,而且我也不知道如何在 ASP.NET 上提交带有 Javascript 的 HTML 表单网站。

我查看了上面 URL 的源代码。我发现在 iframe 中有一个指向另一个“源数据”页面的链接:http://www.spp.org/LIPPosting/LIP.aspx。我尝试根据这个 StackOverflow 线程在 R 中执行 POST 请求:What if I want to web scrape with R for a page with parameters?

##ASP.NET site scrape
forms = getHTMLFormDescription("http://www.spp.org/LIPPosting/LIP.aspx")
# Name the list for easy reference
names(forms)='spp'
# Use the createFunction tool so I can submit a search
fun = createFunction(forms$spp, verbose=T)
# Submit an HTML form looking for data using all form defaults
# Except change the hour to '03'
results <- fun(ddlHour = '03')
# Grab the table results from the HTML based on its id tag  
tableData <- getNodeSet(htmlParse(results), "//*/table[@id = 'dgLIP']")
readHTMLTable(tableData[[1]])

HTML 结果显示,在“小时”表单元素中,我确实选择了“03”。

           <td style="height: 42px; width: 77px;">
<span id="lblLIPHour">Hour</span><br><select name="ddlHour" id="ddlHour"><option value="1">01</option>
<option value="2">02</option>
<option selected value="3">03</option>
<option value="4">04</option>
<option value="5">05</option>
<option value="6">06</option>
<option value="7">07</option>
<option value="8">08</option>

但是,此请求不会传递到服务器,因为当我查看实际表结果时,它是当前时间,而不是“03”。

> readHTMLTable(tableData[[1]])
   Publish Date   Price Date                PNode Price        Parent PNode Settlement Location
1  201402281552 201402281600                 AECI 23.45                AECI                AECI
2  201402281552 201402281600                 AMRN 23.45                AMRN                AMRN
3  201402281552 201402281600                 BLKW 23.45                BLKW                BLKW
4  201402281552 201402281600                 CLEC 23.45                CLEC                CLEC
5  201402281552 201402281600         CSWS_AECC_LA 23.45        CSWS_AECC_LA           AECC_CSWS

此外,我只能获取从服务器返回的页面的 HTML,它不包含所有结果。实际上,该页面底部有 JavaScript 箭头按钮,当我在网页中时,它们允许我在所有结果之间切换。

在网页本身中,要从下拉菜单中选择后查看结果,我必须点击“查看”按钮。有没有办法在 R 中复制它以将我的“03”参数作为查询发送到服务器以将新的 HTML 返回到网页?

如果我能做到这一点,我也可以写一些东西来“推动”页面箭头。

【问题讨论】:

  • 我希望其他人能给你更多乐观的理由,但我的建议是不要这样做。使用 python 和 selenium 驱动程序,即使你事先不了解 python,也会容易得多。我这样说是作为一个热爱 R 并试图将它用于所有事情的人,但在这种情况下,我认为它不是适合这项工作的工具。
  • 感谢 Ista...在进入这个小泡菜之前,我从未听说过 Selenium。您认为使用 Python 驱动程序优于下面 jdharrison 建议的 R 包吗?

标签: javascript asp.net r http rcurl


【解决方案1】:

您可以为此使用 Selenium。见http://johndharrison.github.io/RSelenium/。免责声明我是 RSelenium 软件包的作者。可以在RSelenium basicsRSelenium: Testing Shiny apps

require(RSelenium)
# RSelenium::startServer() # if needed
remDr <- remoteDriver()
remDr$open()
remDr$setImplicitWaitTimeout(3000)
remDr$navigate("http://www.spp.org/LIP.asp")
remDr$switchToFrame("content_frame")
dateElem <- remDr$findElement(using = "id", "txtLIPDate") # select the date
dateRequired <- "01/14/2014"
dateElem$clearElement()
dateElem$sendKeysToElement(list("01/14/2014", key = "enter")) # send a date to app
hourElem <- remDr$findElement(using = "css selector", '#ddlHour [value="5"]') # select the 5th hour
hourElem$clickElement() # select this hour
buttonElem <-remDr$findElement(using = "id", "cmdView")
buttonElem$clickElement() # click the view button

#Sys.sleep(5)
tableElem <- remDr$findElement(using = "id", "dgLIP")
readHTMLTable(htmlParse(tableElem$getElementAttribute("outerHTML")[[1]]))

[1] "tableElem$getElementAttribute(\"outerHTML\")"
$dgLIP
V1           V2                   V3    V4                  V5                  V6
1  Publish Date   Price Date                PNode Price        Parent PNode Settlement Location
2  201401132252 201401132300                 AECI 19.14                AECI                AECI
3  201401132252 201401132300                 AMRN 18.87                AMRN                AMRN
4  201401132252 201401132300                 BLKW 20.28                BLKW                BLKW
5  201401132252 201401132300                 CLEC 18.99                CLEC                CLEC
6  201401132252 201401132300         CSWS_AECC_LA 19.77        CSWS_AECC_LA           AECC_CSWS
7  201401132252 201401132300  CSWS_GREEN_LIGHT_LA  18.5 CSWS_GREEN_LIGHT_LA        GSEC_GL_CSWS
8  201401132252 201401132300              CSWS_LA 19.01             CSWS_LA           AEPM_CSWS
9  201401132252 201401132300              CSWS_LA 19.01             CSWS_LA            AEP_LOSS
10 201401132252 201401132300         CSWS_OMPA_LA 18.66        CSWS_OMPA_LA           OMPA_CSWS
11 201401132252 201401132300      CSWS_TENASKA_LA 18.95     CSWS_TENASKA_LA        GATEWAY_LOAD
12 201401132252 201401132300      CSWS112_WGORLD1  18.7             CSWS_LA           AEPM_CSWS
13 201401132252 201401132300      CSWS112_WGORLD1  18.7             CSWS_LA            AEP_LOSS
14 201401132252 201401132300      CSWS116PEORILD1  18.9             CSWS_LA           AEPM_CSWS
15 201401132252 201401132300      CSWS116PEORILD1  18.9             CSWS_LA            AEP_LOSS
16 201401132252 201401132300    CSWS121EASTLDXFL1 18.92             CSWS_LA           AEPM_CSWS
17 201401132252 201401132300    CSWS121EASTLDXFL1 18.92             CSWS_LA            AEP_LOSS
18 201401132252 201401132300      CSWS121LYNN4LD1 18.91             CSWS_LA           AEPM_CSWS
19 201401132252 201401132300      CSWS121LYNN4LD1 18.91             CSWS_LA            AEP_LOSS
20 201401132252 201401132300   CSWS12TH_STLD69_12 18.92             CSWS_LA           AEPM_CSWS
21 201401132252 201401132300   CSWS12TH_STLD69_12 18.92             CSWS_LA            AEP_LOSS
22 201401132252 201401132300 CSWS12TH_STLD69_12_2 18.92             CSWS_LA           AEPM_CSWS
23 201401132252 201401132300 CSWS12TH_STLD69_12_2 18.92             CSWS_LA            AEP_LOSS
24 201401132252 201401132300      CSWS136_YALELD1  18.9             CSWS_LA           AEPM_CSWS
25 201401132252 201401132300      CSWS136_YALELD1  18.9             CSWS_LA            AEP_LOSS
26 201401132252 201401132300  CSWS141_PINELDXFMR1 19.09             CSWS_LA           AEPM_CSWS
27          < >         <NA>                 <NA>  <NA>                <NA>                <NA>

【讨论】:

  • 好吧,我很感兴趣!我要在星期一试一试
  • 我被困在 'remDr$open()' 得到错误'函数错误(类型,msg,asError = TRUE):无法连接到主机'。我使用 devtools 包安装在 R 中并从 GitHub 下载。
  • @sclarky 您需要运行 selenium 服务器 请参阅 RSelenium 基础小插图。
  • 对不起@jdharrison,这对我来说是一门外语。我同时运行了 checkserver 和 startserver 函数,当我导航到 RSelenium 包中的 bin 文件夹时,selenium jar 文件就在那里。但是我仍然收到错误
  • 这可能是 java 的问题。您是否在该系统上安装了 Java 或 Java + JDK?您可以检查如下 1. 转到命令提示符 2. 键入“java -version”
【解决方案2】:

为了后代,我还想提供我用于在结果页面之间单击页面的代码(没有“显示全部”选项)。我让 RSelenium 单击所有页面,直到不再有“向前单击”选项。在每一页上,它都会将 HTML 表格刮成一个列表:

# Get the first page of results
tableElem <- remDr$findElement(using = "id", "dgLIP")
tmp <- readHTMLTable(htmlParse(tableElem$getElementAttribute("outerHTML")[[1]]))
hourlyData <- list()
# Save the first table without the last row, which is gibberish
hourlyData[[1]] <- tmp[[1]][-27,]

# Click the 'greater than' arrow javascript href element to get to next page  
acc <- 2
while("javascript:__doPostBack('dgLIP$_ctl29$_ctl1','')" %in% unlist(lapply(remDr$findElements("css selector", "[href]"), function(x){x$getElementAttribute("href")}))) {
  webElems <- remDr$findElements("css selector", "[href]")
  clickers <- unlist(lapply(webElems, function(x){x$getElementAttribute("href")}))
  pager <- webElems[[which(clickers == "javascript:__doPostBack('dgLIP$_ctl29$_ctl1','')")]]
  pager$clickElement()
  tableElem <- remDr$findElement(using = "id", "dgLIP")
  tmp <- readHTMLTable(htmlParse(tableElem$getElementAttribute("outerHTML")[[1]]))
  hourlyData[[acc]] <- tmp[[1]]
  acc <- acc + 1
  Sys.sleep(3)
}

【讨论】:

    猜你喜欢
    • 2011-04-20
    • 2020-06-28
    • 2013-11-16
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    相关资源
    最近更新 更多