Ruby on Rails应用中检测被广告拦截器屏蔽的图片URL方案咨询
解决Rails中批量检测被AdBlock拦截的图片URL问题
这种批量检查广告拦截器命中URL的需求,我之前在RoR项目里也遇到过——直接在浏览器里加载上千张图片肯定会崩,换个思路:用广告拦截器的规则库直接在后端批量匹配URL,效率高得多,还不用折腾浏览器。下面是具体的实现方案:
核心思路
AdBlock类插件(比如AdBlock Plus、uBlock Origin)都是基于公开规则库(比如EasyList)来拦截内容的,我们可以直接把这些规则转换成Ruby能识别的正则,然后在后端批量扫描数据库里的图片URL,找出匹配规则的那些。
步骤1:获取并准备广告拦截规则
- 下载最新的EasyList规则(这是AdBlock最常用的规则集),保存到Rails项目的
lib目录下,命名为easylist.txt。 - 我们只需要提取其中针对图片的规则,所以过滤掉注释行、元数据行,留下包含
$image标记(专门针对图片资源)或图片后缀(.jpg/.png/.gif等)的规则。
步骤2:编写Rake任务批量检测
在lib/tasks目录下创建ad_block_check.rake文件,写一个可执行的Rake任务,实现规则转换、URL匹配和结果导出:
namespace :ad_block do desc "批量检测数据库中被AdBlock拦截的图片URL" task check_images: :environment do # 加载并解析EasyList规则 rules_path = Rails.root.join("lib", "easylist.txt") image_regexes = [] File.foreach(rules_path) do |line| # 跳过注释、分组标签等非规则行 next if line.start_with?("!", "[") || line.strip.empty? # 筛选图片相关规则:带$image标记或图片后缀的规则 if line.include?("$image") || line.match?(/\.(jpg|jpeg|png|gif|webp|svg)/i) rule = line.strip # 将AdBlock规则语法转换为Ruby正则 # 处理||:匹配任意协议的域名前缀(http/https) rule.gsub!("||", "^https?:\/\/.*") # 处理^:匹配路径分隔符或URL结束 rule.gsub!("^", "(?:\/|$)") # 移除$image标记(我们已经筛选了图片规则) rule.gsub!("$image", "") # 处理通配符* rule.gsub!("*", ".*") # 生成忽略大小写的正则 begin regex = Regexp.new(rule, Regexp::IGNORECASE) image_regexes << regex rescue RegexpError # 跳过无效的规则 next end end end puts "✅ 加载了#{image_regexes.size}条图片相关的AdBlock规则" # 批量扫描数据库中的图片URL(替换成你的模型和字段名) blocked_images = [] # 用find_each分批处理,避免内存溢出 YourImageModel.find_each(batch_size: 1000) do |model| next unless model.image_url.present? # 检查URL是否匹配任意一条规则 if image_regexes.any? { |regex| model.image_url.match?(regex) } blocked_images << { id: model.id, url: model.image_url } # 可选:直接在数据库标记被拦截的图片 # model.update!(is_ad_blocked: true) end end # 输出结果 puts "\n🔍 共发现#{blocked_images.size}张可能被AdBlock拦截的图片:" blocked_images.each do |img| puts "ID: #{img[:id]} | URL: #{img[:url]}" end # 可选:导出结果到CSV文件 require 'csv' csv_path = Rails.root.join("blocked_images_report.csv") CSV.open(csv_path, "w") do |csv| csv << ["图片ID", "图片URL"] blocked_images.each { |img| csv << [img[:id], img[:url]] } end puts "\n📊 结果已导出到:#{csv_path}" end end
步骤3:运行任务并验证
- 替换代码中的
YourImageModel和image_url为你实际的模型类名和URL字段名。 - 在终端运行:
bundle exec rake ad_block:check_images - 任务完成后,你会得到控制台输出和CSV报告,里面就是可能被AdBlock拦截的图片URL。
注意事项
- 规则转换准确性:AdBlock的规则语法比较复杂(比如例外规则、特殊修饰符),上面的转换只覆盖了最常见的情况。如果需要更精确的匹配,可以参考AdBlock的规则文档完善转换逻辑。
- 性能优化:如果你的图片数量特别大(几十万级),可以把这个任务放到Sidekiq等后台队列中异步执行,避免阻塞Web进程。
- 测试验证:可以先挑几个已知被拦截的URL测试规则是否能匹配上,调整转换逻辑直到符合预期。
内容的提问来源于stack exchange,提问作者sudo
相关产品推荐
相关产品推荐

