【问题标题】:Using HtmlAgilityPack to get a specific row and column data使用 HtmlAgilityPack 获取特定的行和列数据
【发布时间】:2015-03-19 12:57:34
【问题描述】:

这是我的桌子

<table class="DataRows" frame="myFrames" rules="Standard" width="100%">

  <colgroup><col width="70" align="CENTER">
  <col width="200" align="LEFT">
  <col width="80" align="LEFT">
  <col align="LEFT">
  <col align="RIGHT">

  </colgroup><thead>

  <col width="70" align="CENTER">
  <col width="200" align="LEFT">
  <col width="80" align="LEFT">
  <col align="LEFT">
  <col align="RIGHT">

  <thead>

  <tr>
    <td valign="TOP"><span class="classicBold"> 20 </span> Kg.
    <td class="BOLD" valign="TOP" nowrap="">
      PA Passion Foods Inc.
    <td class="BOLD">Fax:
    <td>
      222-555666
    <td class="BOLD">
      Processed foods and juices

  <tr>
    <td><a target="_blank" href="">See on Map </a>
    <td>
      120 NW 157TH AVE 
    <td class="BOLD">Warehouse Hours:
    <td colspan="2">


  <tr>
    <td>
    <td><span class="BOLD">
      Jacksonville,
      </span>
      FL 300000
    <td class="BOLD">Url:
    <td colspan="2">
      <a target="_blank" href="">PA Passion</a>
      &nbsp&nbsp
      <span class="BOLD">E-mail:</span>
      zoro@xyz.com

  <tr>
    <td>
    <td class="REDBOLD" colspan="4">


  <tr>
    <td>
    <td colspan="4" align="LEFT">Franchisee for:<span class="BOLD">
 Nutrella


</span>
  <tr>
    <td>
    <td colspan="4" align="LEFT">Franchisee for:<span class="BOLD">
APPLE Foods, Constants
</span>
  <tr>
    <td>
    <td colspan="4" align="LEFT"><span class="BOLD">

</span>

  <tr>
    <td>
    <td colspan="4" align="LEFT">We service:<span class="BOLD">
All occasions and hospitality services
</span>

  <tr>
    <td>
    <td colspan="4" align="LEFT">We sell :<span class="BOLD">
----
</span>

</td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></td></td></tr></td></td></td></td></tr></td></td></td></td></td></tr>
  </thead>
</table>

我正在使用下面的代码遍历我的 Html 文档中的每个节点

foreach (HtmlNode node in htmlAgilityPackDoc.DocumentNode.SelectNodes("//table[contains(@class,'DataRows')]"))
{

}

当我使用下面的

node.SelectSingleNode(".//tr[1]/td[1]").InnerHtml

我得到以下html

<span class="classicBold"> 20 </span> Kg.
        <td class="BOLD" valign="TOP" nowrap="">
          PA Passion Foods Inc.
        <td class="BOLD">Fax:
        <td>
          222-555666
        <td class="BOLD">
          Processed foods and juices

      <tr>
        <td><a target="_blank" href="">See on Map </a>
        <td>
          120 NW 157TH AVE 
        <td class="BOLD">Warehouse Hours:
        <td colspan="2">


      <tr>
        <td>
        <td><span class="BOLD">
          Jacksonville,
          </span>
          FL 300000
        <td class="BOLD">Url:
        <td colspan="2">
          <a target="_blank" href="">PA Passion</a>
          &nbsp&nbsp
          <span class="BOLD">E-mail:</span>
          zoro@xyz.com

      <tr>
        <td>
        <td class="REDBOLD" colspan="4">


      <tr>
        <td>
        <td colspan="4" align="LEFT">Franchisee for:<span class="BOLD">
     Nutrella


    </span>
      <tr>
        <td>
        <td colspan="4" align="LEFT">Franchisee for:<span class="BOLD">
    APPLE Foods, Constants
    </span>
      <tr>
        <td>
        <td colspan="4" align="LEFT"><span class="BOLD">

    </span>

      <tr>
        <td>
        <td colspan="4" align="LEFT">We service:<span class="BOLD">
    All occasions and hospitality services
    </span>

      <tr>
        <td>
        <td colspan="4" align="LEFT">We sell :<span class="BOLD">
    ----
    </span>

    </td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></tr></td></td></td></td></tr></td></td></td></td></tr></td></td></td></td></td>

如何从中提取地址 120 NW 157TH AVE

当我尝试使用时

node.SelectSingleNode(".//td[@class='BOLD'][4]/preceding-sibling::td").InnerText;

我得到一个错误:

对象引用未设置为对象的实例

【问题讨论】:

    标签: c# xpath xml-parsing html-agility-pack


    【解决方案1】:

    您的 html 是一团乱七八糟的标签,我建议您使用文本节点作为标识符而不是索引,例如

    .//td[./a[contains(text(),'See on Map')]]/td/text() 
    

    得到

    120 NW 157TH AVE

    这是一个完整的示例,可以为您提供一切

        var table = doc.DocumentNode.SelectSingleNode("//table[contains(@class,'DataRows')]");
    
        var name = table.SelectSingleNode(".//td[@class='BOLD']/text()").InnerText.Trim();
        var fax = table.SelectSingleNode(".//td[contains(text(),'Fax')]/td/text()").InnerText.Trim();
        var email = table.SelectSingleNode(".//span[contains(text(),'E-mail')]/following-sibling::text()").InnerText.Trim();
        var address = table.SelectSingleNode(".//td[./a[contains(text(),'See on Map')]]/td/text()").InnerText.Trim();
        var city = table.SelectSingleNode(".//tr[./td/a[contains(text(),'See on Map')]]//tr/td/td/span").InnerText.Trim(',');
        var zip = table.SelectSingleNode(".//tr[./td/a[contains(text(),'See on Map')]]//tr/td/td/span/following-sibling::text()").InnerText.Trim();
    

    请注意,由于您的 html 有多混乱,xpath 必须如此混乱,尝试按索引访问 tr 元素将不起作用,因为所有 tr 元素都是前一个 tr 的子元素,@987654326 是什么普通表中的@ 是您表中的.//tr/tr/tr/tr

    【讨论】:

    • 有趣的是,当我在网站上看到 html 时,它似乎没有任何问题,但是当我使用 .. SelectNodes("//table[contains(@class ,'DataRows')]" 并调用它的InnerHtml,然后它似乎取消了行和列的结束标记..我不知道这是怎么回事。
    • @user20358 因为浏览器试图修复错误的 html 并且非常擅长这一点,所以像上面那样编写错误的 html 的一个原因是为了更难抓取,浏览器无论如何都擅长修复它。
    • 啊哈!.. 我知道这不可能是魔法!感谢那里的提示。顺便说一句,我也使用循环让它工作。它也可以很好地工作
    猜你喜欢
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多