【问题标题】:Scraping data from a GroupGrid从 GroupGrid 中抓取数据
【发布时间】:2016-02-27 18:36:16
【问题描述】:

我想抓取并分析 when2meet 表的输入。

这是一个示例:http://www.when2meet.com/?4474391-IBuBA

该表格快速直观地概述了每个组成员的可用性;我想把它提取到 R 来做一些分析,但是我做不到。

其实很短;我只提取了主页元素。输出(对我来说)是乱码:

library(rvest)

url <- "http://www.when2meet.com/?4474391-IBuBA"

grid <- html(url) %>% html_nodes(xpath = '//*[@id="GroupGrid"]')

grid 看起来像这样:

<div style="font-size:0px;vertical-align:top;"><div id="GroupTime279816300" onmouseover="ShowSlot(279816300);" style="vertical-align:top;display:inline-block;*display:inline;zoom:1;width:44px;height:9px;font-size:0px;border-left: 1px black solid;background: #c5e2b6;"><script><![CDATA[
Col[TimeOfSlot.indexOf(279816300)] = 0;
Row[TimeOfSlot.indexOf(279816300)] = 23;
]]></script></div>
<div id="GroupTime279902700" onmouseover="ShowSlot(279902700);" style="vertical-align:top;display:inline-block;*display:inline;zoom:1;width:44px;height:9px;font-size:0px;border-left: 1px black solid;background: #8ac56d;"><script><![CDATA[
Col[TimeOfSlot.indexOf(279902700)] = 1;
Row[TimeOfSlot.indexOf(279902700)] = 23;
]]></script></div>
<div id="GroupTime279989100" onmouseover="ShowSlot(279989100);" style="vertical-align:top;display:inline-block;*display:inline;zoom:1;width:44px;height:9px;font-size:0px;border-left: 1px black solid;background: #c5e2b6;"><script><![CDATA[
Col[TimeOfSlot.indexOf(279989100)] = 2;
Row[TimeOfSlot.indexOf(279989100)] = 23;
]]></script>

我在这里基本上看不到任何用处;它也可能是乌尔都语。而且我在 Google 或 SO 上找不到任何关于抓取 GroupGrid 表的信息。

有人知道如何进行吗?

理想情况下,我会输出以下形式的 data.tabledata.frame,如果必须的话):

output
#        id    slot available
# 1: user_1  M 9:00      TRUE
# 2: user_1  T 9:30     FALSE
# 3: user_1 W 10:00      TRUE
# 4: user_1 R 10:30      TRUE
# 5: user_2  M 9:00      TRUE
# 6: user_2  T 9:30     FALSE
# 7: user_2 W 10:00      TRUE
# 8: user_2 R 10:30     FALSE

slot 列的确切格式并不重要,也不必是一列——如果更简单,可以是 daytime

【问题讨论】:

    标签: r web-scraping rvest


    【解决方案1】:

    你可以这样做

    library(data.table)
    
    script <- html("http://www.when2meet.com/?4474391-IBuBA") %>%
      html_nodes("script:contains('PeopleNames')") %>% html_text()
    
    f <- function(regex) {
      m <- regmatches(script, gregexpr(regex, script))[[1]]
      #faster than transposing with `t`
      setDT(transpose(lapply(regmatches(m, regexec(regex, m)), "[", -1)))[]
    }
    slots <- f("TimeOfSlot\\[(\\d+)\\]=(\\d+);")
    users <- f( "PeopleNames\\[(\\d+)\\] = '([^']+)';PeopleIDs\\[\\d+\\] = (\\d+);")
    avails <- f("AvailableAtSlot\\[(\\d+)]\\.push\\((\\d+)\\);")
    
    DT <- melt(dcast(avails, V2~V1, 
                     fun.aggregate = function(x) length(x) > 0,
                     value.var = "V2"), id.vars = "V2",
               variable.name = "timeslot", value.name = "available")
    
    DT[users, id := i.V2, on = c(V2 = "V3")]
    DT[slots, time := format(as.POSIXct(as.integer(
      i.V2), origin = "1970-01-01", tz = "GMT"), "%a %H:%M"),
      on = c(timeslot = "V1")]
    
    DT[ , c("V2", "timeslot") := NULL]
    
    DT[time == "Mon 11:00" & available]
    #    available      id      time
    # 1:      TRUE  user_1 Mon 11:00
    # 2:      TRUE  user_2 Mon 11:00
    # 3:      TRUE  user_3 Mon 11:00
    # 4:      TRUE  user_4 Mon 11:00
    # 5:      TRUE  user_5 Mon 11:00
    # 6:      TRUE  user_7 Mon 11:00
    # 7:      TRUE user_10 Mon 11:00
    
    DT[time == "Mon 11:00" & !available]
    #    available     id      time
    # 1:     FALSE user_6 Mon 11:00
    # 2:     FALSE user_8 Mon 11:00
    # 3:     FALSE user_9 Mon 11:00
    

    【讨论】:

    • 感谢改进的屏幕截图。直到明天我才有机会确认这项工作(看起来很棒!)你怎么知道TimeOfSlot RHS 可以转换为POSIXct?您是否只是猜测并验证了来源、时区等?
    • 所有数据都在页面的 JavaScript 中 - 我寻找“user_1”并在那里。是的,将时间戳转换为日期时间对象是反复试验(默认值 CET 提前一小时,所以我明确设置了 GMT;并且原点是共同原点,所以这是我的第一个猜测)。截图是为了显示“周一,上午 11 点”的结果与 subset 的输出相匹配。 :-)
    • 太棒了! regexec 部分特别漂亮。谢谢。我进行了编辑以更多地反映我的风格(我相信会加快速度)
    • 这对现成的完全相同的问题有效,非常感谢。在 2020 年的垃圾箱大火中,这是发生的第一件积极的事情。
    • 无法强调这是现成的工作方式有多棒。为了自己的方便,我添加了一个时区功能,其他人可能会觉得这很有用:DT[slots, time := format(lubridate::with_tz(as.POSIXct(as.integer( i.V2), origin = "1970-01-01", tz = "GMT"), "America/New_York"), "%a %H:%M"), on = c(timeslot = "V1")]
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多