最近用AFNetworking獲取XML格式的數據,然后我就嘗試著獲取網頁上的數據。
實例:獲取簡書首頁文章列表
NSString *url = [NSString stringWithFormat:@"http://www.lxweimin.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:@"http://*[@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:@"http://book/title[@lang='en']"];
結果:
<title lang="en">Harry Potter</title>
說明:返回第一個符合『//』后面那個匹配的元素。相對路徑可以實現精準定位,不需要從根部一層層到需要的元素。
絕對路徑:
id cusotom = [document firstChildWithXPath:@"/html/body"];
說明:絕對路徑是從網頁的起始標簽一直定位對應標簽的方式。這種方式路徑會很長,不好用。
注意:
有的時候我們按照上面的路徑表達式,會發生不能訪問某些節點的情況。
比如訪問下面紅框里的內容:
id cusotom = [document firstChildWithXPath:@"http://body/div[@id='Wrapper']/div[@class='content']/div[@class='Main']"];
結果:
nil
原因說明:
我明明是按照xpath規則一層層訪問的,為什么結果為nil呢?
原來這些屬性是動態變化,比如是用JS動態形成的頁面,那么這些屬性在每次加載的時候都是不一樣的。
那么這種情況我怎么獲取比如『cell item』的數據呢?
解決辦法:直接跳過這些路徑訪問他下面的路徑:
id cusotom = [document firstChildWithXPath:@"http://body/div[@id='Wrapper']/div[@class='content']/div[@class='box']/div[@class='cell item']"];
怎么確定那些屬性是動態形成的?暫時我也不知道,我只能一層一層的試。