0

第一次尝试学习在 Visual Studio 和 C# 中使用 HTML。我正在使用html 敏捷包库。进行解析。

从这个页面 我试图从这个页面的各个地方提取信息并将它们保存为格式正确的字符串

这是我当前的代码(取自: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。首先,我还希望能够从年度数据中选择这些数字,而不仅仅是从季度数据(页面顶部的查看选项)。

我还想获取每列数字的日期,包括季度和年度(每列顶部的“截至...”)

同样对于未来的项目,谷歌是否为此提供了 API?

4

4 回答 4

4

如果您仔细查看原始输入 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());
            }
        }
于 2012-06-11T12:34:01.223 回答
0

我强烈建议不要使用这种方法。谷歌吐出的 HTML 可能非常不稳定,因此即使您巩固了解析方法以获取所需的所有数据,在一天、一周或一个月内,HTML 格式也可能全部改变,您需要重写你的解析逻辑。

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

SEC 在此处为每家上市公司发布此 XBRL = http://xbrl.sec.gov/

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

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

于 2012-06-14T15:43:32.433 回答
0

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

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

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

于 2012-06-09T07:34:59.160 回答
0

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

于 2012-06-10T04:44:36.917 回答