您的当前位置:首页正文

使用AFNetworking获取网页数据

来源:花图问答

最近用AFNetworking获取XML格式的数据,然后我就尝试着获取网页上的数据。

实例:获取简书首页文章列表

    NSString *url = [NSString 
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"text/html", nil]];
    [manager GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSError *error;
        ONOXMLDocument *document = [ONOXMLDocument HTMLDocumentWithData:responseObject error:&error];
        [document enumerateElementsWithXPath:@"//*[@class='article-list thumbnails']/li[@class='have-img']/div/h4" usingBlock:^(ONOXMLElement *element, NSUInteger idx, BOOL *stop) {
            NSLog(@"Element:%@",[element stringValue]);
        }];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@",[error localizedDescription]);
    }];

结果:


XPath介绍

XPath是一门在XML中查找信息的语言。XPath用于在XML文档中通过元素和属性进行导航。
网页的HTML元素可以通过『查看页面源码』查看,如:


XPath通过『路径表达式』来选择节点。基本用法:

相对路径

[document firstChildWithXPath:@"//book/title[@lang='en']"];

结果:
<title lang="en">Harry Potter</title>

说明:返回第一个符合『//』后面那个匹配的元素。相对路径可以实现精准定位,不需要从根部一层层到需要的元素。

绝对路径:

id cusotom = [document firstChildWithXPath:@"/html/body"];

说明:绝对路径是从网页的起始标签一直定位对应标签的方式。这种方式路径会很长,不好用。

注意:
有的时候我们按照上面的路径表达式,会发生不能访问某些节点的情况。
比如访问下面红框里的内容:

id cusotom = [document firstChildWithXPath:@"//body/div[@id='Wrapper']/div[@class='content']/div[@class='Main']"];

结果:
nil

原因说明:
我明明是按照xpath规则一层层访问的,为什么结果为nil呢?
原来这些属性是动态变化,比如是用JS动态形成的页面,那么这些属性在每次加载的时候都是不一样的。

那么这种情况我怎么获取比如『cell item』的数据呢?
解决办法:直接跳过这些路径访问他下面的路径:

id cusotom = [document firstChildWithXPath:@"//body/div[@id='Wrapper']/div[@class='content']/div[@class='box']/div[@class='cell item']"];

怎么确定那些属性是动态形成的?暂时我也不知道,我只能一层一层的试。