【问题标题】:{xml_nodeset (0)} issue when webscraping table{xml_nodeset (0)} webscraping 表时的问题
【发布时间】:2019-12-24 03:31:55
【问题描述】:

我正在尝试从这个 url 中抓取第一个表:

https://www.whoscored.com/Matches/318578/LiveStatistics/England-Premier-League-2009-2010-Blackburn-Arsenal

使用以下代码:

url <- "https://www.whoscored.com/Matches/318578/LiveStatistics/England-Premier-League-2009-2010-Blackburn-Arsenal"
data <- url %>%
  read_html() %>%
  html_nodes(xpath='//*[@id="top-player-stats-summary-grid"]')

给数据赋值{xml_nodeset (0)}

url <- "https://www.whoscored.com/Matches/318578/LiveStatistics/England-Premier-League-2009-2010-Blackburn-Arsenal"
data <- url %>%
  read_html() %>%
  html_nodes(css='.grid')

同样的问题。

显然这可能是一个 javascript 问题 - 有没有一种快速的方法来提取相关数据?检查表格条目似乎表明数据不是从其他地方导入的,而是编码到页面中的,所以似乎我应该能够从源代码中提取它(对不起,我完全不知道 HTML 和 JS 是如何工作的我的问题可能没有意义)。

【问题讨论】:

    标签: r web-scraping rvest


    【解决方案1】:

    页面在使用浏览器时通过页面上运行的 javascript 动态更新内容。 rvest 不会发生这种情况。但是,您可以在开发工具网络选项卡中观察 xhr 调用,该调用将此内容返回为 json

    require(httr)
    require(jsonlite)
    
    headers = c('user-agent' = 'Mozilla/5.0',
                'accept' = 'application/json, text/javascript, */*; q=0.01',
               'referer' = 'https://www.whoscored.com/Matches/318578/LiveStatistics/England-Premier-League-2009-2010-Blackburn-Arsenal',
                'authority' = 'www.whoscored.com',
                'x-requested-with' = 'XMLHttpRequest')
    
    params = list(
      'category' = 'summary',
      'subcategory' = 'all',
      'statsAccumulationType' = '0',
      'isCurrent' = 'true',
      'playerId' = '',
      'teamIds' = '158',
      'matchId' = '318578',
      'stageId' = '',
      'tournamentOptions' = '',
      'sortBy' = '',
      'sortAscending' = '',
      'age' = '',
      'ageComparisonType' = '',
      'appearances' = '',
      'appearancesComparisonType' = '',
      'field' = '',
      'nationality' = '',
      'positionOptions' = '',
      'timeOfTheGameEnd' = '',
      'timeOfTheGameStart' = '',
      'isMinApp' = '',
      'page' = '',
      'includeZeroValues' = '',
      'numberOfPlayersToPick' = ''
    )
    
    r <- httr::GET(url = 'https://www.whoscored.com/StatisticsFeed/1/GetMatchCentrePlayerStatistics', httr::add_headers(.headers=headers), query = params)
    
    data <- jsonlite::fromJSON(content(r,as="text") )
    print(data$playerTableStats)
    

    data$playerTableStats 通过View(data$playerTableStats) 的内容小样本。您可以根据需要以您想要的格式解析您想要的信息。

    【讨论】:

    • 您能否解释一下您是如何定义 headersparams 中的参数和值的?对于那些在服务器端有数据的网站,这种方法是否可以替代selenium
    • 这取决于页面如何更新内容(如果它动态更新)。您可以通过使用 F12 打开开发工具并转到网络选项卡来查看请求,按 F5 刷新页面,然后按 Ctrl + F 打开查找框并键入 Robinson,然后按 Enter。您会发现那里显示的请求以及参数和标头。我用 python 运行以测试删除一些标题。您可能可以删除更多。见herehere
    • 阅读您的评论几秒钟后,我认为 Robinson 是一种在 javascript 中工作的函数 :)))。然后我意识到这是玩家的名字。好的谢谢。我明白了……我将对此方法进行一些试验。
    • 谢谢!我想我现在开始明白了。奇怪的是,我第一次运行你说它工作的代码并且我能够存储数据,但第二次我得到这个错误:data &lt;- jsonlite::fromJSON(content(r,as="text") )No encoding supplied: defaulting to UTF-8. Error: lexical error: invalid char in json text. &lt;!DOCTYPE HTML PUBLIC "-//W3C// (right here) ------^ In addition: Warning message: JSON string contains (illegal) UTF8 byte-order-mark! 你知道这里发生了什么吗?
    • 我认为该页面可能具有反抓取措施,并且有时您会得到不同的结果,即 html。如果是这种情况,那么接下来要尝试浏览器自动化,例如RS硒
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多