HTML Agility Pack的行为不符合预期

时间:2012-03-02 09:55:02

标签: html-parsing html-agility-pack

我正在尝试使用HTML Agility Pack解析此HTML页面,但我似乎无法按预期工作。

这是我的页面(缩短):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de-ch" xml:lang="de-ch">
<head>
</head>
<body id="Adressservices">
    <div id="page">
        <div id="page-544">
            <table class="full">
                <thead>
                    <tr>
                        <th class="first" scope="col" style="width: 18%;">Type</th>
                        <th class="col" style="width: 20%;">Name</th>
                        <th class="col">Date</th>
                        <th class="col" style="text-align: right; width: 10%;">Size</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td class="first">Change</td>
                        <td><a href="/download?file=5210044">somefile01.zip</a></td>
                        <td style="width: 5%;"><b class="filesize">2012-03-01</b></td>
                        <td style="text-align: right;"><b class="filesize">881.00</b></td>
                    </tr>
                    <tr>
                        <td class="first">Change</td>
                        <td><a href="/download?file=7610042">somefile02.zip</a></td>
                        <td style="width: 5%;"><b class="filesize">2012-02-01</b></td>
                        <td style="text-align: right;"><b class="filesize">1400.00</b></td>
                    </tr>
                    <tr>.....</tr>
                </tbody>
            </table>
        </div>
    </div>
</body>
</html>

真实页面在该表格中有更多<tr>....</tr>行。

我可以使用此代码段轻松下载HTML Agility Pack页面:

HtmlWeb web = new HtmlWeb();
HtmlDocument archiveDoc = web.Load(_archiveUrl);
var tables = archiveDoc.DocumentNode.SelectNodes("//table");

所以我处理了<table>元素,工作得很好。

现在我试图从该表中获取第一个 <tr>元素,我尝试了这个:

HtmlNode node = tables[0];
var allTRNodes = node.SelectNodes("tbody/tr");
var firstTR = allTRNodes[0];

在这里,我没有按预期获得n <tr>个节点 - 但只有两个节点。其中第一个不包含<td>类型的y子节点列表......

然后我尝试了Linq-to-“HTML”:

HtmlNode node = tables[0];
var firstTR = node.Element("tbody").Element("tr");

但又一次:我没有得到第一个<tr>节点,其中包含<td>类型的y子节点列表......

尝试获取第一个<td>内所有<tr>个节点的列表也没有按预期工作:

HtmlNode node = tables[0];
var allTDNodes = node.SelectNodes("tbody/tr/td");
var firstTD = allTDNodes[0];

而不是预期的y <td>个节点,我只得到三个子节点 - #text中的两个,类型<td>中的最后一个 - 为什么?

似乎HTML Agility Pack错误地将<td>节点列表误解为嵌套节点......

有什么想法吗?思考?提示如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

使用后代,如下例所示:

var linkNode = doc.DocumentNode.SelectSingle("//div[@id=\"content-wrapper\"]/dl/dd");
var hrefNode = linkNode.SelectSingleNode("descendant::a");

我不同意HtmlAgility包那个node.SelectNode *从顶部调用遍历dom而不是从当前节点遍历

这是您的案例采用的样本

// table 
var tableNode = docNode.SelectSingleNode("//table"); 
// first tr
var trNode = tableNode.SelectSingleNode("descendant::tr"); 

// you can also try, but it's overkill
var trNode1 = tableNode.SelectSingleNode("descendant::tr[0]"); 

// then your td
var tdNode = trNode.SelectSingleNode("descendant::td");