执行 Web 数据提取

本文关键字:提取 数据 Web 执行 | 更新日期: 2023-09-27 18:35:03

>我已经安装了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"))
{
            
}

执行 Web 数据提取

有趣。该页面的 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 
} 

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

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

试试这个:

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 位(用作字典键(即日期( 如果比较为 false,则代码会将后续子节点值添加到字典中,映射到日期键,直到日期键更改。

要将值从字典迁移到输出,我肯定您可以方便地做到这一点

在格式化日期方面,请参阅雅各布的答案,他的回答非常好,尽管看起来日期已经按照您想要的方式格式化了。

我在这里提供了两个foreach循环:第一个做你想要它做的事情(只是从网站上抓取日期(。在我完全理解你在问什么之前,我实际上写了第二个,但如果你想使用它,我会把它留下来。

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