2008-11-18 94 views
19

我已将整个网页的html保存为字符串,现在我想从链接中抓取“href”值,最好能够稍后将它们保存到不同的字符串中。什么是最好的方法来做到这一点?C# - 解析网页的最佳方法?

我试过保存字符串作为一个.xml文档和使用XPathDocument的导航解析它,而是(惊喜惊喜)不浏览一个不真正-AN-XML的文档太清楚了。

是否正则表达式最佳方法来实现我想要完成的?

回答

10

正则表达式是这样做的一种方式,但它可能有问题。

大多数HTML页面不能使用标准html技术进行分析,因为正如你发现的那样,大多数HTML页面不能被验证。

您可能会花时间尝试整合HTML Tidy或类似的工具,但只需构建您所需的正则表达式会快得多。

UPDATE

在此更新我已经收到了15和9个downvotes的时间。我认为也许人们不会阅读这个问题,也不会对这个答案发表评论。 OP所要做的就是获取href值。 就是这样。从这个角度来看,一个简单的正则表达式就好了。如果作者想分析其他项目,那么我就不会推荐正则表达式,正如我在开始时所说的那样,这充其量是有问题的。

+0

很好的回答 - 正则表达式是你的朋友! – 2008-11-18 22:02:19

+23

不好的答案。不要这样做。 – SLaks 2010-02-09 14:26:26

+8

-1嗯,使用Regex解析HTML。什么可能会出错?哦,这是正确的:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – Ash 2010-02-18 04:42:49

0

如果您知道或可以将文档修正为至少格式良好,您可能会使用xml获得更多运气。如果你有好的 html(或者说,xhtml),.Net中的xml系统应该能够处理它。不幸的是,好的html非常罕见。

另一方面,在解析html时,正则表达式为真的很差。幸运的是,你不需要处理完整的html规范。所有你需要担心的是解析href=字符串来获取网址。即使这可能是棘手的,所以我不会马上尝试。相反,我会首先提出几个问题来尝试建立一些基本规则。他们基本上归结为“您对文档有多少了解?”,但这里有:

  • 您知道“href”文本是否总是小写吗?
  • 你知道它是否总是使用双引号,单引号或者什么都不是?
  • 它始终是一个有效的URL,还是你需要考虑'#',javascript语句之类的东西?
  • 是否可以使用内容描述html特征的文档(IE:href=也可以位于文档中而不属于锚标签)?
  • 你还能告诉我们关于该文件的事情吗?
2

也许你想要的东西,像大气磅礴解析器:http://www.majestic12.co.uk/projects/html_parser.php

有可以对付片状HTML,以及一些其他选项。像其他人提到的那样,Html Agility Pack值得一看。

我不认为正则表达式是HTML的理想解决方案,因为HTML不是上下文无关的。他们可能会产生足够的,如果不精确的结果;即使确定性地识别URI也是一个麻烦的问题。

1

我同意Chris Lively的看法,因为HTML通常不是很完善,你可能最好使用正则表达式。

href=[\"\'](http:\/\/|\.\/|\/)?\w+(\.\w+)*(\/\w+(\.\w+)?)*(\/|\?\w*=\w*(&\w*=\w*)*)?[\"\'] 

here上RegExLib应该让你开始

45

我可以推荐HTML Agility Pack。我曾经在一些需要解析HTML的情况下使用它,并且效果很好。一旦将HTML加载到其中,您可以使用XPath表达式来查询文档并获取您的锚标记(以及其中的任何其他内容)。

HtmlDocument yourDoc = // load your HTML; 
int someCount = yourDoc.DocumentNode.SelectNodes("your_xpath").Count; 
2

它总是更好,如果可能不重新发现轮子。一些好的工具存在,要么HTML转换为格式良好的XML,或作为一个XmlReader:

这里有三个很好的工具:

  1. TagSoup,一个开源项目,是一个Java和SAX - 基于工具,由John Cowan开发。这是一个用Java编写的兼容SAX的解析器,它不是解析格式良好的或有效的XML,而是解析HTML,因为它在野外被发现:穷人,讨厌和野蛮,尽管通常很不简单。 TagSoup专为需要使用某种理性应用程序设计外观来处理这些东西的人设计。通过提供SAX接口,它允许将标准XML工具应用于最差的HTML。 TagSoup还包含一个命令行处理器,用于读取HTML文件,并可生成干净的HTML或与XHTML非常接近的格式良好的XML。
    Taggle是TagSoup的商业C++端口。

  2. SgmlReader是由微软的Chris Lovett开发的工具。
    SgmlReader是任何SGML文档(包括内置的HTML支持)的XmlReader API。还提供了一个命令行实用程序,用于输出格式良好的XML结果。
    下载的压缩文件,包括独立的可执行文件和完整的源代码:SgmlReader.zip

  3. 的突出成就是the pure XSLT 2.0 Parser of HTMLDavid Carlisle

阅读它的代码对我们每个人来说都是一个很好的学习练习。

从描述:

d:htmlparse(字符串)
  d:htmlparse(字符串,命名空间,HTML模式)

   的一个参数的形式是等同于)
    d:htmlparse(字符串, 'http://ww.w3.org/1999/xhtml',真()))

   解析使用一些内置启发式)字符串作为HTML和/或XML    控制隐含的元素打开和关闭。

   它不具有HTML DTD的全部知识,但确实有
   空元素和实体定义完整列表的完整列表。 HTML实体和
   十进制和十六进制字符引用都被接受。注意html-entities
   即使在html-mode = false()的情况下也被识别。

   元素名称小写(如果HTML模式是真实的()),并放入该命名空间参数(其可以是“”指定的
   命名空间来表示
   无命名空间,除非输入已显式命名空间声明,在
   这些将被兑现这种情况下。

   属性名小写如果HTML模式=真()

阅读更详细的描述here

希望这有助于。

干杯,

Dimitre Novatchev。