您的位置:首页 > 移动开发 > IOS开发

IOS HTML 解析

2014-01-26 09:16 232 查看
 


IOS HTML 解析

分类: ios2013-05-21
10:23 769人阅读 评论(0) 收藏 举报

[plain] view
plaincopy

#define PARSER_URL  @"http://www.baidu.com/s?wd=iphone&rsv_bp=0&ch=&tn=baidu&bar=&rsv_spt=3&ie=utf-8&rsv_sug3=5&rsv_sug=0&rsv_sug1=5&rsv_sug4=115&inputT=1438"  

  

-(void) parser{  

    NSString *urlString =  [NSString stringWithContentsOfURL:[NSURL URLWithString:PARSER_URL] encoding:NSUTF8StringEncoding error:nil];  

  

    NSData *data = [urlString dataUsingEncoding:NSUTF8StringEncoding];  

    // Create parser  

    TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:data];  

    //Get all the cells of the 2nd row of the 3rd table  

    NSString *xpathQuery = @"//*[@id='container']/p/span";  

    NSArray *elements  = [xpathParser searchWithXPathQuery:xpathQuery];  

    NSLog(@"elements.count -->%i",[elements count]);  

    // Access the first cell  

    // Get the text within the cell tag  

  

    for (TFHppleElement * element in elements) {  

        NSLog(@"element------------->%@", element);  

        NSLog(@"element.tagName----->%@", [element tagName]);  

        NSLog(@"element.attribute--->%@", [element attributes]);  

        NSLog(@"element.child------->%@", [element children]);  

        for (TFHppleElement *childElement in [element children]) {  

            NSLog(@"childElement.text-->%@", childElement.content);  

            [self.label setText:childElement.content];  

        }  

    }  

}  

一.使用 TFHpple 解析库
来源地址:TFHpple lIB
感谢stack overflow  Vineet
Bhatia 网友的热心回答.
来源: ios html parser

二 . 使用HTMLParser 类库解析
add "/usr/include/libxml2" 

来源: HTMLParser


Objective-C解析HTML!

2013-03-27 12:54 佚名 oschina 字号:T | T



xml,json都有大量的库来解析,我们如何解析html呢? TFHpple是一个小型的封装,可以用来解析html,它是对libxml的封装,语法是xpath。 今天我看到一个直接用libxml来解析html。

AD:2013云计算架构师峰会课程资料下载

使用Objective-C解析HTML或者XML,系统自带有两种方式一个是通过libxml,一个是通过NSXMLParser。不过这两种方式都需要自己写很多编码来处理抓取下来的内容,而且不是很直观。

有一个比较好的类库hpple,它是一个轻量级的包装框架,可以很好的解决这个问题 。它是用XPath来定位和解析HTML或者XML。
安装步骤:

-加入 libxml2 到你的项目中

   Menu Project->Edit Project Settings

   搜索 “Header Search Paths”

   添加新的 search path “${SDKROOT}/usr/include/libxml2″

   Enable recursive option

-加入 libxml2 library 到你的项目

   Menu Project->Edit Project Settings

   搜索 “Other Linker Flags”

   添加新的 search flag “-lxml2″

-将下面hpple的源代码 加入到你的项目中:

HTFpple.h

HTFpple.m

HTFppleElement.h

HTFppleElement.m

XPathQuery.h

XPathQuery.m

-XPath学习地址http://www.w3schools.com/XPath/default.asp 
示例代码:
#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 search:@"//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]; 

下载 地址:https://github.com/topfunky/hpple 

另外,还有一个类似的解决方案可以参考

ElementParser http://github.com/Objective3/ElementParser

 

源码下载:http://down.51cto.com/data/616107
 

【编辑推荐】

iOS网络交互数据格式解析之json

iOS中关于json解析的几种方式

xml,json都有大量的库来解析,我们如何解析html呢?

TFHpple是一个小型的封装,可以用来解析html,它是对libxml的封装,语法是xpath。

今天我看到一个直接用libxml来解析html,参看:http://www.cocoanetics.com/2011/09/taming-html-parsing-with-libxml-1/#comment-3090 那张图画得一目了然,很值得收藏。这个文章中的源码不能遍历所有的html,我做了一点修改可以将html遍历打印出来

源码打印

      

// NSData data contains the document data  

// encoding is the NSStringEncoding of the data  

// baseURL the documents base URL, i.e. location   

   

CFStringEncoding cfenc = CFStringConvertNSStringEncodingToEncoding(encoding);  

CFStringRef cfencstr = CFStringConvertEncodingToIANACharSetName(cfenc);  

const char *enc = CFStringGetCStringPtr(cfencstr, 0);  

   

htmlDocPtr _htmlDocument = htmlReadDoc([data bytes],  

      [[baseURL absoluteString] UTF8String],  

      enc,  

      XML_PARSE_NOERROR | XML_PARSE_NOWARNING);  

if (_htmlDocument)  

{  

   xmlFreeDoc(_htmlDocument);  

}  

  

xmlNodePtr currentNode = (xmlNodePtr)_htmlDocument;  

  

while (currentNode)   

    {  

        // output node if it is an element  

          

        if (currentNode->type == XML_ELEMENT_NODE)  

        {  

            NSMutableArray *attrArray = [NSMutableArray array];  

              

            for (xmlAttrPtr attrNode = currentNode->properties; attrNode; attrNode = attrNode->next)  

            {  

                xmlNodePtr contents = attrNode->children;  

                  

                [attrArray addObject:[NSString stringWithFormat:@"%s='%s'", attrNode->name, contents->content]];  

            }  

              

            NSString *attrString = [attrArray componentsJoinedByString:@" "];   

              

            if ([attrString length])  

            {  

                attrString = [@" " stringByAppendingString:attrString];  

            }  

              

            NSLog(@"<%s%@>", currentNode->name, attrString);  

        }  

        else if (currentNode->type == XML_TEXT_NODE)  

        {  

            //NSLog(@"%s", currentNode->content);  

            NSLog(@"%@", [NSString stringWithCString:(const char *)currentNode->content encoding:NSUTF8StringEncoding]);  

        }  

        else if (currentNode->type == XML_COMMENT_NODE)  

        {  

            NSLog(@"/* %s */", currentNode->name);  

        }  

      

          

        if (currentNode && currentNode->children)  

        {  

            currentNode = currentNode->children;  

        }  

        else if (currentNode && currentNode->next)  

        {  

            currentNode = currentNode->next;  

        }  

        else  

        {  

            currentNode = currentNode->parent;  

              

            // close node  

            if (currentNode && currentNode->type == XML_ELEMENT_NODE)  

            {  

                NSLog(@"</%s>", currentNode->name);  

            }  

              

            if (currentNode->next)  

            {  

                currentNode = currentNode->next;  

            }  

            else   

            {  

                while(currentNode)  

                {  

                    currentNode = currentNode->parent;  

                    if (currentNode && currentNode->type == XML_ELEMENT_NODE)  

                    {  

                        NSLog(@"</%s>", currentNode->name);  

                        if (strcmp((const char *)currentNode->name, "table") == 0)  

                        {  

                            NSLog(@"over");  

                        }  

                    }  

                      

                    if (currentNode == nodes->nodeTab[0])  

                    {  

                        break;  

                    }  

                      

                    if (currentNode && currentNode->next)  

                    {  

                        currentNode = currentNode->next;  

                        break;  

                    }  

                }  

            }  

        }  

          

        if (currentNode == nodes->nodeTab[0])  

        {  

            break;  

        }  

    }  

不过我还是喜欢用TFHpple,因为它很简单,也好用,但是它的功能不是很完完善。比如,不能获取children node,我就写了两个方法,一个是获取children node,一个是获取所有的contents.  还有node的属性content的key与node's content的key一样,都是@"nodeContent", 正确情况下属性的应是@"attributeContent",

所以我写了这个方法,同时修改node属性的content key.

源码打印

NSDictionary *DictionaryForNode2(xmlNodePtr currentNode, NSMutableDictionary *parentResult)  

{  

    NSMutableDictionary *resultForNode = [NSMutableDictionary dictionary];  

      

    if (currentNode->name)  

    {  

        NSString *currentNodeContent =  

        [NSString stringWithCString:(const char *)currentNode->name encoding:NSUTF8StringEncoding];  

        [resultForNode setObject:currentNodeContent forKey:@"nodeName"];  

    }  

      

    if (currentNode->content)  

    {  

        NSString *currentNodeContent = [NSString stringWithCString:(const char *)currentNode->content encoding:NSUTF8StringEncoding];  

          

        if (currentNode->type == XML_TEXT_NODE)  

        {  

            if (currentNode->parent->type == XML_ELEMENT_NODE)  

            {  

                [parentResult setObject:currentNodeContent forKey:@"nodeContent"];  

                return nil;  

            }  

              

            if (currentNode->parent->type == XML_ATTRIBUTE_NODE)  

            {  

                [parentResult  

                 setObject:  

                 [currentNodeContent  

                  stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]  

                 forKey:@"attributeContent"];  

                return nil;  

  

            }  

        }  

    }  

      

  

      

    xmlAttr *attribute = currentNode->properties;  

    if (attribute)  

    {  

        NSMutableArray *attributeArray = [NSMutableArray array];  

        while (attribute)  

        {  

            NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary];  

            NSString *attributeName =  

            [NSString stringWithCString:(const char *)attribute->name encoding:NSUTF8StringEncoding];  

            if (attributeName)  

            {  

                [attributeDictionary setObject:attributeName forKey:@"attributeName"];  

            }  

              

            if (attribute->children)  

            {  

                NSDictionary *childDictionary = DictionaryForNode2(attribute->children, attributeDictionary);  

                if (childDictionary)  

                {  

                    [attributeDictionary setObject:childDictionary forKey:@"attributeContent"];  

                }  

            }  

              

            if ([attributeDictionary count] > 0)  

            {  

                [attributeArray addObject:attributeDictionary];  

            }  

            attribute = attribute->next;  

        }  

          

        if ([attributeArray count] > 0)  

        {  

            [resultForNode setObject:attributeArray forKey:@"nodeAttributeArray"];  

        }  

    }  

      

    xmlNodePtr childNode = currentNode->children;  

    if (childNode)  

    {  

        NSMutableArray *childContentArray = [NSMutableArray array];  

        while (childNode)  

        {  

            NSDictionary *childDictionary = DictionaryForNode2(childNode, resultForNode);  

            if (childDictionary)  

            {  

                [childContentArray addObject:childDictionary];  

            }  

            childNode = childNode->next;  

        }  

        if ([childContentArray count] > 0)  

        {  

            [resultForNode setObject:childContentArray forKey:@"nodeChildArray"];  

        }  

    }  

      

    return resultForNode;  

}  

TFHppleElement.m里加了两个key 常量

源码打印

NSString * const TFHppleNodeAttributeContentKey  = @"attributeContent";  

NSString * const TFHppleNodeChildArrayKey        = @"nodeChildArray";  

并修改获取属性方法为:

源码打印

- (NSDictionary *) attributes  

{  

  NSMutableDictionary * translatedAttributes = [NSMutableDictionary dictionary];  

  for (NSDictionary * attributeDict in [node objectForKey:TFHppleNodeAttributeArrayKey]) {  

    [translatedAttributes setObject:[attributeDict objectForKey:TFHppleNodeAttributeContentKey]  

                             forKey:[attributeDict objectForKey:TFHppleNodeAttributeNameKey]];  

  }  

  return translatedAttributes;  

}  

并添加获取children node 方法:

源码打印

- (BOOL) hasChildren  

{  

    NSArray *childs = [node objectForKey: TFHppleNodeChildArrayKey];  

      

    if (childs)   

    {  

        return  YES;  

    }  

      

    return  NO;  

}  

  

- (NSArray *) children  

{  

    if ([self hasChildren])  

        return [node objectForKey: TFHppleNodeChildArrayKey];  

    return nil;  

}  

最后我还加了一个获取所有content的主法:

源码打印

- (NSString *)contentsAt:(NSString *)xPathOrCss;  

请看 源码

参看:http://giles-wang.blogspot.com/2011/08/iphoneansi.html

原文链接:http://blog.csdn.net/favormm/article/details/6794487
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息