【问题标题】:Parsing a CSV HTML stream in R在 R 中解析 CSV HTML 流
【发布时间】:2012-09-13 06:06:22
【问题描述】:

我正在尝试解析以 csv 格式显示的 html 页面。

我想在页面运行时将这个表格直接读入 R (http://www.nwrfc.noaa.gov/esp/esp2csv.cgi?id=slkw1),然后将数据转换成矩阵以便进一步处理。

不确定 RCurl 或 XML 包是否是最好的方法,但是一旦我将对象放入 R 中,就无法找到解析对象的好方法。

【问题讨论】:

    标签: html r html-parsing web-scraping


    【解决方案1】:
    > con=url("http://www.nwrfc.noaa.gov/esp/esp2csv.cgi?id=slkw1")
    > table(count.fields(con, sep=","))
    
        1 25521 
        2     1 
    

    所以只有一个字段的两行...事实证明,跳过两行可以让数据读取成功。

    > con=url("http://www.nwrfc.noaa.gov/esp/esp2csv.cgi?id=slkw1")
    > temp <- scan(file=con,  skip=2, what="a", sep=",") 
    # paged through the scan results
    > table(grepl("<br />", temp))
    
    FALSE  TRUE 
    25478    43
    
    > con=url("http://www.nwrfc.noaa.gov/esp/esp2csv.cgi?id=slkw1")
    > temp <- readLines(con=con)
    > temp2=gsub("<br />", "\n", temp)
    # Knew that the first two lines were HTML junk.
    > temp3 = read.table( text=temp2[3], sep= ",", fill =TRUE, header=TRUE)
    > str(temp3)
    'data.frame':   43 obs. of  581 variables:
     $ X.pre.STA.ID: Factor w/ 1 level "SLKW1": 1 1 1 1 1 1 1 1 1 1 ...
     $ START.YEAR  : int  1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 ...
     $ X9.1        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
     $ X9.2        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
     $ X9.3        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
     $ X9.4        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
     $ X9.5        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
     $ X9.6        : int  -999 -999 -999 -999 -999 -999 -999 -999 -999 -999 ...
    
    snipped  output  There is better data below
    
     $ X9.18       : int  41 41 41 41 41 41 41 41 41 41 ...
     $ X9.19       : int  41 41 41 41 41 41 41 41 41 41 ...
     $ X9.20       : int  40 40 40 40 40 40 40 40 40 40 ...
     $ X9.21       : int  39 39 39 39 39 39 39 39 39 39 ...
     $ X9.22       : int  39 39 39 39 39 39 39 39 39 39 ...
     $ X9.23       : int  39 39 39 39 39 39 39 39 39 39 ...
     $ X9.24       : int  38 38 38 38 38 38 38 38 38 38 ...
     $ X9.25       : int  38 38 38 38 38 38 38 38 38 38 ...
     $ X9.26       : int  38 38 38 38 38 38 38 38 38 38 ...
     $ X9.27       : int  38 38 38 38 38 38 38 38 38 38 ...
     $ X9.28       : int  48 53 106 49 89 48 94 117 49 49 ...
     $ X9.29       : int  57 45 436 40 403 38 145 294 40 40 ...
     $ X9.30       : int  259 34 1270 37 1622 33 80 432 37 37 ...
    

    最后一列被强制转换为取决于 read.table 设置的因子或字符,因为最后一行中的最后一个元素是

    >  temp3[43, 581]
    [1] "-999</pre></body>"
    

    有几种处理方法。选一个。并不重要,因为整列都是 -999。

    【讨论】:

    • 谢谢!这很好用,我会做一些修改来处理数据,但这会删除所有不需要的 html 标记。一个问题是: "read.table( text=temp2[3], sep=",", fill =TRUE, header=TRUE)" 如何删除 html 流开头的
       标记?在使用该行之前,我尝试使用 gsub 替换所有 
       和  标记,结果爆炸了。再次感谢!
    •  和  标签是 temp2[1:2],我只将 temp2[3] 传递给 read.table()
    【解决方案2】:

    我已经走到这一步了。如果有人可以更进一步,请编辑我的答案。

    library(RCurl)
    library(XML)
    library(stringr)
    # grab the content. can't use readHTMLTable since this isn't one.
    htmldata <- getURL('http://www.nwrfc.noaa.gov/esp/esp2csv.cgi?id=slkw1')
    # grab data between the pre tags
    dataonly <- substr(htmldata, str_locate(data, "<pre>")[2]+1 ,
    str_locate(data, "</pre>")[1]-1)
    # replace <br> tags with new lines.
    dataonly2 <- str_replace(dataonly, "<br />", "\n")
    

    【讨论】:

    • 嗨!谢谢你,我认为它已经接近工作了,然后上面的脚本进来了,我最终玩了半个小时。不过还是谢谢!!!
    猜你喜欢
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多