如何刮这个squawka页面?

时间:2014-03-01 22:06:20

标签: python r python-2.7 web-scraping screen-scraping

我试图提取以下信息:

在页面上

http://epl.squawka.com/stoke-city-vs-arsenal/01-03-2014/english-barclays-premier-league/matches

按下红色的“完整统计”按钮会打开一个菜单,其中包括(在左侧)“十字架”按钮。这将在屏幕的右侧打开一个足球场的图像,上面有19个箭头,这些是斯托克在斯托克 - 阿森纳比赛中的传球。它们是彩色编码的,红色=未完成,绿色=完成,黄色=键通过。 当你点击箭头时,它会告诉你谁给了传球以及在什么时间比赛。 此外,箭头显示了球员在传球时的位置以及球员传球的位置。

我希望能够抓住这个页面,以便我得到一个包含列的表:

团队;名称的发送者;位置的发送者;位置的接收器;分钟;颜色的箭头

这是斯托克的交叉传球,我也想自动为阿森纳重复一遍(因此,上表中的“俱乐部”栏目。)

虽然我过去曾经抓过网页,但这些都是静态相当直接的页面,我对于如何从这个页面中抓取信息感到茫然。 我真的很感谢如何刮取我刚才描述的数据。我精通R,所以我特别感谢能帮助我在R中实现这一目标的代码,但我也非常感谢使用其他语言或软件的帮助。

谢谢你, 彼得

1 个答案:

答案 0 :(得分:9)

彼得这些家伙表示你可以用Selenium做到这一点。我也喜欢使用优秀的selectr package 想法是简单地与网站互动,然后在其他地方做其余的事情。 squawkData应包含所需的一切。

# RSelenium::startServer() # if needed
require(RSelenium)
remDr <- remoteDriver()
remDr$open()
remDr$setImplicitWaitTimeout(3000)
remDr$navigate("http://epl.squawka.com/stoke-city-vs-arsenal/01-03-2014/english-barclays-premier-league/matches")
squawkData <- remDr$executeScript("return new XMLSerializer().serializeToString(squawkaDp.xml);", list())
require(selectr)
example <- querySelectorAll(xmlParse(squawkData[[1]]), "crosses time_slice")
example[[1]]


<time_slice name="0 - 5" id="1">
  <event player_id="531" mins="4" secs="39" minsec="279" team="44" type="Failed">
    <start>73.1,87.1</start>
    <end>97.9,49.1</end>
  </event>
</time_slice> 

免责声明我是RSelenium软件包的作者。可以在RSelenium basicsRSelenium: Testing Shiny apps查看有关操作的基本内容 {{3}}

使用selectr可以轻松访问更多信息:

> xmlValue(querySelectorAll(xmlParse(squawkData[[1]]), "players #531 name")[[1]])
[1] "Charlie Adam"

> xmlValue(querySelectorAll(xmlParse(squawkData[[1]]), "game team#44 long_name")[[1]])
[1] "Stoke City"

更新:
要将示例处理为数据框,您可以执行类似

的操作
out <- lapply(example, function(x){
# handle each event
  if(length(x['event']) > 0){
    res <- lapply(x['event'], function(y){
      matchAttrs <- as.list(xmlAttrs(y))
      matchAttrs$start <- xmlValue(y['start']$start)
      matchAttrs$end <- xmlValue(y['end']$end)
      matchAttrs
    })
    return(do.call(rbind.data.frame, res))
  }
}
)

> head(do.call(rbind, out))
        player_id mins secs minsec team   type     start       end
event         531    4   39    279   44 Failed 73.1,87.1 97.9,49.1
event5        311    6   33    393   31 Failed 92.3,13.1 93.0,31.0
event1        376    8   57    537   31 Failed  97.7,6.1 96.7,16.4
event6        311   13   50    830   31 Failed  99.5,0.5 94.9,42.6
event11       311   14   11    851   31 Failed  99.5,0.5 93.1,51.0
event7        311   17   41   1061   31 Failed 99.5,99.5 92.6,50.1