1

これは、RSSフィードによって生成された形式の悪いhtmlから「imgsrc」画像リンクを解析するための私のメソッド本体です... NSXMLはXMLのみを解析することを知っていますが、混乱を乗り越えてこれらの小さなものを見つけることができることを願っています乱雑なhtmlからの画像リンク。

src属性を持つnsDataのIMGという各要素名で見つかったsrc属性で見つかった最初の画像リンクのみを取得し、それを別のクラスのNSString*imgに保存しようとしています。imgタグはすべて同じではありません。たとえば、nsDataのインスタンスには、次のいずれかのような1つの画像インスタンスのみが含まれます。

<img class = "ms-rteStyle-photoCredit" src="www.imagelinkthatineed.com"必要のないもの

<img alt = "" src="www.imagelinkineedfortableimagecellpreview"必要のないもの

<img class = "ms-rteStyle-photoCredit" src="www.IneedThisLink.com"必要のないもの

NSLog出力を生成するように見える唯一のクラスは最初のクラスです。

パーサーメソッドを実際に実行するにはどうすればよいですか?

方法があるとすると、あなたがお勧めする別の、より簡単な方法はありますか?

#import "HtmlParser.h"
#import "ArticleItem.h"

@implementation HtmlParser
@synthesize elementArray;

- (HtmlParser *) InitHtmlByString:(NSString *)string {
//    NSString *description = [NSString string];
NSData *nsData = [[NSData alloc] initWithContentsOfFile:(NSString *)string];
elementArray = [[NSMutableArray alloc] init];
parser = [[NSXMLParser alloc] initWithData:nsData];
parser.delegate = self;
[parser parse];

I NSLog(@ "%@"、nsData);の場合 このメソッド本体では、出力は生のHTMLを吐き出します。

currentHTMLElement = [ArticleItem alloc];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"img src"]) {
    currentHTMLElement = [[ArticleItem alloc] init];
}
NSLog(@"\t%@ found a %@ element", self, elementName);
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (!currentHTMLElement)
    currentHTMLElement = [[NSMutableString alloc] initWithString:string];   
NSLog(@"Processing Value: %@", currentHTMLElement);
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName   
{
if ([elementName isEqualToString:@"img src"])
    {
        currentHTMLElement.img = elementName;
        [elementArray addObject:currentHTMLElement];
        currentHTMLElement = nil;
        currentNodeContent = nil;
    }
else
{
    if (currentHTMLElement !=nil && elementName != nil && ([elementName isEqualToString:@"img src"]))
    {
        [currentHTMLElement setValue:currentHTMLElement forKey:elementName];
    }
}
    currentHTMLElement = nil;
}                
@end

考えていただきありがとうございます。

4

1 に答える 1

7

HTMLは一般的に整形式のXMLではないため、機能しNSXMLParserない可能性があります。HTMLを解析する場合は、このRayWenderlichの記事「iOSでHTMLを解析する方法」を参照してください。これらの手順に従い、プロジェクトにHppleを追加した場合は、次のsrcように画像属性を取得できます。

#import "TFHpple.h"

- (void)retrieveImageSourceTagsViaHpple:(NSURL *)url
{
    NSData *data = [NSData dataWithContentsOfURL:url];

    TFHpple *parser = [TFHpple hppleWithHTMLData:data];

    NSString *xpathQueryString = @"//img";
    NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];

    for (TFHppleElement *element in nodes)
    {
        NSString *src = [element objectForKey:@"src"];
        NSLog(@"img src: %@", src);
    }
}

NSRegularExpressionまたは、これは反応答の猛攻撃に備えていると私は言います(私の大好きなStack Overflowの回答imgのように)、 htmlファイル内のタグのリストが必要な場合は、次のやや複雑な正規表現を使用できます表現:

- (void)retrieveImageSourceTagsViaRegex:(NSURL *)url
{
    NSString *string = [NSString stringWithContentsOfURL:url
                                                encoding:NSUTF8StringEncoding
                                                   error:nil];

    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];

    [regex enumerateMatchesInString:string
                            options:0
                              range:NSMakeRange(0, [string length])
                         usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {

                             NSString *src = [string substringWithRange:[result rangeAtIndex:2]];
                             NSLog(@"img src: %@", src);
                         }];
}

を使用したい場合はNSXMLParser、次のようになります。

- (void)retrieveImageSourceTagsViaNSXMLParser:(NSURL *)url
{
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    parser.delegate = self;
    [parser parse];
}

#pragma mark - NSXMLParserDelegate methods

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"img"])
    {
        NSString *src = attributeDict[@"src"];

        NSLog(@"img src: %@", src);
    }
}

問題は、私の経験でNSXMLParserは、HTMLの解析がLibXML2/Hppleよりもうまくいかないことです。いくつかの単純なページでは、上記がうまく機能していることがわかります。しかし、他の状況では、そうではありません。結論として、NSXMLParser整形式のXMLの解析には優れていますが、HTMLの解析に使用することには注意が必要です。

于 2013-02-13T20:36:43.873 に答える