3

我已经安装了HTMLAgilityPack,但是一旦捕获文档表,我就无法掌握如何提取第一个 td 元素包含格式中今天日期的行dd-mmm-yy

任何人都可以用代码片段指出我正确的方向吗?

目前我有:

HtmlDocument doc = new HtmlDocument();
doc.Load("http://lbma.org.uk/pages/printerFriendly.cfm?thisURL=index.cfm&title=gold_fixings&page_id=53&show=2012&type=daily");
foreach(HtmlNode tr in doc.DocumentNode.SelectNodes("tr"))
{
            
}
4

3 回答 3

1

乐趣。该页面的 Html 格式非常错误,因此我可以看到您的问题。不过,我不会用 10 英尺长的杆子接触 XPath。Linq 让生活变得如此轻松。

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://lbma.org.uk/pages/printerFriendly.cfm?thisURL=index.cfm&title=gold_fixings&page_id=53&show=2012&type=daily");

HtmlNode todaysRow = doc.DocumentNode.Descendants("tr").Where(n => n.InnerText.StartsWith(string.Format("{0:dd-MMM-yy}", DateTime.Today), StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
if (todaysRow != null)
{
    List<HtmlNode> cells = todaysRow.Descendants("td").ToList();
    decimal usd = decimal.Parse(cells[1].FirstChild.InnerText);
    decimal gbp = decimal.Parse(cells[2].FirstChild.InnerText);
    // ... etc 
} 
于 2012-05-30T23:19:58.183 回答
0

试试这个:

Dictionary<string, string> values = new Dictionary<string, string>();
string key, date;
HtmlDocument doc = Load(html);
HtmlNode node = doc.DocumentNode.SelectSingleNode(".//table[@class='pricing detail']");
//this will pull out only the dates, and store them in variable 'date'
foreach(HtmlNode child in node.SelectNodes(".//tr[@class='left']")
{
    date = child.GetInnerText;
}
//this will pull out the dates and the prices, and put them into a mapped data structure for easy (and quick!) referencing
foreach(HtmlNode child in node.SelectNodes(".//tr")
{
    if(child.Attributes.contains("class"))
    {
        key = child.GetInnerText;
    }
    else
    {
        values.Add(key, child.GetInnerText);
    }
}

那么只需将文本放入字典中的数组或字符串中即可。

说明:基本上,这段foreach()代码只会在与属性匹配的表中寻找孩子<tr>。然后遍历节点集合,并检查节点是否是日期(即,节点是否与属性匹配<table class="pricing detail">。如果匹配,则将该节点的值(GetInnerText 位)用作字典键(即日期) 如果比较为假,则代码将后续子节点值添加到字典中,映射到日期键,直到日期键更改。

要将值从字典迁移到输出,我很肯定你可以轻松做到这一点

在格式化日期方面,请参阅Jacob's answer,他做得非常好,尽管看起来日期已经按照您希望的方式进行了格式化。

我在这里提供了两个 foreach 循环:第一个执行您希望它执行的操作(只需从网站上获取日期)。实际上,我在完全理解您的要求之前就写了第二个,但是如果您想使用它,我会保留它。

注意 我故意没有使这段代码灵活......它非常严格地附加到 HTML 的结构上。我这样做有几个原因……首先,学习如何有效刮擦的最好方法是被迫编写灵活的刮擦器,每次使用后不必完全退役。我知道我是站在一个肥皂盒上,但是一旦你真正掌握了一些抓取信息的原则,你会发现你的程序会更容易、更流畅,而且,我敢说……更有趣……编写和维护。第二个是,我想鼓励您真正探索 htmlagilitypack 必须提供的功能。它确实是一个令人印象深刻的库,非常值得花时间来玩弄它。

于 2012-06-26T21:08:30.350 回答
0

您需要阅读 XPath。我仍在学习自己,所以可能有比这更好的路径陈述,但你需要做一些类似的事情:

foreach(HtmlNode tr in doc.DocumentNode.SelectNodes("tr[td[1] = '03-Jan-12']"))
{

}    
于 2012-05-23T16:19:38.773 回答