在iPhone上解析HTML

68

请问有没有人能够推荐一个用于解析HTML的C或Objective-C库?它需要能够处理一些不太符合标准的HTML代码。

是否存在这样的库,或者我最好尝试使用正则表达式来解析HTML?


我喜欢Ben Reeves在这个帖子中提到的轻量级包装器。该包装器已经转移到了Github上: Objective-C-HMTL-Parser - yarchiko
1
这个问题为什么被认为是“不具建设性”的? - 735Tesla
9个回答

89

我发现使用hpple很有用,可以解析混乱的HTML。 Hpple项目是一个基于XPathQuery库的Objective-C包装器,用于解析HTML。使用它,您可以发送XPath查询并收到结果。

要求

-将libxml2包含添加到您的项目中

  1. 菜单 项目->编辑项目设置
  2. 搜索设置“头搜索路径”
  3. 添加新搜索路径“${SDKROOT} /usr/include/libxml2”
  4. 启用递归选项

-将libxml2库添加到您的项目中

  1. 菜单 项目->编辑项目设置
  2. 搜索设置“其他链接器标志”
  3. 添加新搜索标志“-lxml2”

-从hpple获取以下源代码文件并将它们添加到您的项目中:

  1. TFpple.h
  2. TFpple.m
  3. TFppleElement.h
  4. TFppleElement.m
  5. XPathQuery.h
  6. XPathQuery.m

-在w3school XPath Tutorial上学习XPath语言,以便感到舒适。

代码示例

#import "TFHpple.h"

NSData *data = [[NSData alloc] initWithContentsOfFile:@"example.html"];

// Create parser
xpathParser = [[TFHpple alloc] initWithHTMLData:data];

//Get all the cells of the 2nd row of the 3rd table 
NSArray *elements  = [xpathParser searchWithXPathQuery:@"//table[3]/tr[2]/td"];

// Access the first cell
TFHppleElement *element = [elements objectAtIndex:0];

// Get the text within the cell tag
NSString *content = [element content];  

[xpathParser release];
[data release];

已知问题

因为 hpple 是针对 XPathQuery 的另一个封装,所以这个选项可能不是最有效的。 如果在您的项目中需要考虑性能问题,建议基于 hpple 和 xpathquery 库代码编写自己的轻量级解决方案。


2
我刚刚使用了这个,到目前为止效果非常好。 - Karsten Silz
它在处理字符串数据方面表现得非常好。您能告诉我如何从HTML中获取并显示图像吗? - Akshay
Askhay,图片不会存储在HTML中。您必须获取URL并自行下载。一旦您获得了URL,可以使用[NSData dataWithContentsOfURL]来获取文件。 - Maciej Swic
1
自2011年7月8日起,TFHpplesearch:方法已更名为searchWithXPathQuery:。请参见https://github.com/topfunky/hpple/commit/fd5ec102a55ce08f68c6f2060acfcdfb2d3a13a3。 - Protocole
这对我非常有效,谢谢。我有一个奇怪的怪癖,文件名似乎在前面有一个空格字符,但这可能是由于编码错误而发生,并且与hpple无关。 - Robert
你可以使用Hpple添加/删除元素吗? - Valerio Santinelli

49

看起来SDK中有libxml2.2,并且libxml/HTMLparser.h声明了以下内容:

该模块实现了一个与XML解析器API兼容的HTML 4.0非验证解析器。它应该能够解析“现实世界”中的HTML文件,即使是从规范角度严重破损的。

这听起来就是我需要的,所以我可能会使用它。


19

提醒一下,如果有人通过谷歌搜索一个好的XPath解析器并使用了TFHpple,请注意TFHpple使用XPathQuery。这个工具很不错,但存在内存泄漏问题。

在函数“PerformXPathQuery”中,如果发现节点为空,则会在清理前跳出函数。

所以,在你看到以下代码时,请添加两行清理代码:

  xmlNodeSetPtr nodes = xpathObj->nodesetval;
  if (!nodes)
    {
      NSLog(@"Nodes was nil.");
        /* Cleanup */
        xmlXPathFreeObject(xpathObj);
        xmlXPathFreeContext(xpathCtx);
      return nil;
    }

如果你正在做大量的解析工作,这将导致严重的内存泄漏问题。那么...我该如何挽回我的夜晚呢 :-)


我只能找到 Hpple,但它自 2009 年以来就没有更新了。我在哪里可以找到“TFHpple”? - Maciej Swic
1
https://github.com/topfunky/hpple - 是的,我认为它相当老了。不过一旦你清理掉泄漏问题,它还是可以正常工作的。 - DavidAWalsh
2
看起来这个修复已经在最新的提交中更新了。 - jfisk

12

很棒,Ben。我可能会在我的即将推出的iPad应用中使用它。 - Brock Woolf
2
网站崩溃了,你应该在 GitHub 上发布这个问题! - bentford
Ben,我尝试添加你的库 - 它也适用于iPhone开发吗?因为我得到了http://stackoverflow.com/questions/14086354/adding-htmlparser-library-undefined-symbols-for-architecture-armv7s - Dejell

5
这可能取决于HTML的混乱程度和你想要提取的内容。但通常Tidy做得很好。它是用C编写的,我猜你应该能够为iPhone构建并静态链接它。你可以轻松安装命令行版本并先测试结果。

5
你可能想要查看ElementParser。它提供了对HTML和XML的“刚好足够”的解析。漂亮的接口使得在XML / HTML文档中游走非常简单。 http://touchtank.wordpress.com/

新链接:https://github.com/Objective3/ElementParser - smdvlpr
4
ElementParser 的漏洞相当多,而且自 2009 年以来没有更新。我强烈反对使用它。 - steipete

4
如何使用Webkit组件以及可能的第三方包,例如jquery来完成这些任务?在一个不可见的组件中获取HTML数据并利用JavaScript框架的成熟选择器是否是可能的呢?

3
谷歌的GData Objective-C API重新实现了NSXMLElement和其他相关类,这些类被苹果从iPhone SDK中删除。您可以在此处找到它:http://code.google.com/p/gdata-objectivec-client/。我已经用它来处理通过Jabber发送消息。当然,如果您的HTML格式不正确(缺少闭合标签),这可能不会有太大帮助。

3
我们使用Convertigo在服务器端解析HTML,并返回干净整洁的JSON Web服务给我们的移动应用程序。

这并没有回答问题-他在寻找一个客户端库。 - Freney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接