【问题标题】:Advanced HTML Agility Pack useage高级 HTML 敏捷包使用
【发布时间】:2011-06-04 05:08:16
【问题描述】:

我对 HTML Agility Pack 还很陌生,所以我需要一些帮助来了解下一步该去哪里。我可以做一些简单的事情,比如从 href 中提取一个值(知道我正在寻找的 url 字符串),我可以根据正在使用的特定类在跨度中提取值。但是我不明白如何在有大量或标签的情况下使用 HTML Agility Pack,而这些标签不是一个真正的可靠锚点?

这是我正在浏览的一段实际代码。我在单元格中放置了虚拟数据以展示我在寻找什么。

提取以下内容的最佳方法是什么:

1.) 公司名称?

2.) 电话号码?

3.) 电子邮件地址?

HTML....

<td>
  <!-- Company Info -->
  <table cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td class="black">
        <table cellspacing="1" cellpadding="0" border="0" width="370">
          <tr>
            <th>COMPANY NAME</th>
          </tr>
          <tr>
            <td class="search">
              <table cellpadding="5" cellspacing="0" border="0" width="100%">
                <tr>
                  <td>
                    <table cellpadding="1" cellspacing="0" border="0" width="100%">
                      <tr>
                        <td colspan="2" align="center">Un-needed Links...</td>
                      </tr>
                      <tr>
                        <td align="center" colspan="2"><hr></td>
                      </tr>
                      <tr>
                        <td align="right" nowrap>
                          <b>
                            <font color="FF0000">
                              Contact Person&nbsp;
                              <img src="/images/icon_contact.gif" align="absmiddle">&nbsp;:
                            </font>
                          </b>
                        </td>
                        <td align="left" width="100%">&nbsp;Judy Smith</td>
                      </tr>
                      <tr>
                        <td align="right" nowrap>
                        <b><font color="FF0000">Phone Number&nbsp;<img src="/images/icon_phone.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;555-555-5555</td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">E-mail Address&nbsp;<img src="/images/icon_email.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;<a HREF="mailto:judy.smith@companyname.com">judy.smith@companyname.com</a></td>
                      </tr>
                      <tr>
                        <td align="center" colspan="2"><hr></td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">Home Office Location&nbsp;<img src="/images/icon_home.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;ATLANTA, GA</td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">Home Office Phone&nbsp;<img src="/images/icon_home.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;555-555-5555</td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">Home Office Fax&nbsp;<img src="/images/icon_home.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;666-666-6666</td>
                      </tr>
                      <tr>
                        <td align="center" colspan="2"><hr></td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">Broker MC Number&nbsp;<img src="/images/icon_number.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;123456</td>
                      </tr>
                      <tr>
                        <td align="right" nowrap><b><font color="FF0000">Carrier MC Number&nbsp;<img src="/images/icon_number.gif" align="absmiddle">&nbsp;:</font></b></td>
                        <td align="left" width="100%">&nbsp;654321</td>
                      </tr>
                    </table>
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
  <br>

  <!-- Starting Point -->
  <table cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td class="black">
        <table cellspacing="1" cellpadding="0" border="0" width="370">
          <tr>
            <th>Starting Point</th>
            <th>Available</th>
          </tr>
          <tr>
            <td class="search" width="270">&nbsp;<b>ABBEVILLE, GA&nbsp;</b></td>
            <td class="search" align="center" width="100"><span style="color: forestgreen">&nbsp;1/5/11&nbsp;</span></td>
          </tr>
        </table>
      </td>
    </tr>

  </table>
  <br>
  <!-- Destination Point -->
  <table cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td class="black">
        <table cellspacing="1" cellpadding="0" border="0" width="370">
          <tr>
            <th>Destination Point</th>
            <th>Direction</th>
          </tr>
          <tr>
            <td class="search" width="270">&nbsp;<b>ATLANTA, GA&nbsp;</b></td>
            <td class="search" align="center" width="100"><span style="color: FF0000">&nbsp;&nbsp;</span></td>
          </tr>
        </table>
      </td>

    </tr>
  </table>
  <br>
  <!-- Truck Details -->
  <table cellpadding="0" cellspacing="0" border="0">
    <tr>
      <td class="black">
        <table cellspacing="1" cellpadding="0" border="0" width="370">
          <tr>
            <th>Truck Details</th>
          </tr>
          <tr>
            <td class="search">
              <table cellpadding="5" cellspacing="0" border="0">
                <tr>
                  <td>
                    <table cellpadding="0" cellspacing="0" border="0">
                      <tr>
                        <td align="right"><b>Date Posted&nbsp;:</b></td>
                        <td align="left">&nbsp;&nbsp;1/5/2011 10:34:48 AM</td>
                      </tr>
                      <tr>
                        <td align="right"><b>Quantity&nbsp;:</b></td>
                        <td align="left">&nbsp;&nbsp;1</td>
                      </tr>
                      <tr>
                        <td align="right"><b>Equipment Type&nbsp;:</b></td>
                        <td align="left">&nbsp;&nbsp;FT</td>
                      </tr>
                      <tr>
                        <td align="right"><b>Load Size&nbsp;:</b></td>
                        <td align="left">&nbsp;&nbsp;Full</td>
                      </tr>
                      <tr>
                        <td align="right" valign="top"><b>Special Information&nbsp;:</b></td>
                        <td align="left">&nbsp;&nbsp;</td>
                      </tr>
                    </table>
                  </td>
                </tr>
              </table>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
  <br>
</td>

....更多 HTML

【问题讨论】:

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


    【解决方案1】:

    嗯,您必须了解 XPATH 才能真正利用 HTML 敏捷包抓取功能 :-) 您可以通过 Google XPATH examples 开始使用。

    专注于屏幕抓取问题,棘手的部分是选择您认为对您想要获取的信息最具辨别力的 xpath 表达式。大多数情况下,解决方案不止一种,您必须准备好更新代码以与目标站点 HTML 演变保持一致。

    因此,这是在非常简单的表达式之间进行权衡,有可能匹配不需要的文本,而过度判别表达式则不能容忍抓取的 HTML 的演变,有可能不匹配任何内容。

    至于您的具体文本,这是一个很好的真实示例,下面是一个代码:

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(yourText);
    
    string companyName = doc.DocumentNode.SelectSingleNode("/td/table/tr/td/table/tr/th").InnerText;
    Console.WriteLine("company name=" + companyName);
    
    // another way
    companyName = doc.DocumentNode.SelectSingleNode("//td[@class='black']/table/tr/th").InnerText;
    Console.WriteLine("company name=" + companyName);
    
    // a more advanced XPATH expression, means
    // "Select a TD tag anywhere in the doc that has a preceding sibling of TD type with a B chid, with a FONT child with inner text starting with 'Phone Number'"
    string phoneNumber = doc.DocumentNode.SelectSingleNode("//td[starts-with(preceding-sibling::td/b/font/text(), 'Phone Number')]").InnerText;
    Console.WriteLine("phone Number=" + phoneNumber);
    
    // same kind of story but go down the next A tag
    string email = doc.DocumentNode.SelectSingleNode("//td[starts-with(preceding-sibling::td/b/font/text(), 'E-mail')]/a").InnerText;
    Console.WriteLine("email=" + email);
    

    PS:请注意 HTML Agility Pack 总是希望 XPATH 表达式中使用的标签是小写的,即使它们不在原始 HTML 文本中。

    如您所见,此处使用两种不同的表达式检索公司名称。他们都在样本上工作,但如果在中间的任何地方添加新标签,第一个不会抗拒。第二个更面向未来,但基于 CSS 类标签,也可能会改变。这总是一个权衡。

    电话号码和电子邮件相似,但显示了 XPATH 的强大功能。

    【讨论】:

    • 这是一个了不起的答案。非常感谢您提供的多个示例。
    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多