zoukankan      html  css  js  c++  java
  • 怎样抓取网页内容

    如果给你一个网页链接, 来抓取指定的内容, 比如豆瓣电影排行榜, 那要怎样才能做到了?

    其实网页内容的结构很是类似于XML, 那么我们就可以用解析XML的方式来解析HTML, 不过两者之间的差距还是很大的, 好了, 废话不多说, 我们开始解析HTML。

    那么解析XML的库比较多, 这里选用libxml来解析, 因为libxml是c语言接口, 找了一个用objective-c包装接口的库-hpple, 它的地址是https://github.com/topfunky/hpple, 那么网页用的是豆瓣电影排行榜, 地址是http://movie.douban.com/chart

    接下来新建工程, 工程采用的ARC, 引进libxml2和hpple库, 新建实体类movie, 完整的项目结构如下: 

    NewImage

    movie的实现如下, 这个是实体类, 根据抓取网页的内容来定这个实体

    movie.h 

    @interface Movie : NSObject
    @property(nonatomic, strong) NSString   *name;
    @property(nonatomic, strong) NSString   *imageUrl;
    @property(nonatomic, strong) NSString   *descrition;
    @property(nonatomic, strong) NSString   *movieUrl;
    @property(nonatomic) NSInteger  ratingNumber;
    @property(nonatomic, strong) NSString   *comment;
    @end

    那么最重要的部分来了, 不管网页的内容是什么, 我们得先需要获取网页的内容, 下面就是通过NSURLConnection来获取整个网页的内容。

    - (void)loadHTMLContent
    {
        NSString *movieUrl = MOVIE_URL;
        NSString *urlString = [movieUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url = [NSURL URLWithString:urlString];
        
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        
        __weak ViewController *weak_self = self;
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
            if (nil == error) {
    //            NSString *retString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    //            NSLog(@"%@", retString);
                [weak_self parserHTML:data];
            }
            
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        }];
    }

    这里只是简单的获取网页内容, 一些HTTP和错误处理不在此文讨论中, 所以这里的代码比较简单, 在上面的代码中有个parserHTML:的方法, 就是来解析获取的网页内容, 在解析网页内容之前, 先来扯下xpath。

    假设一个简单网页内容如下:

    <html>
      <head>
        <title>Some webpage</title>
      </head>
      <body>
        <p class=”normal”>This is the first paragraph</p>
        <p class=”special”>This is the second paragraph. <b>This is in bold.</b></p>
      </body> 
    </html>

    比如想得到title的内容,那么xpath表达就是/html/head/title。如果想得到class="special"节点内容,xpath就是/html/body/p[@class='special']。

    所以只要找对了xpath, 就会得到相应的节点内容, 那么来看下用hpple解析HTML

    - (void)parserHTML:(NSData *)data
    {
        if (nil != data) {
            TFHpple *movieParser = [TFHpple hppleWithHTMLData:data];
            NSString *movieXpathQueryString = @"/html/body/div[@id='wrapper']/div[@id='content']/div[@class='grid-16-8 clearfix']/div[@class='article']/div[@class='indent']/table/tr/td/a[@class='nbg']";
            NSArray *movieNodes = [movieParser searchWithXPathQuery:movieXpathQueryString];
            
            for (TFHppleElement *element in movieNodes) {
                Movie *m = [[Movie alloc] init];
                m.name = [element objectForKey:@"title"];
                m.movieUrl = [element objectForKey:@"href"];
                
                for (TFHppleElement *child in element.children) {
                    if ([child.tagName isEqualToString:@"img"]) {
                        @try {
                            m.imageUrl = [child objectForKey:@"src"];
                        }
                        @catch (NSException *exception) {
                            
                        }
                    }
                }
                
                [self.movies addObject:m];
            }
            
            [self.movieTableView reloadData];
        }
    }
    

    代码中首页找到相应节点的路径, 然后searchWithXPathQuery, 得到一个数组, 遍历组织数据就能够在table view中展示了。具体效果如下:

    NewImage

    好了, 网页内容被抓取出来了, 具体的实际项目中都要比这个复杂, so, 这只是个引导的示例。

    参考:http://www.raywenderlich.com/14172/how-to-parse-html-on-ios#

    注: 本文由啸寒原著,请支持原著!转载请附上原文链接: http://www.cnblogs.com/xiaohan-wu/p/3203932.html

  • 相关阅读:
    Vue移动端调用高德获取当前定位城市
    var,let,const三者的区别
    JVM学习与总结一
    五层网络模型整理
    功能强大的CFR反编译工具
    jad 反编译 jar文件、批量、单个class文件,秒懂!
    [ERROR] 2020-08-03 10:18:11 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:350) Context initialization failed
    TortoiseSVN的bin目录下没有 svn.exe 问题;Error running 'tomcat8.0.47': Unable to open debugger port (127.0.0.1:57422): java.net.SocketException "socket closed";端口被占用问题
    显示数据时,将同列不同行的数据合并到其中一行的sql
    java.lang.IllegalArgumentException: ServletContext must not be null
  • 原文地址:https://www.cnblogs.com/xiaohan-wu/p/3203932.html
Copyright © 2011-2022 走看看