如何使用C#在本地自动获取在线HTML表格

好,保持简短:

我有一些不同的网站,其中包含我想要“本地”查询的信息。

我已经寻找可能性,我自己也有一些想法。

  1. 在Excel中,我发现了一个function,我可以导航到一个网页,并从表中复制数据。 问题是这只发生一次。 表中的数据将每周更新,所以我需要每次打开我的程序时自动更新Excel。

  2. 我可以使用爬虫,但是我必须为每个表格写一个不同的解决scheme,并find一种方法来保存它。

我有一个MySQL数据库知道包含我需要在我的程序中的许多信息,所以如果任何解决scheme需要一个完全可以接受的数据库。

关于我的程序:将用C#编写,首先作为本地程序,然后再写入MVC项目。 这两个项目的build议是非常受欢迎的,如果你需要更多的信息刚刚评论,我会尝试和描述一些。 🙂

编辑! 1

我非常抱歉,我从一开始就不了解我所谈论的桌子,但是当我开始这个问题时,我仍然需要find所有的桌子。 然而,现在我已经拿出了一些表格来向大家展示我需要使用的不同types的表格。 关于这个项目,应该告诉你,我打算制作的这个节目只供私人使用,不能出售。 我不知道在公共网站上抓取的规则,所以这就是为什么我保持私人。

表2 表3

正如你所看到的,很多足球数据以不同的方式显示,所以我需要知道哪种方式最适合我收集数据,因为我相信用这些知识devise医学数据库会更容易。

安德斯,Excel有一个内置的方式来获取数据,你必须这样做一次。 下一次你只需刷新查询。 请看这个链接。

对cricinfo记分卡的htmlparsing

跟进

尝试看看这个网页:soccernet.espn.go.com/stats/_/league/eng.1/…有3个表,但似乎excel检测到他们。 🙁 – 安德斯·格尔纳7分钟前

在这个特定的网站,如果你查看源代码,你会发现这个表没有ID。 所有的三张桌子都有同样的class级“桌面”。 如果您想在工作簿打开事件中循环所有表并提取数据。 因为所有的3个表都有相同的类别,所以你的工作变得更容易了。

或者,你也可以这样做

在Excel中,单击文件 | 打开 ,在对话框中,直接input你在下面提到的URL。 你会注意到,Excel整理数据整齐:)

实际上,您可以编写一个小的macros/代码,用于打开临时工作簿,然后打开该URL,然后将临时工作簿中的表格简单地提取到工作簿中。 我的估计是,一个好的互联网连接,整个过程不应超过15秒完成

如果我只是阅读网页信息,我发现HtmlAgilityPack非常有帮助。 它可以很容易地使用LINQ来查找带有标识信息的特定标签,然后轻松导航子标签。 所以你可以find一个<table>标签,很容易find<tr>和<td>并捕获Text属性来查找单元格的内容。

你可以使用可视化的Web开膛手 ,他们有一个你可以在.NET中使用的API,并且你可以使用他们的devise器来创build模板来提取你想要的数据,这非常容易使用,我的公司用它来从站点即使分页和search。

您可以使用Selenium(用于自动Webtesting)。 这是一个非常有用的工具。 它的API将允许你做像XPath,CSS或DOMsearch特定的表格。

你可以用很多不同的语言通过“远程控制”来驱动Selenium。 请参阅: http : //seleniumhq.org/projects/remote-control/

请参阅C#示例: http : //www.theautomatedtester.co.uk/tutorials/selenium/selenium_csharp_nunit.htm

有关示例,请参阅StackoverFlow: 如何使用Selenium RC检索表格列中的文本?

我的方法是使用一个工具为包含您的表数据的每个URL生成一个RSS提要,然后在您的UI(无论是WPF,WinForms还是asp.net)中显示数据。 这样,当你find/获取一个新的网站来提取数据时,你可以很容易地设置额外的“频道”,你的工作就是将新网站标准化为标准的RSS源格式(可以在其中一个工具中configuration),你甚至可以configuration你的用户界面来根据configuration设置来提取额外的feed,所以在添加一个新的站点时不需要重新编译。

您可以决定将订阅源数据存储在数据库中,或者实时显示,并自动定期执行数据的caching/刷新。 我认为这种方法的基本前提是将每个站点的各种表格格式标准化为一种通用格式(rss或其他格式),然后只担心在应用程序中使用一种标准格式。 这种方法可以在一个以通用格式显示数据的类库中设置,然后该类库可以被C#应用程序和Web应用程序使用。

编辑:这是一个链接到好几个工具的信息,可以用来创build任何网站的RSS提要: http : //profy.com/2007/09/30/7-tools-to-make-an-rss -feed-OF-任何-网站/

以下是使用HtmlAgilityPack的一些示例代码:

using System; using System.Collections.Generic; using System.Web; using System.Xml.XPath; using HtmlAgilityPack; namespace TableRipper { class Program { static List<string> SerializeColumnSet(XPathNodeIterator columnSet) { List<string> serialized = new List<string>(); while (columnSet.MoveNext()) { string value = HttpUtility.HtmlDecode(columnSet.Current.Value.ToString().Trim()); if (value.Contains(",") || value.Contains("\"")) { value = string.Concat('"', value.Replace("\"", "\"\""), '"'); } serialized.Add(value); } return serialized; } static List<List<string>> RipTable(string url, string xpath, bool includeHeaders = true) { HtmlWeb web = new HtmlWeb(); HtmlDocument document = web.Load(url); XPathNavigator navigator = document.CreateNavigator(); XPathNodeIterator tableElementSet = navigator.Select(xpath); List<List<string>> table = new List<List<string>>(); if (tableElementSet.MoveNext()) { XPathNavigator tableElement = tableElementSet.Current; XPathNavigator tableBodyElement = tableElement.SelectSingleNode("tbody") ?? tableElement; XPathNodeIterator tableRowSet = tableBodyElement.Select("tr"); bool hasRows = tableRowSet.MoveNext(); if (hasRows) { if (includeHeaders) { XPathNavigator tableHeadElement = tableElement.SelectSingleNode("thead"); XPathNodeIterator tableHeadColumnSet = null; if (tableHeadElement != null) { tableHeadColumnSet = tableHeadElement.Select("tr/th"); } else if ((tableHeadColumnSet = tableRowSet.Current.Select("th")).Count > 0) { hasRows = tableRowSet.MoveNext(); } if (tableHeadColumnSet != null) { table.Add(SerializeColumnSet(tableHeadColumnSet)); } } if (hasRows) { do { table.Add(SerializeColumnSet(tableRowSet.Current.Select("td"))); } while (tableRowSet.MoveNext()); } } } return table; } static void Main(string[] args) { foreach (List<string> row in RipTable(args[0], args[1])) { Console.WriteLine(string.Join(",", row)); } } } } 

经testing:

http://www.msn.com “// table [@ summary ='市场更新']”

http://www.worldclimate.com/cgi-bin/data.pl?ref=N48W121+2200+450672C&#x201C:// table [1]”

它远非完美,例如它不会处理colspan或rowspan,但它是一个开始。