【问题标题】:How to list all TD elements containing a SPAN?如何列出包含 SPAN 的所有 TD 元素?
【发布时间】:2014-03-27 13:15:17
【问题描述】:

我正在尝试使用 Fizzler 在 C# 中解析网站。我的目标是获得这个元素: /html/body/form/div[3]/div/div/div/div/div/table/tbody/tr[18]/td[2]/span (FireBug XPath)。

问题在于 TR 和 TD 编号不固定。据我所知,我总是需要 LAST 跨度,在 LAST TD 中,在 LAST TR 中 :)

我正在尝试这个,但我得到的只是 NULL:

HtmlWeb document = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = document.Load("http://websiteaddress.com/site-name.html");

HtmlNodeCollection tableDatas = doc.DocumentNode.SelectNodes("//table/tbody/tr/td/span").Last();

这是我要解析的 TABLE。我只需要最后一行最后一个 td 中最后一个 span 的内容。

<table id="ctl00_WebPartManager1_blablabla_ctl00_tblRates" cellspacing="5" cellpadding="5" rules="all" border="1" style="width:100%;">
                <tr>
                    <th></th><th><span>USD</span></th>
                </tr><tr>
                    <th></th><th><span>USA $</span></th>
                </tr><tr>
                    <th></th><th><span>1</span></th>
                </tr><tr>
                    <td><span>2014. 03. 03.</span></td><td><span>227,31 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 04.</span></td><td><span>226,79 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 05.</span></td><td><span>225,66 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 06.</span></td><td><span>225,03 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 07.</span></td><td><span>223,14 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 10.</span></td><td><span>224,63 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 11.</span></td><td><span>226,06 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 12.</span></td><td><span>226,53 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 13.</span></td><td><span>223,63 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 14.</span></td><td><span>225,74 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 17.</span></td><td><span>224,67 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 18.</span></td><td><span>224,65 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 19.</span></td><td><span>223,26 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 20.</span></td><td><span>225,94 </span></td>
                </tr><tr>
                    <td><span>2014. 03. 21.</span></td><td><span>226,25 </span></td>
                </tr>
            </table>

这是我从 document.load() 方法得到的结果(有点乱...):

    <table id="ctl00_WebPartManager1_blablabla_ctl00_tblRates" cellspacing="5" cellpadding="5" rules="all" border="1" style="width:100%;">
                <tr>
                    <th><th><span>USD</span>
                <tr>
                    <th><th><span>USA $</span>
                <tr>
                    <th><th><span>1</span>
                <tr>
                    <td><span>2014. 03. 03.</span><td><span>227,31 </span>
                <tr>
                    <td><span>2014. 03. 04.</span><td><span>226,79 </span>
                <tr>
                    <td><span>2014. 03. 05.</span><td><span>225,66 </span>
                <tr>
                    <td><span>2014. 03. 06.</span><td><span>225,03 </span>
                <tr>
                    <td><span>2014. 03. 07.</span><td><span>223,14 </span>
                <tr>
                    <td><span>2014. 03. 10.</span><td><span>224,63 </span>
                <tr>
                    <td><span>2014. 03. 11.</span><td><span>226,06 </span>
                <tr>
                    <td><span>2014. 03. 12.</span><td><span>226,53 </span>
                <tr>
                    <td><span>2014. 03. 13.</span><td><span>223,63 </span>
                <tr>
                    <td><span>2014. 03. 14.</span><td><span>225,74 </span>
                <tr>
                    <td><span>2014. 03. 17.</span><td><span>224,67 </span>
                <tr>
                    <td><span>2014. 03. 18.</span><td><span>224,65 </span>
                <tr>
                    <td><span>2014. 03. 19.</span><td><span>223,26 </span>
                <tr>
                    <td><span>2014. 03. 20.</span><td><span>225,94 </span>
                <tr>
                    <td><span>2014. 03. 21.</span><td><span>226,25 </span>

            </td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></th></th></tr></th></th></tr></th></th></tr></table>

有人可以帮帮我吗?

非常感谢!

【问题讨论】:

标签: c# xpath html-agility-pack fizzler


【解决方案1】:

除了&lt;tbody&gt; 元素being introduced by the browser,但不是由 HTML Agility Pack 提供的(这就是您根本收不到任何结果的原因);使用[last() 谓词访问当前元素中的最后一个子元素。

//table/tr[last()]/td[last()]/span[last()]

你也可以查询所有的最后一个 span,但这可能会慢一点,因为它必须在之前构造整个结果集:

(//table/tr/td/span)[last()]

在 C# 中使用 .Last(); 会稍微差一些,因为在省略除最后一个值之外的所有值之前,结果集甚至必须构造为 C# 数组。

【讨论】:

  • 你是对的,这是问题所在:) 我唯一的问题是为什么它返回日期(2014.03.21.)而不是利率?所以我假设它正在获取第一个 TD,而不是最后一个。
  • 您一定是查询了错误的数据,或者输入中没有汇率。这个查询肯定应该返回最后的费率,并且对我有用(在 BaseX 中测试)。
  • 用我从 Load() 函数得到的结果更新了我的问题。我认为问题在于混乱的桌子结构......
  • HTML 没有正确关闭标签。试试//table/tr//span[last()],它会忽略实际的树结构并获取每个表行的最后一个 span 元素。
  • 是的,TR-s 现在互相嵌套了……一团糟。您的代码返回:美元。所以,直到最后一个跨度才通过 TRs :(
【解决方案2】:

您可以使用last() 而不是确切的元素位置来获取结果集中的最后一个元素:

//table/tr[last()]/td[last()]/span[last()]

XPath 上方将获取最后一个&lt;tr&gt;,然后在该&lt;tr&gt; 中查找最后一个&lt;td&gt;,然后在该&lt;td&gt; 中查找最后一个&lt;span&gt;

如果这不是您想要的,我建议发布示例 html,以便我们更容易更好地理解问题。

【讨论】:

  • 谢谢,这对我来说也返回 NULL,但我将表格数据添加到我的问题帖子中。
猜你喜欢
  • 1970-01-01
  • 2015-05-18
  • 1970-01-01
  • 2018-02-19
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 2015-10-10
  • 2015-01-29
相关资源
最近更新 更多