【问题标题】:R not accepting xpath queryR不接受xpath查询
【发布时间】:2014-09-01 10:36:39
【问题描述】:

您好,我正在使用 R 中的 XML 包来抓取 html 页面。感兴趣的页面是http://www.ncbi.nlm.nih.gov/protein/225903367?report=fasta,并且在该页面上有一个序列,当检查 chrome 中的元素时,xpath 是

//*[@id="gi_225903367_141"]

但是当我尝试使用:

xpathSApply(htmlParse(fasta.url.content),"//*[@id="viewercontent1"]/pre")
Error: unexpected symbol in "xpathSApply(htmlParse(fasta.url.content),"//*[@id="viewercontent1"

我收到上述错误。

XML 包是否对 xpath 很挑剔?

这是使用 Mathius 提供的 xpath 的查询

xpathSApply(htmlParse(fasta.url.content),"//span[contains(@id,'gi_225903367_1')]")
list()
attr(,"class")
[1] "XMLNodeSet"

我得到一个空列表。我不怀疑 xpath 不正确,但我想知道这是否与 R 相关。

【问题讨论】:

  • 尝试将内部双引号更改为单引号。作为//*[@id='viewercontent1']/pre
  • 这似乎有效,但是收到一个空列表...
  • 我不确定我是否理解您所追求的元素。是//*[@id="gi_225903367_141"] 还是//*[@id="viewercontent1"]/pre 还是//*[@id="viewercontent1]"
  • 是MYS开头的序列
  • 那么,MYS 是什么?请简单回答我的问题,您在寻找什么 HTML 元素?

标签: xml r xpath web-scraping


【解决方案1】:

问题是页面是使用javascript动态创建的,在返回给R的渲染中看不到序列。

CRAN 包“rentrez”提供到eutils 的接口,这是查询Entrez 的编程方式

library(rentrez)
entrez_fetch(db="protein", id="225903367", rettype="fasta")

【讨论】:

  • 你救了我的命!太感谢了!还要感谢您解释为什么序列不在页面源中 - 我在几个小时前就想通了,但这个答案将帮助任何人理解为什么他们不能简单地网页抓取 html/xml。
【解决方案2】:

这得到了列表,虽然我不知道它是否 100% 正确,因为我不使用 fasta 文件。看起来lapply(dat, cat) 可能需要在下面的dat 结果上调用。

> library(RCurl)
> library(XML)
> url <- getURL("http://www.ncbi.nlm.nih.gov/protein/225903367?report=fasta")
> dat <- readHTMLList(url)
> length(dat)
# [1] 39
> object.size(dat)
# 42704 bytes

整个列表不是很大,所以我建议将整个列表放入 R 中。这样您就拥有了所有相关数据,并且您不必花一整天时间尝试对 html 文档进行正则表达式。看起来可能会触发意外符号,因为您写了//*,而* 需要在其上使用转义字符,可能是//[*]

编辑你得到的错误是由于其他双引号内的双引号引起的。在 R 中应该引用 "//*[@id='viewercontent1']/pre"

是的,XML 可能很挑剔,但这通常是因为 (1) 它是互联网,以及 (2) 解析器期望某些内容包含在 html 代码中,有时它不是。我的教授写了RCurlXML,他建议在XML::readHTMLTable 或任何其他read* 函数出现问题时转到RCurl::getURL

您在输出中遇到的这些问题并不奇怪。它们是一个空结果,正如分配属性的函数所期望的那样。

【讨论】:

    【解决方案3】:

    如果您访问此网址 ncbi.nlm.nih.gov/protein/225903367?report=fasta 你会看到一系列以“MYS”开头的字母,就是这样 我需要的序列。

    最后我想我明白你需要什么了。你要找的内容在下面span

    <span id="gi_225903367_1" class="ff_line">
        MYSFNTLRLYLWETIVFFSLAASKEAEAARSAPKPMSPSDFLDKLMGRTS…
    </span>
    

    您可以通过如下 XPath 表达式找到它:

    "//span[@id = 'gi_225903367_1']"
    

    注意:这是检索具有id 属性值“gi_225903367_1”的span 元素的正确表达式。我无法评论您是否在 R 代码中正确应用了 XPath。

    【讨论】:

    • 感谢您耐心等待马修斯。这一定是我在 R 中正在做的事情
    • @brucezepplin 为什么?使用上面的表达式会得到什么结果或错误消息?
    • 我只是使用您提供的 xpath 得到一个空列表。我在更新的问题中对此进行了详细说明。如您所说,xpath 看起来是正确的。
    • 我认为问题在于,如果您查看页面源,则在 url 的 html 内容中找不到我要查找的元素。这对我来说很奇怪,因为当您右键单击序列并检查元素本身时,元素(您提供的 xpath)确实存在。然而,这并没有反映在页面源代码中
    • 是的 - 页面“MYS”上的文本正在被一个名为“EntrezSystem2.PEntrez.Protein.Sequence_ResultsPanel.SequenceViewer.Sequence_ViewerReport.dopt”的程序调用。这就是为什么我无法从页面中抓取序列。
    【解决方案4】:

    @brucezepplin,我感到你很沮丧。 @Mathias Muller,我使用了您编写的内容并运行了以下内容:

    test <- "http://www.ncbi.nlm.nih.gov/protein/225903367?report=fasta" 
    doc <- htmlTreeParse(test, asText = TRUE, useInternalNodes = TRUE) 
    xpathSApply(doc, "//div[@id = 'viewercontent1']", xmlValue)
    xpathSApply(doc, "//div[@id = 'viewercontent1']//span[@id = 'gi_225903367_1']", xmlValue)
    xpathSApply(doc, "//div[@id = 'viewercontent1']/gi/span", xmlValue))
    

    首先,当我查看“doc”时,它只显示了几行标题,而不是整页。

    但是第一个 xpath 返回了list(),所以至少它可以正常工作。接下来的两个返回NULL。在所需的跨度节点之前有一个&lt;pre&gt; 以及一个>gi。

    简而言之,这不是一个答案,但也许会让其他人更容易提供解决方案。

    【讨论】:

      猜你喜欢
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 2021-06-17
      相关资源
      最近更新 更多