如何刮掉这个 squawka 页面?

Posted

技术标签:

【中文标题】如何刮掉这个 squawka 页面?【英文标题】:how to scrape this squawka page? 【发布时间】:2014-04-02 23:32:18 【问题描述】:

我正在尝试提取以下信息:

在页面上

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

按下红色的“完整统计”按钮会打开一个菜单,其中包括(在左侧)“交叉”按钮。这将在屏幕右侧打开一个带有 19 个箭头的足球场图像,这些是斯托克在斯托克-阿森纳比赛中的传中。它们是彩色编码的,红色 = 未完成,绿色 = 完成,黄色 = 关键通行证。 当你点击一个箭头时,它会告诉你是谁传球的以及在比赛的哪一分钟。 此外,箭头还显示了球员在传球时的站立位置以及被传球的球员所在的位置。

我希望能够抓取此页面,以便获得包含列的表格:

团队;发件人姓名;发件人位置;接收者位置;分钟;箭头颜色

这是斯托克队的传球,我也想自动为阿森纳重复这个(因此,上表中的“俱乐部”列)。

虽然我过去曾抓取过网页,但这些都是静态的相当简单的页面,我完全不知道如何从这个页面上抓取信息。 我非常感谢有关如何抓取我刚才描述的数据的帮助。我精通 R,因此我特别感谢能帮助我在 R 中实现这一目标的代码,但我也非常感谢使用其他语言或软件的帮助。

谢谢你, 彼得

【问题讨论】:

您可能必须使用浏览器驱动程序,例如 Selenium。有R接口;见lluisramon.github.io/relenium 和johndharrison.github.io/RSelenium。 我从来没有听说过这样的事情,新作业!我将如何在 squawka 使用它来抓取像这样的页面?有什么提示吗? 有一个很好的例子,说明如何将 Selenium 与 R 一起使用,只是 here,目前在 R tag 上直接回答了你上面的问题 【参考方案1】:

Peter 正如他们所说的那样,您可以使用 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 basics 和 RSelenium: Testing Shiny apps.

可以使用选择器轻松访问更多信息:

> 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

【讨论】:

谢谢你,约翰,这很好用,我已经研究了几个小时了。我还有两个问题:1。你是怎么知道解决“squawkaDp.xml”的? 2. 我想生成一个数据框(或类似的东西),其中包含 player_id、mins、secs、minsec、team、type、startX、startY、endX、endY 列,其读数为 531、4、39、279、44、"失败”, 73.1, 87.1, 97.9, 49.1 311, 6”, 33, 393, 31, “失败”, 92.3, 13.1, 93.0, 31.0 376, 8, 57, 537, 31, “失败”, 97.7, 6.1, 96.7、16.4 等等(总共 38 行)我该怎么做?XMLNodeSets 总是让我完全逃脱.. @PeterVerbeet 我很高兴这个例子对你有用。可以开始单击站点上的按钮等,但是数据包含在可缩放矢量图形格式中。更容易获得源代码。我查看了 epl.squawka.com/scripts/squawkaDp_v10.30.js?v=7 在此文件中搜索 showCrosses function: 并在此函数中注意 var crosses = $(squawkaDp.xml).find('crosses') 行。关于您的第二个问题,我将在上面的代码中添加一个快速指针。 非常感谢,约翰,这非常有效!我显然需要深入研究一些文献,以便能够在其他网站上进一步理解和做到这一点。有小费吗?无论如何,我将来会非常安静地使用你的 RSelenium 包,感谢你非常有用的帮助和时间! 又出现了一个问题。我试图为“eredivisie.squawka.com/feyenoord-vs-ajax/02-03-2014/…”做同样的事情,当我运行“xmlParse(squawkData[[1]])”时,我得到一个错误:“输入不是正确的 UTF-8,表示编码!字节:0xE8 0x22 0x2C 0x22。”有什么办法可以解决这个问题吗? 这是 squawka 网站的问题。他们正在发送 utf8 数据,但它包含其他编码。使用example &lt;- querySelectorAll(xmlParse(gsub('encoding="UTF-8"', 'encoding="ISO-8859-1"', squawkData[[1]])), "crosses time_slice") 进行快速修复,但这可能存在问题。

以上是关于如何刮掉这个 squawka 页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何刮掉另一个跨度类中的一个跨度?

scrapy中的新手:如何response.css刮掉文本部分?

如何使用美丽的汤来刮掉SEC的Edgar数据库并接收欲望数据

制作scrapy蜘蛛跟随给定起始URL的链接

刮掉字符前后的 SQL 数据

Scrapy:如何通过AJAX调用刮取第二个HTML页面