0

我正在尝试使用 hpple 解析以下链接:

http://www.decanter.com/news/wine-news/529748/mimimum-pricing-opponents-slam-cameron-speech

代码:

- (void)parseURL:(NSURL *)url {
    NSData *htmlData = [NSData dataWithContentsOfURL:url];    
    TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
    NSArray *elements  = [xpathParser searchWithXPathQuery:@"<div class=\"body\" id=\"article-529748-body\">"];
    NSLog(@"elements %@",elements);
    TFHppleElement *element = [elements objectAtIndex:0];
    NSString *myTitle = [element content];
    [xpathParser release];
}

但它正在崩溃。崩溃报告:

XPath error : Invalid expression
<div class="body" id="article-529748-body">
^
XPath error : Invalid expression
<div class="body" id="article-529748-body">
^

如何解决这个问题?为什么我的元素数组是空的?我是否以错误的方式解析?我想获取该 div 标签中的可用信息。

4

3 回答 3

0

写这个(2年后!)以防它对其他有类似问题的人有用。

为了解析 div 中的 html,您需要

  1. 使用与 JamMySon 在此页面上引用的语法相似的语法(不需要转义单引号)
  2. 请记住,[元素内容] 只为您提供该节点的内容(如果有),而不是它的子节点。

因此,您可能需要使用递归遍历 div 的节点树。

代码 (ARC):

- (void) decanterHpple{
    NSURL *url = [NSURL URLWithString:@"http://www.decanter.com/news/wine-news/529748/mimimum-pricing-opponents-slam-cameron-speech"];
    NSData *htmlData = [NSData dataWithContentsOfURL:url];

    TFHpple *pageParser = [TFHpple hppleWithHTMLData:htmlData];

    NSString *queryString = @"//div[@id='article-529748-body']";//1.works with unescaped single-quotes(') AND 2.No need for class='' when using id=''
    NSArray *elements = [pageParser searchWithXPathQuery:queryString];

    //old code ~ slightly amended
    if([elements count]){
        TFHppleElement *element = [elements objectAtIndex:0];
        NSString *myTitle = [element content];
        NSLog(@"myTitle:%@",myTitle );
    }
    //new code
    NSString *theText = [self stringFromWalkThruNodes:elements];
    NSLog(@"theText:%@",theText );
}

使用这种递归方法:

- (NSString*) stringFromWalkThruNodes:(NSArray*) nodes {
    static int level = 0;//level is only useful for keeping track of recursion when stepping through with a breakpoint
    level++;//put breakpoint here...
    NSString *text = @"";
    for (TFHppleElement *element in nodes){
        if (element.content) {
            text = [text stringByAppendingString:element.content];
        }
        if (element.children) {
            NSString *innerText = [self stringFromWalkThruNodes:element.children];
            text = [text stringByAppendingString:innerText];
        }
    }
    level--;
    return text;
}

这给出了输出:

2014-10-22 19:44:07.996 Decanted [10148:a0b] myTitle:(null)

2014-10-22 19:44:07.997 Decanted [10148:a0b] theText:

“这就是为什么我们正在通过公共卫生责任协议努力开展一系列促进负责任饮酒的举措。”帕廷顿说,这些举措包括在英国扩大社区酒精合作伙伴关系,以及零售商在全国范围内提高消费者对酒精饮料中酒精单位的认识。帕廷顿说,“与这些措施不同,最低单位定价是一种生硬的工具,既不能解决酒精滥用问题,也不能惩罚绝大多数负责任的消费者。” 正如政府部长们承认的那样,这也可能是非法的。Decanter 也反对该计划,称其“存在根本缺陷”。“真正的问题,”编辑盖伊伍德沃德说,“在于超市将葡萄酒作为亏损的领头羊, 削减利润,

PS。在阅读了前面提到的Wenderlich 教程之后才开始玩Hpple ;我敢肯定,更有经验的人可能会想出一个更优雅的解决方案!

于 2014-10-22T19:00:14.453 回答
0

尝试改变这个:

NSArray *elements  = [xpathParser searchWithXPathQuery:@"<div class=\"body\" id=\"article-529748-body\">"];

至:

NSArray *elements  = [xpathParser searchWithXPathQuery:@"//div [@class='body'] [@id=\'article-529748-body\']"];
于 2014-08-19T23:47:53.250 回答
0

检查您的元素数组不为空

- (void)parseURL:(NSURL *)url {
NSData *htmlData = [NSData dataWithContentsOfURL:url];    
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements  = [xpathParser searchWithXPathQuery:@"<div class=\"body\" id=\"article-529748-body\">"];
NSLog(@"elements %@",elements);
if([elements count]){
    TFHppleElement *element = [elements objectAtIndex:0];
}
NSString *myTitle = [element content];
[xpathParser release];
}
于 2012-02-18T06:22:05.720 回答