6

每个人。

我正在尝试在 UIWebView 中获取当前页面的所有图像 url。

所以,这是我的代码。

- (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);
}

第一个 NSLog 返回正确图像的 src,但第二个 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 :

我不知道为什么。请帮我...

谢谢。

4

4 回答 4

13

Perrohunter 指出了一种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属性值可以用as'"; 和
  • src和 the之间=以及 the=和后续值之间可以有空格。

我自由地认识到,阅读正则表达式模式对于初学者来说是痛苦的,也许其他解决方案可能更有意义(Joris 的 JSON 建议,使用扫描仪等)。但是如果你想使用正则表达式,上面的模式可能会覆盖更多的img标签排列,并且enumerateMatchesInString可能比matchesInString.

于 2013-01-24T18:53:18.847 回答
11

我不喜欢正则表达式,所以这是我没有它们的答案。

为澄清而缩进的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);
于 2013-01-24T16:50:36.727 回答
6

您可以在加载的 webview html 源代码上运行正则表达式来实现这一点

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);
    }

这是一个非常基本的正则表达式,可以匹配标签内的任何内容,如果您的图像具有更多属性(例如类或 id),则需要更多详细信息

于 2013-01-24T16:21:37.813 回答
2

使用给定的 html,您可以使用SwiftSoup库。使用斯威夫特 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")
    }
于 2017-04-05T17:28:32.937 回答