【问题标题】:R How to Check if XPath ExistsR如何检查XPath是否存在
【发布时间】:2014-08-26 09:38:27
【问题描述】:

希望比我知识渊博的人能在这里有所启发。

作为大型网络抓取工具的一部分,我想从一组页面中提取元数据。当我运行它时,它摔倒了,调查显示这是由于请求的 Xpath 之一不存在。

我可以看到一个潜在的解决方案是将页面的所有元数据抓取到一个向量中,并检查每个所需的元数据是否存在,然后再构建一个我想要的新向量。

但是

如果我只抓取页面中存在的我想要的位,那就更好了。

require(XML)
require(RCurl)
parsed <- htmlParse("http://www.coindesk.com/information")

meta <- list()
meta[1] <- xpathSApply(parsed, "//meta[starts-with(@property, \"og:title\")]", xmlGetAttr,"content")
meta[2] <- xpathApply(parsed, "//meta[starts-with(@property, \"og:description\")]", xmlGetAttr,"content")
meta[3] <- xpathApply(parsed, "//meta[starts-with(@property, \"og:url\")]",  xmlGetAttr,"content")
meta[4] <- xpathApply(parsed, "//meta[starts-with(@property, \"article:published_time\")]",  xmlGetAttr,"content")
meta[5] <- xpathApply(parsed, "//meta[starts-with(@property, \"article:modified_time\")]",  xmlGetAttr,"content")

这将引发错误,因为og:description 不在此页面中。

Error in meta[2] <- xpathApply(parsed, "//meta[starts-with(@property, \"og:description\")]",  : 
  replacement has length zero

任何人都可以建议一个简单的测试,在尝试提取它之前检查它的存在,优雅地摔倒,也许是 NULL 响应?

【问题讨论】:

  • 你得到什么错误?当我运行你的代码时,我得到一个空列表。
  • 我也是,即使我修复了htmlParse 行中的双引号,这让我非常怀疑这段代码不会产生这个问题。
  • 对不起,伙计们,我在被夫人拖出门之前匆忙发布了这个问题,我很不高兴我应该在假期里做“工作”。是的,我拿起双引号并删除了它们。 Jdharrison - 我认为你是对的,它返回一个空列表,我没有处理它。这只是编码 FULL STOP 的第四天,这是一个陡峭的学习曲线。 Spacedman 的长度测试显然可以完成这项工作。谢谢

标签: r xpath web-scraping


【解决方案1】:

假设当您尝试处理空列表时出现错误...

> parsed <- htmlParse("http://www.coindesk.com/information")
> meta <- xpathApply(parsed, "//meta[starts-with(@property, \"og:description\")]", xmlGetAttr,"content")
> meta
list()
> length(meta)==0
[1] TRUE

然后测试length(meta)==0 - 如果缺少元素,则为TRUE。否则它的FALSE - 就像这个提取标题属性的例子一样:

> meta <- xpathApply(parsed, "//meta[starts-with(@property, \"og:title\")]", xmlGetAttr,"content")
> meta
[[1]]
[1] "Beginner's guide to bitcoin - CoinDesk's Information Center"

> length(meta)==0
[1] FALSE

【讨论】:

  • 你能解释一下反斜杠的语法吗,如 \"og:description\?我不精通 xpath,但在此之前我认为正斜杠或双正斜杠是路径定位符。跨度>
  • 那些只是转义引号,因为 R 字符串被包含在引号内。反斜杠实际上不在字符串中。
【解决方案2】:

这个问题的答案很难确定。虽然有几个 xpathApply 的自定义实现来处理 NULL 结果,但所提出的问题的解决方案确实存在于 Spacedman 的建议中。

IF 语句的第一部分调用 xPath 并检查返回长度是否 = 0。 如果是,则将自定义消息应用于列表,“Title NA”或“Description NA”,但 如果长度不为 0(即存在匹配项),则它将 xPath 应用于列表。

简单。

 require(XML)
    require(RCurl)
    parsed <- htmlParse("http://www.coindesk.com/information")

    meta    <- list()
    meta[1] <- if(length(xpathSApply(parsed, "//meta[starts-with(@property, \"og:title\")]", xmlGetAttr,"content"))==0) 
               {
                 "Title NA"
               } 
               else 
               {
                 xpathSApply(parsed, "//meta[starts-with(@property, \"og:title\")]", xmlGetAttr,"content")
               }
    meta[2] <- if(length(xpathApply(parsed, "//meta[starts-with(@property, \"og:description\")]", xmlGetAttr,"content"))==0) 
               {  
                 "Description NA" 
               } 
               else 
               {
                  xpathApply(parsed, "//meta[starts-with(@property, \"og:description\")]", xmlGetAttr,"content")
               } 

【讨论】:

    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 2011-08-07
    相关资源
    最近更新 更多