Xpath无法处理HtmlAgilityPack文档

时间:2015-03-06 06:07:53

标签: vb.net xpath html-agility-pack

我有一个特殊的问题。当我尝试将Xpath应用于HtmlAgility.HtmlDocument时,它不起作用。但是当我使用相同文档的内部html并创建另一个HtmlAgility.HtmlDocument对象时,会找到匹配项。真的很感激任何想法。

Dim ret As String = Nothing
Dim tmpHtmlNode As HtmlNode = _pageHTML.DocumentNode.SelectSingleNode(token.MatchingXPath)
If tmpHtmlNode IsNot Nothing AndAlso tmpHtmlNode.InnerText IsNot Nothing Then ' THIS FETCHES NULL'
    ret = tmpHtmlNode.InnerText.Trim
End If

Dim x As New HtmlAgilityPack.HtmlDocument
x.LoadHtml(_pageHTML.DocumentNode.InnerHtml)
Dim node As HtmlNode = Nothing
node = x.DocumentNode.SelectSingleNode(token.MatchingXPath)
Console.WriteLine(node.InnerText) ' THIS WORKS'

在上面的coce中,tmpHtmlNode在评估XPath后为NULL。以下node会返回所需的文字。

使用的Xpath是"//*[contains(text(),'Number of Discs:')]/following-sibling::text()",预期匹配的Html部分是:

<h2>Product Details</h2>
<div class="content">
  <ul>
    <li><b>Performer:</b> <a href="/s/ref=dp_db_clas_perf?ie=UTF8&amp;keywords=Royal%20Scots%20Dragoon%20Guards&amp;search-alias=classical">Royal Scots Dragoon Guards</a></li>
  <li><b>Audio CD</b>  (March 24, 1992)</li>
  <li><b>Number of Discs:</b> 1</li>
  <li><b>Label:</b> RCA</li>
  <li><b>ASIN:</b> B000002WEN</li>
  <li><b>Average Customer Review:</b>
  <li id="SalesRank">
    <b>Amazon Best Sellers Rank:</b>
    #68,703 in Music (<a href="http://www.amazon.com/best-sellers-music-albums/zgbs/music/ref=pd_dp_ts_m_1">See Top 100 in Music</a>)
  </li>
</ul>
<span class="tiny">
  <ul class="noteBullets">
  </ul>
</span>
</div>

2 个答案:

答案 0 :(得分:0)

<li>
  <b>Number of Discs:</b>
 1
</li>'

也许这会有所帮助

//b[contains(text(), 'Number of Discs')]/../text()

我认为数字&#34;属于&#34;到li节点,而不是b。这就是为什么你不能说跟随兄弟:: text()

答案 1 :(得分:0)

原始问题HtmlDocument是在针对XPath解析下载的html时,它没有返回任何匹配项。而当使用相同的html创建另一个HtmlDocument并且使用相同的XPath解析时,它找到了匹配。因此问题不在于实际的XPath,否则它在第二个实例中不起作用(这就是为什么我没有在第一个实例中发布XPath)。

在调用问题中发布的代码之前,运行以下代码来解析同一HtmlDocument

中的另一个(不同的)字段
        Dim ret As List(Of String) = Nothing
        Dim tmpHtmlNodes As HtmlNodeCollection = _pageHTML.DocumentNode.SelectNodes(token.MatchingXPath)
        If tmpHtmlNodes IsNot Nothing AndAlso tmpHtmlNodes.Count > 0 Then
            For Each tmpHtmlNode As HtmlNode In tmpHtmlNodesx
                If tmpHtmlNode IsNot Nothing AndAlso tmpHtmlNode.InnerText IsNot Nothing Then
                    If ret Is Nothing Then ret = New List(Of String)
                    ret.Add(tmpHtmlNode.InnerText.Trim)
                    tmpHtmlNode = Nothing
                End If
            Next
        End If
        tmpHtmlNodes.Clear()
        Return ret

此字段的解析逻辑具有行tmpHtmlNodes.Clear(),这是罪魁祸首。这会更改HtmlDocument并导致下一次解析失败的调用,因为它无法找到clear()删除的节点。

总结这个问题: 1.在上面的问题中列出的解析逻辑运行之前,有另一个解析逻辑运行与clears()匹配的HtmlNodeCollection个节点 2.这会影响下一个解析逻辑运行的HtmlDocument(这是问题中列出的逻辑) 因此,Xpath失败

仍有疑问是_pageHtml因为早期的HtmlNodeCollection.Clear()而被更改,那么为什么我会从_pageHtml获取Html并创建另一个HtmlDocument然后运行这个新HtmlDocument工作的解析逻辑是什么?