从财务报表中刮取HTML

时间:2012-06-09 07:25:21

标签: c# visual-studio-2010 web-scraping html-agility-pack

首次尝试在Visual Studio和C#中学习HTML。我正在使用html agility pack库。做解析。

从此page我试图从此页面中的各个位置提取信息并将其保存为格式正确的字符串

这是我当前的代码(摘自:shriek

HtmlNode tdNode = document.DocumentNode.DescendantNodes().FirstOrDefault(n => n.Name == "td"
&& n.InnerText.Trim() == "Net Income");
if (tdNode != null)
{
  HtmlNode trNode = tdNode.ParentNode;
  foreach (HtmlNode node in trNode.DescendantNodes().Where(n => n.NodeType ==     HtmlNodeType.Element))
  {
    Console.WriteLine(node.InnerText.Trim());
    //Output:
    //Net Income
    //265.00
    //298.00
    //601.00
    //672.00
    //666.00
  }
 }

它正常工作,但我想获得更多信息,我不确定如何正确搜索HTML。首先,我希望能够从年度数据中选择这些数字,而不仅仅是季度数据(页面顶部的查看选项)。

我还希望获得每列数字的日期,包括季度和年度(每列顶部的“截止日期”)

对于未来的项目,google是否为此提供了API?

4 个答案:

答案 0 :(得分:4)

如果仔细查看原始输入html源代码,您会看到其数据围绕6个主要部分进行组织,这些部分是具有以下“id”属性之一的DIV html元素:“incinterimdiv”“ incannualdiv“”balinterimdiv“”balannualdiv“”casinterimdiv“”casannualdiv“。显然,这些匹配损益表资产负债表现金流 Quaterly 年度数据。

现在,当您使用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());
            }
        }

答案 1 :(得分:0)

您有两种选择。一种是对HTML页面进行反向工程,找出单击年度数据时运行的JavaScript代码,查看数据从何处获取并询问数据。

第二个更强大的解决方案是使用Selenium等平台,它实际上模拟了Web浏览器并为您运行JavaScript。

据我所知,财务报表没有CSV界面。也许雅虎!有一个。

答案 2 :(得分:0)

如果您需要导航到正确的页面,那么您可能希望使用WatiN。 WatiN被设计为网页的自动化测试工具,并驱动选定的Web浏览器来获取页面。它还允许您识别输入字段并在文本框或按钮中输入文本。这很像HtmlAgilityPack,所以你不应该觉得它太难掌握。

答案 3 :(得分:0)

我强烈建议不要采用这种方法。谷歌正在吐出的HTML很可能是非常不稳定的,所以即使你巩固你的解析方法以获得所需的所有数据,在一天,一周或一个月内,HTML格式都可以改变,你需要重写你的解析逻辑。

你应该尝试使用更静态的东西,比如XBRL。

美国证券交易委员会在此公布每个上市公司的XBRL = http://xbrl.sec.gov/

您可以使用此工具包以编程方式处理数据 - http://code.google.com/p/xbrlware/

编辑:阻力最小的路径实际上是使用http://www.xignite.com/xFinancials.asmx,但这项服务需要花钱。