【问题标题】:Correlate Adjacent Element Vales using HTML Agility Pack使用 HTML Agility Pack 关联相邻元素值
【发布时间】:2011-07-26 20:36:51
【问题描述】:

我正在尝试获取 HTML 注释后面带有文本“结果”的 h2 元素,然后是类名称为“stockfeed”的表格元素。

我已经知道如何提取我需要的数据(见下文),但我不确定如何同时将这 2 个元素拉到一起。我知道我可以使用相同的索引器来迭代集合以关联值,但这似乎很容易出错,因为我的 h2 元素之一可能没有相邻的表元素(罕见但可能)。

HTML 标记示例:

<h1>
    Results Page</h1>
<h2>
    Updated Daily @ 10:00 AM</h2>
<div class='someClass1'>
    <!-- Results -->
    <div class='something'>
    </div>
    <h2 style='display: inline;'>
        <a href='http://www.somesite.com'>Table 1</a>
    </h2>
    <div class='clr'>
    </div>
    <div class='resultBlock'>
        <table class='stockfeed'>
            <thead>
                <tr>
                    <th>
                        Part
                    </th>
                    <th>
                        Description
                    </th>
                    <th>
                        Stock
                    </th>
                    <th>
                        Price
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr class='row1' valign='top'>
                    <td>
                        A 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
                <tr class='row1' valign='top'>
                    <td>
                        B 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
                <tr class='row1' valign='top'>
                    <td>
                        C 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    <!-- Results -->
    <div class='something'>
    </div>
    <h2 style='display: inline;'>
        <a href='http://www.somesite.com'>Table 2</a>
    </h2>
    <div class='clr'>
    </div>
    <div class='resultBlock'>
        <table class='stockfeed'>
            <thead>
                <tr>
                    <th>
                        Part
                    </th>
                    <th>
                        Description
                    </th>
                    <th>
                        Stock
                    </th>
                    <th>
                        Price
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr class='row1' valign='top'>
                    <td>
                        A 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
                <tr class='row1' valign='top'>
                    <td>
                        B 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
                <tr class='row1' valign='top'>
                    <td>
                        C 1234567890
                    </td>
                    <td class='description'>
                        Part Description
                    </td>
                    <td>
                        1,000,000
                    </td>
                    <td>
                        $1.99
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

分别解析值的当前代码:

    HtmlNodeCollection titles = doc.DocumentNode.SelectNodes("//comment()[contains(.,'Results')]/following-sibling::h2");
    for (int tit = 0; tit < titles.Count; ++tit)
    {
        // Do Something
    }

    HtmlNodeCollection tables = doc.DocumentNode.SelectNodes("//table[@class='stockfeed']");
    for (int tab = 0; tab < tables.Count; ++tab)
    {
        // Do Something
    }

【问题讨论】:

  • +1 表示不使用正则表达式。 ;)
  • 只是为了清楚目标是什么,你想要获得什么元素?你从来没有明确说过你想要得到什么(尽管可以从代码中推断出你可能想要什么)。
  • 杰夫,我正在尝试获取注释“”之后的 h2 元素,然后是类为“stockfeed”的表格元素。
  • @Zachary:我已经想到了,但您可能想在问题本身中说明这一点。 ;)

标签: c# web-scraping html-agility-pack


【解决方案1】:

所以,如果我没看错,你就是在尝试获取每个结果对应的表格。

您可以使用与获取以下h2 元素类似的方法来获取与其相关的以下table 元素。

var query = doc.DocumentNode
    .SelectNodes("//comment()[contains(.,'Results')]/following-sibling::h2");

foreach (var h2 in query.Cast<HtmlNode>())
{
    var table = h2.SelectSingleNode("following-sibling::*/table[@class='stockfeed']");
    // do stuff with h2 and table
}

【讨论】:

  • 所以当你有一个过滤的集合“例如 h2.SelectSing(....)”时你仍然可以访问整个 DOM?
  • 当然可以!尽管您的查询将与您当前所在的节点相关。
  • 知道了这一点,它确实使 HAP 变得非常强大和易于使用......我现在可以愉快地淘汰所有旧的字符串/正则表达式 HTML 解析器了!谢谢!
猜你喜欢
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 2012-02-10
  • 1970-01-01
相关资源
最近更新 更多