【问题标题】:Scraping With HtmlAgilityPack使用 HtmlAgilityPack 进行抓取
【发布时间】:2012-10-30 23:04:04
【问题描述】:

我有一个巨大的 html 页面,我想从中删除值。

我尝试使用 Firebug 来获取我想要的元素的 XPath,但它不是静态 XPath,因为它会不时更改,所以我如何获得我想要的值。

在下面的 sn-p 中,我想获取位于 20 的每小时木材产量

    <div class="boxes-contents cf"><table id="production" cellpadding="1" cellspacing="1">
    <thead>
        <tr>
            <th colspan="4">
                Production per hour:            </th>
        </tr>
    </thead>
    <tbody>
                <tr>
            <td class="ico">
                <img class="r1" src="img/x.gif" alt="Lumber" title="Lumber" />
            </td>
            <td class="res">
                Lumber:
            </td>
            <td class="num">
                20          </td>
        </tr>
                <tr>
            <td class="ico">
                <img class="r2" src="img/x.gif" alt="Clay" title="Clay" />
            </td>
            <td class="res">
                Clay:
            </td>
            <td class="num">
                20          </td>
        </tr>
                <tr>
            <td class="ico">
                <img class="r3" src="img/x.gif" alt="Iron" title="Iron" />
            </td>
            <td class="res">
                Iron:
            </td>
            <td class="num">
                20          </td>
        </tr>
                <tr>
            <td class="ico">
                <img class="r4" src="img/x.gif" alt="Crop" title="Crop" />
            </td>
            <td class="res">
                Crop:
            </td>
            <td class="num">
                59          </td>
        </tr>
            </tbody>
</table>
    </div>

【问题讨论】:

  • 能否请您发布一些代码来显示您已经尝试过的内容。
  • 这是一个地狱般的试验,没有对象引用错误无论如何我会说它虽然没用

标签: c# html-agility-pack


【解决方案1】:

使用 Html 敏捷包,您需要执行以下操作。

byte[] htmlBytes;
MemoryStream htmlMemStream;
StreamReader htmlStreamReader;
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlBytes = webclient.DownloadData(url);
htmlMemStream = new MemoryStream(htmlBytes);
htmlStreamReader = new StreamReader(htmlMemStream);
htmlDoc.LoadHtml(htmlStreamReader.ReadToEnd());

var table = htmlDoc.DocumentNode.Descendants("table").FirstOrDefault();

var lumberTd = table.Descendants("td").Where(node => node.Attributes["class"] != null && node.Attributes["class"].Value == "num").FirstOrDefault();

string lumberValue = lumberTd.InnerText.Trim();

警告,'FirstOrDefault()' 可能返回 null,因此您可能应该在其中进行一些检查。

希望对您有所帮助。

【讨论】:

  • 首先非常感谢您的有用帖子,但有没有更直接的方法可以从网页中获取我想要的值,特别是它不是标有特定 ID 的值。 ?
  • 从您提供的示例 html 中,我看不到任何唯一 ID 可以让您更轻松地提取您想要的数据。
  • 不,你错过了理解我的意思,我的意思是当元素有一个 ID 时,我可以很容易地使用 GetElementById 来获取它,所以有没有像 GetElementById 方法这样直接的方法来获取特定节点而无需嵌套大量代码?
  • 是的,你可以做 htmlDoc.DocumentNode.Descendants().Where(node => node.Attributes["id"] != null && node.Attributes["id"].Value == "myid").FirstOrDefault();
【解决方案2】:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(fileName);

var result = doc.DocumentNode.SelectNodes("//div[@class='boxes-contents cf']//tbody/tr")
                .First(tr => tr.Element("td").Element("img").Attributes["title"].Value == "Lumber")
                .Elements("td")
                .First(td=>td.Attributes["class"].Value=="num")
                .InnerText
                .Trim();

【讨论】:

  • 这真的是一段非常好的代码,但我想知道如何确定获得我想要的元素的代码。不要给我一条鱼,而是教我如何获得一条鱼:D,我记得它:P
猜你喜欢
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 2017-01-20
  • 2012-07-20
  • 1970-01-01
相关资源
最近更新 更多