最近用AFNetworking获取XML格式的数据,然后我就尝试着获取网页上的数据。
实例:获取简书首页文章列表
NSString *url = [NSString stringWithFormat:@"http://www.jianshu.com"];
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']"];
怎么确定那些属性是动态形成的?暂时我也不知道,我只能一层一层的试。