抓取 Javascript 生成的 HTML 表格时出现奇怪的字符

Posted

技术标签:

【中文标题】抓取 Javascript 生成的 HTML 表格时出现奇怪的字符【英文标题】:Weird characters when scraping HTML tables generated by Javascript 【发布时间】:2020-05-31 01:39:18 【问题描述】:

我正在尝试从https://www.flashscore.com/tennis/atp-singles/australian-open-2020/results/ 中抓取一些数据

特别是,我对源代码中的“比赛页面数据结果”div 感兴趣。当我把它拉出来时,数据确实出现在 html 源代码中,但它看起来像这样:

"SA÷2¬~ZA÷ATP - SINGLES: Australian Open (Australia), hard¬ZEE÷MP4jLdJh¬ZB÷3473162¬ZC÷n5bYULYo¬ZD÷p¬ZE÷6N6d2yER¬ZF÷0¬ZO÷0¬ZG÷2¬ZH÷9011_MP4jLdJh¬ZJ÷5¬ZL÷/tennis/atp-singles/australian-open/¬ZX÷01110...000Australian O021, hard00000000Australian O027ralia)¬ZHS÷5724¬ZCC÷0¬ZAF÷ATP - Singles¬~AA÷WEJGUHfb¬AD÷1580633100¬ADE÷1580633100¬AB÷3¬CR÷3¬AC÷3¬CX÷Thiem 

将真实数据与随机字符混合在一起。我试图从 'utf-8' 转换为 'ascii' 但它有同样的问题,只是使用不同的随机字符。

我在这里需要的正确编码是什么?还是有完全不同的方法?我正在使用 R(rvest 包)来避免在浏览器窗口中打开每一页。如果这更容易,我可以切换到 Python。

【问题讨论】:

我不知道您的 R (rvest package) 或 Python。如果您对node 感到满意,那么有一个包cheerio 非常适合在不打开浏览器页面的情况下进行网络抓取。有了这个,您将获得所有 HTML 源代码。 看起来带有奇数字符的源代码实际上是创建页面的脚本的一部分,而不是显示页面本身的 HTML。您也许可以手动取消选择它,否则您可以使用 RSelenium 之类的东西通过自动浏览器捕获页面。 div 锦标赛页面数据结果中的数据内容看起来像是某种混淆。也许是故意的?然而,这种疯狂是有规律的。如果您搜索“AB÷3-CR÷3-AC÷3-CX÷”(查看源代码),您将在玩家正前方获得 124 次点击。我的猜测是 javascript 会即时将数据转换为有效的 html。我不知道你是如何抓取的,但在 JS 支持下,内容放在 【参考方案1】:

正如人们在 cmets 中提到的,这不是编码问题。 div 的文本内容是用一种由 javascript 解释的表格标记语言编写的。

您可以对解析器进行逆向工程。首先,每个匹配项由波浪号 (~) 字符分隔,数据字段由“¬”字符分隔。每个字段都是以“÷”分隔的键值对的形式。

将其转换为数据框并不容易,因为数据不是矩形的。转成 JSON 会更容易。

以下是如何获取一些感兴趣的字段的示例:

"https://www.flashscore.com/tennis/atp-singles/australian-open-2020/results/" %>%
  xml2::read_html() %>% 
  rvest::html_node("#tournament-page-data-results") %>% 
  rvest::html_text() %>% strsplit("[~]") %>% unlist() %>% strsplit("\u00ac") %>%
  lapply(function(x) gsub("^.*\u00f7", "", x)) %>%
  lapply(function(x)
    y <- as.numeric(grep("\\d10", x, value = TRUE))
    y <- as.difftime(y, units = "secs") + as.POSIXct("1970-01-01 00:00:00")
    x[grep("\\d10", x)] <- as.character(y)
    return(x)) %>% 
  lapply(`[`, -(1:2)) %>% 
  lapply(function(x) x[!grepl("^[[:alnum:]]8$", x)]) %>%
  lapply(function(x) grep("[a-z ]", x, value = TRUE)[-c(2,4,6,8)]) %>%
  `[`(-(1:2)) %>%
  do.call(rbind, .) %>%
  as.data.frame(stringsAsFactors = FALSE) %>%
  `names<-`(c("Date", "Stage", "Player1", "Player2")) %>%
  tibble::as.tibble()
#> # A tibble: 127 x 4
#>    Date                Stage          Player1           Player2          
#>    <chr>               <chr>          <chr>             <chr>            
#>  1 2020-02-02 07:45:00 Final          Djokovic N. (Srb) Thiem D. (Aut)   
#>  2 2020-01-31 07:45:00 Semi-finals    Thiem D. (Aut)    Zverev A. (Ger)  
#>  3 2020-01-30 07:45:00 Semi-finals    Federer R. (Sui)  Djokovic N. (Srb)
#>  4 2020-01-29 07:45:00 Quarter-finals Thiem D. (Aut)    Nadal R. (Esp)   
#>  5 2020-01-29 02:45:00 Quarter-finals Wawrinka S. (Sui) Zverev A. (Ger)  
#>  6 2020-01-28 07:50:00 Quarter-finals Raonic M. (Can)   Djokovic N. (Srb)
#>  7 2020-01-28 03:15:00 Quarter-finals Sandgren T. (Usa) Federer R. (Sui) 
#>  8 2020-01-27 08:05:00 1/8-finals     Rublev A. (Rus)   Zverev A. (Ger)  
#>  9 2020-01-27 07:15:00 1/8-finals     Nadal R. (Esp)    Kyrgios N. (Aus) 
#> 10 2020-01-27 03:15:00 1/8-finals     Medvedev D. (Rus) Wawrinka S. (Sui)
#> # ... with 117 more rows

【讨论】:

以上是关于抓取 Javascript 生成的 HTML 表格时出现奇怪的字符的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 抓取网页动态内容(动态 HTML/Javascript 表格)

用python抓取javascript生成的html

使用 C# 在 html 文档中抓取由 JavaScript 动态生成的数据

抓取javascript生成的网页

任何人都有一个很好的解决方案来抓取带有 Javascript 生成的内容(在本例中为 HTML 表)的页面的 HTML 源代码? [关闭]

如何抓取 HTTPS javascript 网页