解析R中的html:输出data.frame制作的问题

时间:2015-03-12 09:26:57

标签: r parsing

我试图从网页中提取数据。因此我想用3个变量创建一个函数: 1)要查看的网页矢量 2)输出文件中列名的向量 3)输出文件中每列的html代码中的标记向量

parser <- function(fileUrl, itemName, itemMark)
{
    library(XML)
    total_result <- data.frame()       
    for (file in fileUrl)    {
        temp <- data.frame(1)
        itemTemp <- c()  
        doc <-htmlTreeParse(file,useInternal=TRUE)
        for (i in 1:length(itemName)){            
            itemTemp <- xpathSApply(doc,itemMark[[i]], xmlValue)
            temp <- data.frame(temp,itemTemp, check.rows=FALSE)
        }
        total_result <- rbind(total_result, temp)        
    }   
    total_result[,1]<-NULL
    names(total_result) <- itemName
    total_result

}

它实际上适用于网页上具有相同频率的项目。但它并不适用于其他情况。我有这样的错误

  

data.frame(temp,itemTemp,check.rows = FALSE)中的错误:参数   意味着不同的行数:100,0

我明白对于data.frame函数我需要参数有相同的行数但我不能得到它如何让我的解析器工作。 你能帮我吗?

重现错误:

url <- c("http://www.ebay.com/sch/Cell-Phones-Smartphones-/9355/i.html?LH_BIN=1&_from=R40&LH_ItemCondition=1000&_nkw=(iphone,%20htc,%20samsung,%20lg,%20nokia,%20sony)&_dcat=9355&rt=nc&_pppn=r1&Carrier=Unlocked|!","http://www.ebay.com/sch/Cell-Phones-Smartphones-/9355/i.html?LH_BIN=1&_from=R40&LH_ItemCondition=1000&_dcat=9355&Carrier=Unlocked%7C%21&_nkw=%28iphone%2C+htc%2C+samsung%2C+lg%2C+nokia%2C+sony%29&_pgn=2&_skc=50&rt=nc")
marks <- c("//span[@class='cbx']","//span[@class='cnt']")
names < c("1a","2a")
parser(url,names,marks)

1 个答案:

答案 0 :(得分:1)

您正尝试在此步骤中在数据框中组合两个不等长度的向量:

temp <- data.frame(temp,itemTemp, check.rows=FALSE)

看起来你正试图抓住ebay页面左侧的过滤器。这样做,你错过了很多。有很多(见全部)链接。实际只显示一个子集。我想你还有更多的工作要弄清楚如何做到这一点......

无论如何,“免费送货”“免费店内提货”“退货接受”“已完成的商品”“已售商品”旁边都没有数字。这就是为什么矢量不同

library(rvest)
url <- c("http://www.ebay.com/sch/Cell-Phones-Smartphones-/9355/i.html?LH_BIN=1&_from=R40&LH_ItemCondition=1000&_nkw=(iphone,%20htc,%20samsung,%20lg,%20nokia,%20sony)&_dcat=9355&rt=nc&_pppn=r1&Carrier=Unlocked|!","http://www.ebay.com/sch/Cell-Phones-Smartphones-/9355/i.html?LH_BIN=1&_from=R40&LH_ItemCondition=1000&_dcat=9355&Carrier=Unlocked%7C%21&_nkw=%28iphone%2C+htc%2C+samsung%2C+lg%2C+nokia%2C+sony%29&_pgn=2&_skc=50&rt=nc")
url[1] %>% html() %>% html_nodes(xpath="//span[@class='cbx']") %>% html_text()
url[1] %>% html() %>% html_nodes(xpath="//span[@class='cnt']") %>% html_text()

编辑补充:我认为这应该为你做。这有点hacky,但完成工作。这里的想法是你将.pad-bottom元素下载到一个向量中。这些包含一堆空格,但也包含您要查找的文本和数字。它需要一点点字符串grepping,splitting等来实现,但这样做可以确保您拥有匹配的数据。显然,单独下载元素并希望它们在以后匹配不起作用。

library(rvest)
library(stringr)
a <- url[1] %>% html() %>% html_nodes(".pad-bottom") %>% html_text()
# remove some whitespace
a <- gsub("[\r|\t]", "", a)
# nodes seem to be separated by three new lines. 
a <- unlist(strsplit(a, "\n\n\n"))
# now get rid of the rest of the new lines
a <- gsub("\n", "", a)
# get rid of the elements that are empty
a <- a[a!=""]
# get rid of the elements that don't have a "("... these don't have numbers next to them.
a <- a[grepl("\\(", a)]
# put it all together into a dataframe.
df <- data.frame(name=substring(a, 1, regexpr("\\(", a)-1),
                 count=gsub("\\(|,", "", str_extract(a, "\\(([0-9]*,?[0-9]*)")))