如何在WKWebView加载URL时拦截广告?
在WKWebView中拦截网页广告的实现方案
嘿,我来帮你解决WKWebView拦截广告的问题,这里有几个实用的方案,你可以根据需求选择:
方法一:通过WKNavigationDelegate拦截广告请求
这个方法的核心是拦截网页发起的所有请求,判断请求URL是否属于广告资源,直接取消加载,从源头阻止广告获取。
首先你需要给WKWebView设置代理,然后实现webView:decidePolicyForNavigationAction:decisionHandler:这个代理方法:
// 先设置WKWebView的navigationDelegate _webVw.navigationDelegate = self; // 实现代理方法,拦截请求 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL *requestURL = navigationAction.request.URL; NSString *urlString = requestURL.absoluteString.lowercaseString; // 这里可以根据广告URL的特征来筛选,比如常见的广告关键词、特定广告域名 NSArray *adKeywords = @[@"ad", @"advertisement", @"banner", @"adservice", @"adnetwork"]; BOOL isAdRequest = NO; for (NSString *keyword in adKeywords) { if ([urlString containsString:keyword]) { isAdRequest = YES; break; } } if (isAdRequest) { // 拦截广告请求,不允许加载 decisionHandler(WKNavigationActionPolicyCancel); } else { // 允许正常的页面请求加载 decisionHandler(WKNavigationActionPolicyAllow); } }
优缺点:优点是从源头拦截,节省流量;缺点是需要维护广告关键词/域名列表,遇到新的广告链接可能需要更新列表,容易有漏网之鱼。
方法二:注入JavaScript隐藏网页广告元素
有些广告是和页面内容一起加载的,或者通过动态脚本生成的,这时候可以注入JS脚本,找到页面中的广告DOM元素并隐藏/移除它们。
你需要在初始化WKWebView时,通过WKUserScript注入自定义的JS代码:
// 创建WKWebView配置对象 WKWebViewConfiguration *webConfig = [[WKWebViewConfiguration alloc] init]; // 编写广告拦截的JS脚本:匹配常见的广告元素(class/id含ad关键词的元素),并移除它们 NSString *adBlockJS = @"function removeAds() { \ // 选择所有可能是广告的元素 var adElements = document.querySelectorAll( \ '[class*=\"ad\"], [id*=\"ad\"], .banner, .advertisement, .ad-container' \ ); \ // 遍历并移除元素 adElements.forEach(function(element) { \ element.parentNode.removeChild(element); \ }); \ } \ // 页面加载完成后执行一次 window.addEventListener('load', removeAds); \ // 监听DOM变化,处理动态加载的广告 var observer = new MutationObserver(function() { \ removeAds(); \ }); \ observer.observe(document.body, { childList: true, subtree: true });"; // 创建WKUserScript,设置在文档加载完成后注入,只作用于主框架 WKUserScript *adBlockScript = [[WKUserScript alloc] initWithSource:adBlockJS injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES]; [webConfig.userContentController addUserScript:adBlockScript]; // 用配置好的config初始化WKWebView _webVw = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:webConfig]; // 加载目标页面 [_webVw loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:page_url]]];
优缺点:能处理页面上的静态和动态广告,不需要拦截网络请求;缺点是广告资源可能已经加载了(浪费流量),而且需要准确匹配广告元素的选择器,不同网站的广告结构可能不一样。
方法三:组合两种方案(推荐)
把请求拦截和JS注入结合起来,先通过代理拦截大部分广告请求,再用JS移除页面上漏网的广告元素,这样既能节省流量,又能保证拦截效果。
比如先按方法一设置代理拦截请求,再按方法二注入JS脚本,两者配合使用,拦截效果会更好。
内容的提问来源于stack exchange,提问作者Shah Paneri
相关产品推荐
相关产品推荐

