如果您仔细查看原始输入 html 源代码,您会发现它的数据围绕 6 个主要部分组织,这些部分是具有以下“id”属性之一的 DIV html 元素:“ incinterimdiv
”“ incannualdiv
”“ balinterimdiv
”“ balannualdiv
”“ casinterimdiv
”“ casannualdiv
”。显然,这些与季度或年度数据的损益表、资产负债表和现金流量相匹配。
现在,当您使用 Html Agility Pack 抓取网站时,我建议您使用 XPATH ,这是访问 HTML 代码中任何节点的最简单方法,而不依赖于 XML,因为 Html Agility Pack 支持纯XPATH over HTML。
当然,XPATH 必须学习,但它非常优雅,因为它在一行中完成了很多事情。我知道这对于新的酷炫的面向 C# 的 Xlinq 语法可能看起来过时了 :),但 XPATH 更简洁。它还使您能够将代码和输入 HTML 之间的绑定集中在普通的旧字符串中,并避免在输入源演变时(例如,当 ID 更改时)重新编译代码。这使您的抓取代码更加健壮,并且面向未来。您还可以将 XPATH 绑定放在 XSL(T) 文件中,以便能够将HTML 转换为以 XML 形式呈现的数据。
无论如何,足够的题外话了 :) 这是一个示例代码,允许您从特定行标题获取财务数据,另一个从所有行获取所有数据(来自 6 个主要部分之一):
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://www.google.com/finance?q=NASDAQ:TXN&fstype=ii");
// How get a specific line:
// 1) recursively get all DIV elements with the 'id' attribute set to 'casannualdiv'
// 2) get all TABLE elements under, with the 'id' attribute set to 'fs-table'
// 3) recursively get all TD elements containing the given text (trimmed)
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@id='casannualdiv']/table[@id='fs-table']//td[normalize-space(text()) = 'Deferred Taxes']"))
{
Console.WriteLine("Title:" + node.InnerHtml.Trim());
// get all following sibling TD elements
foreach (HtmlNode sibling in node.SelectNodes("following-sibling::td"))
{
Console.WriteLine(" data:" + sibling.InnerText.Trim()); // InnerText works also for negative values
}
}
// How to get all lines:
// 1) recursively get all DIV elements with the 'id' attribute set to 'casannualdiv'
// 2) get all TABLE elements under, with the 'id' attribute set to 'fs-table'
// 3) recursively get all TD elements containing the class 'lft lm'
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@id='casannualdiv']/table[@id='fs-table']//td[@class='lft lm']"))
{
Console.WriteLine("Title:" + node.InnerHtml.Trim());
foreach (HtmlNode sibling in node.SelectNodes("following-sibling::td"))
{
Console.WriteLine(" data:" + sibling.InnerText.Trim());
}
}