如何解析HTML以搜索特定于内容的针

Pav*_*van 3 html xml parsing objective-c ios

鉴于NSString以下最初是CData从解析XML文档中检索到的对象转换而来的NSXMLParser,如何获得该书的以下属性:标题,书籍图像封面,作者,价格和评级?

这是我获得以下属性的基本解决方案

  1. 书名 - 我可以通过查看riRssTitlespan类来获得这个,但是我必须弄清楚如何读取ahref url标签之间的标题以获得标题

  2. 书籍图像 - 我必须通过抓取第一个URL http://ecx.images-amazon.com/images/I/41Lg22K3ViL._SL160_PIsitb-sticker-arrow-dp,TopRight,12,-18_SH30_OU02_.jpg,然后将所有内容留下来http://ecx.images-amazon.com/images/I/41Lg22K3ViL省略其余部分,然后附加.jpg标签以便在稍后的位置获得完整的图像检索URL.

  3. 书籍作者 - 我必须按照与步骤1相同的步骤,而是搜索riRssContributorspan标签.

  4. 预订价格 - 这里没有价格标签在所有商品中都很常见,但我确实看到的一个共同点就是价格总是在font tag它所在的位置BOLD tag.

  5. 评级 - 可以通过查找包含该单词的URL stars然后获取其后的数字来检索,4意味着4颗星,任何-5附加的数字意味着额外的.5星.所以3-5意味着3.5星.

什么是最好的方式,没有它变得凌乱?此外,我不喜欢我的代码如何破解,如果亚马逊决定改变它显示它的URL的方式,我的应用程序依赖亚马逊维护其URL命名约定.

但就目前而言,这是前进的最佳方式吗?有没有一个快速解析器可以实现我想做的事情?

这是亚马逊RSS提要的一个例子:http://www.amazon.co.uk/gp/rss/bestsellers/books/72/ref=zg_bs_72_rsslink


以下是NSString我为每个项目检索的以下CData 数据.

<div style="float:left;">
    <a class="url" href="http://www.amazon.co.uk/Gone-Girl-Gillian-Flynn/dp/0753827662/ref=pd_zg_rss_ts_b_72_9">
        <img src="http://ecx.images-amazon.com/images/I/41Lg22K3ViL._SL160_PIsitb-sticker-arrow-dp,TopRight,12,-18_SH30_OU02_.jpg" alt="Gone Girl" border="0" hspace="0" vspace="0" />
    </a>
</div>
<span class="riRssTitle">
    <a href="http://www.amazon.co.uk/Gone-Girl-Gillian-Flynn/dp/0753827662/ref=pd_zg_rss_ts_b_72_9">Gone Girl</a>
</span>
<br />
<span class="riRssContributor">
    <a href="http://www.amazon.co.uk/Gillian-Flynn/e/B001JP3W46/ref=ntt_athr_dp_pel_1">Gillian Flynn</a>
    <span class="byLinePipe">(Author)</span>
</span>
<br />
<img src="http://g-ecx.images-amazon.com/images/G/02/x-locale/common/icons/uparrow_green_trans._V192561975_.gif" width="13" align="abstop" alt="Ranking has gone up in the past 24 hours" title="Ranking has gone up in the past 24 hours" height="11" border="0" />
<font color="green">
    <strong></strong>
</font> 674 days in the top 100 
<br />
<img src="http://g-ecx.images-amazon.com/images/G/02/detail/stars-4-0._V192253865_.gif" width="64" height="12" border="0" style="margin: 0; padding: 0;"/>(5704)
<br />
<br />
<a href="http://www.amazon.co.uk/Gone-Girl-Gillian-Flynn/dp/0753827662/ref=pd_zg_rss_ts_b_72_9">Buy new: </a>
<strike>£9.07</strike>
<font color="#990000">
    <b>£3.85</b>
</font>
<br />
<a href="http://www.amazon.co.uk/gp/offer-listing/0753827662/ref=pd_zg_rss_ts_b_72_9?ie=UTF8&condition=all">60 used & new</a> from 
<span class="price">£2.21</span>
<br />
<br />(Visit the 
<a href="http://www.amazon.co.uk/Best-Sellers-Books-Crime-Thrillers-Mystery/zgbs/books/72/ref=pd_zg_rss_ts_b_72_9">Bestsellers in Crime, Thrillers & Mystery</a> list for authoritative information on this product's current rank.)
Run Code Online (Sandbox Code Playgroud)

Kry*_*ski 8

TFHpple绝对是解析HTML的库.(> github上的1000颗星) https://github.com/topfunky/hpple

这是该RSS源的obj-c解决方案:

NSString *stringURL = @"http://www.amazon.co.uk/gp/rss/bestsellers/books/72/ref=zg_bs_72_rsslink";
NSURL  *url = [NSURL URLWithString:stringURL];
NSData *htmlData = [NSData dataWithContentsOfURL:url];

TFHpple * doc = [[TFHpple alloc] initWithHTMLData:htmlData];

NSArray *titleElements = [doc searchWithXPathQuery:@"//span[@class='riRssTitle']/a"];
for (TFHppleElement *element in titleElements)
{
    NSString *title = element.firstChild.content;
    NSLog(@"title: %@", title);
}

NSArray *imageElements = [doc searchWithXPathQuery:@"//a[@class='url']/img"];
for (TFHppleElement *element in imageElements)
{
    NSString *image = element.attributes[@"src"];
    NSMutableArray *parts = [[image componentsSeparatedByString:@"/"] mutableCopy];
    NSArray *pathParts = [parts.lastObject componentsSeparatedByString:@"."];
    [parts removeLastObject];
    [parts addObject:[NSString stringWithFormat:@"%@.%@",pathParts.firstObject, pathParts.lastObject]];
    image = [parts componentsJoinedByString:@"/"];
    NSLog(@"image: %@", image);
}

NSArray *authorElements = [doc searchWithXPathQuery:@"//span[@class='riRssContributor']/a"];
for (TFHppleElement *element in authorElements)
{
    NSString *author = element.firstChild.content;
    NSLog(@"author: %@", author);
}

NSArray *priceElements = [doc searchWithXPathQuery:@"//font/b"];
for (TFHppleElement *element in priceElements)
{
    NSString *price = element.firstChild.content;
    NSLog(@"price: %@", price);
}

NSArray *ratingElements = [doc searchWithXPathQuery:@"//img"];
for (TFHppleElement *element in ratingElements)
{
    if (![element.attributes[@"src"] containsString:@"stars"])
        continue;

    NSArray *parts = [element.attributes[@"src"] componentsSeparatedByString:@"-"];
    if (parts.count < 5) continue;

    NSString *rating = [NSString stringWithFormat:@"%@.%@", parts[3], [parts[4] substringToIndex:1]];
    NSLog(@"rating: %@", rating);
}
Run Code Online (Sandbox Code Playgroud)

就像你说的那样,你受亚马逊命名惯例的支配.