Все.

Я пытаюсь получить все URL-адреса изображения текущей страницы в UIWebView.

Итак, вот мой код.

- (void)webViewDidFinishLoad:(UIWebView*)webView {
    NSString *firstImageUrl = [self.webView stringByEvaluatingJavaScriptFromString:@"var images = document.getElementsByTagName('img');images[0].src.toString();"];
    NSString *imageUrls = [self.webView stringByEvaluatingJavaScriptFromString:@"var images= document.getElementsByTagName('img');var imageUrls = "";for(var i = 0; i < images.length; i++){var image = images[i];imageUrls += image.src;imageUrls += \\’,\\’;}imageUrls.toString();"];
    NSLog(@"firstUrl : %@", firstImageUrl);
    NSLog(@"images : %@",imageUrls);
}

1-й NSLog возвращает правильный src изображения, но 2-й NSLog ничего не возвращает.

2013-01-25 00:51:23.253 WebDemo[3416:907] firstUrl: https://www.paypalobjects.com/en_US/i/scr/pixel.gif
2013-01-25 00:51:23.254 WebDemo[3416:907] images :

Я не знаю почему. Пожалуйста, помогите мне...

Спасибо.

6
tsk 24 Янв 2013 в 20:11

4 ответа

Лучший ответ

Перрохантер указал на одно NSRegularExpression решение, которое великолепно. Если вы не хотите перечислять массив совпадений, вы можете использовать блочный enumerateMatchesInString, тоже:

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

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

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

Я также обновил шаблон регулярных выражений для решения следующих проблем:

  • между начальным тегом img и атрибутом src могут быть атрибуты;
  • после атрибута src и до > могут быть атрибуты;
  • в середине тега img могут быть символы новой строки (. захватывает все, кроме символа новой строки);
  • значение атрибута src может быть заключено в кавычки ', а также "; а также
  • между src и = могут быть пробелы, а также между = и последующим значением.

Я свободно признаю, что чтение шаблонов регулярных выражений болезненно для непосвященных, и, возможно, другие решения могут иметь больше смысла (предложение JSON от Joris, с использованием сканеров и т. Д.). Но если вы хотите использовать регулярные выражения, приведенный выше шаблон может охватывать еще несколько перестановок тега img, и enumerateMatchesInString может быть немного более эффективным, чем matchesInString.

13
Rob 24 Янв 2013 в 19:03

С данным html вы можете использовать библиотеку SwiftSoup. Использование Swift 3

do {
    let doc: Document = try SwiftSoup.parse(html)
    let srcs: Elements = try doc.select("img[src]")
    let srcsStringArray: [String?] = srcs.array().map { try? $0.attr("src").description }
    // do something with srcsStringArray
    } catch Exception.Error(_, let message) {
        print(message)
    } catch {
        print("error")
    }
2
kamil3 5 Апр 2017 в 17:28

Я не люблю регулярные выражения, поэтому вот мой ответ без них.

Javascript с отступом для пояснения:

// javascript to execute:
(function() {
    var images=document.querySelectorAll("img");
    var imageUrls=[];
    [].forEach.call(images, function(el) {
        imageUrls[imageUrls.length] = el.src;
    }); 
    return JSON.stringify(imageUrls);
})()

Вы заметите, что я возвращаю строку JSON здесь. Чтобы прочитать это обратно в Objective-C:

NSString *imageURLString = [self.webview stringByEvaluatingJavaScriptFromString:@"(function() {var images=document.querySelectorAll(\"img\");var imageUrls=[];[].forEach.call(images, function(el) { imageUrls[imageUrls.length] = el.src;}); return JSON.stringify(imageUrls);})()"];

// parse json back into an array
NSError *jsonError = nil;
NSArray *urls = [NSJSONSerialization JSONObjectWithData:[imageURLString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];

if (!urls) {
    NSLog(@"JSON error: %@", jsonError);
    return;
}

NSLog(@"Images : %@", urls);
11
Joris Kluivers 24 Янв 2013 в 17:06

Вы могли бы добиться этого, запустив регулярное выражение в загруженном HTML-коде webview.

NSString *yourHTMLSourceCodeString = [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"];

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

    NSArray *matches = [regex matchesInString:yourHTMLSourceCodeString
                                      options:0
                                        range:NSMakeRange(0, [yourHTMLSourceCodeString length])];

    NSLog(@"total matches %d",[matches count]);

    for (NSTextCheckingResult *match in matches) {
        NSString *img = [yourHTMLSourceCodeString substringWithRange:[match rangeAtIndex:2]] ;
        NSLog(@"img src %@",img);
    }

Это довольно простое регулярное выражение, которое соответствует чему-либо внутри тега, и потребуется больше подробностей, если ваши изображения имеют больше атрибутов, таких как class или id

6
perrohunter 24 Янв 2013 в 16:31