Thursday, December 07, 2006

编写Adblock Plus 过滤器

本文翻译自Adblock Plus0.7.2.2的帮助文档《Adblock Plus:Writing Adblock Plus filters》,原文链接:Adblock Plus: Writing Adblock Plus filters.
将大家喜闻乐见的过滤规则(filter)翻译为过滤器,因为"过滤规则"这个词让位于"filter rules"了.
Creative Commons,诸君自便.
------Jacky-Q

目录

Writing Adblock Plus filters

当前版本的Adblock Plus允许你用许多不同的方法"优化"你创建的过滤器.本篇文档阐述 了你所能拥有的选择以及使用之道.
免责声明:本篇文档所提供的过滤器范例仅供参考,非用于直接使用.

Adblock Plus过滤器简介(Introduction to Adblock Plus filters)

本章节所描述的功能理应足够满足仅仅是偶尔创建些过滤器的用户的需求.

基本过滤规则(Basic filter rules)

你所能定义的最常见的过滤器当然就是你想要干掉的那些横 幅广告的地址.不过,它们常常是变动的.比如这样一个例子 http://domain.com/ads/banner123.gif ,123就是个随机数.直接干掉这个地址无甚大用处,你需要一个更通用的过滤器 ----比如 http://domian.com/ads/banner*.gif 或者可能甚至是 http://domain.com/ads/* .
小贴士:注意不要替换出太多的通配符.过滤器 http://domain.com/* 绝对会干掉所有的横幅广告但同时也会干掉domain.com上 剩下的你想浏览的瓜瓜枣枣.

定义白名单(Defining exception rules)

有时你会发现有某条过滤器把一些本不应被干掉的东西也干净利落地阻挡掉了,你不想移除这条过滤器但是也不想那些东西被“光荣匹配”。 这时便显出了白名单的好处来——它可以定义一些可以在过滤器下幸存的东西。比如你对过滤器 advhttp://domain.com/advice.html 过滤掉很不爽,你 就可以定义一个白名单规则@@advice .白名单规则和过滤规则并无不同,你可以使用通配符或正则表达式,只不过还必须在每条白名单前面加上@@来声明它是个百名单罢了. 白名单还有其他用处.如果一条白名单规则以 http://https:// 开头(可以在之前加个竖线),那么它可以让该地址下的所有页面处于白名单保护之中.例如: 如果你给个白名单规则 @@|http: //domain.com ,然后打开一些domain.com的页面——Adblock Plus将对这些页面无能为力,没有什么会被阻挡掉.

注释(Comments)

任何以惊叹号开头的规则都会被标识为一条注释,并在过滤器列表中以灰色显示。Adblock Plus会忽略这条规则而不是真的试图按图索骥,所以在这里写下任何你想说的话是安全的。你可以在某条过滤器上面添加这样地注释来描述这条过滤器到底在干什么。或者你可以在你的过滤器顶部放上注释来表明原创作者(正如大部分过滤器 列表写手做的那样)。

高级功能(Advanced features)

本章节所讲述的功能通常给强悍的用户和过滤器列表写手使用。爱看不爱。

匹配地址头/尾部(Matching at beginning/end of an address)

Adblock Plus通常会默认所有过滤器的头部和尾部都有个通配符,像 过滤器 ad 和*ad* 就无甚区别.虽说基本上这不会造成问题,不过你有时难免希望能够让定义的某些过滤器只匹配地址的头部或尾部.例如你也许其实是想干掉所有的 flash ,但是如果添加的过滤 器是swf,那么这个地址:http://domain.com/swf/index.html 将会玉石俱焚. 这个问题的解决方案是:给过滤器加个竖条符来告诉Adblock Plus到地址的尾部去开展工作.例如过滤器 swf| 将会干掉 http://domain.com/annoyingflash.swf 而不是http://domain.com/swf/index.html .而过滤器 |http://baddomain.com/ 将会干掉http://baddomain.com/banner.gif 而不是 http://gooddomian.com/analyze?http://badomain.com .

指定过滤项(Specifying filter options)

Adblock Plus允许你指定一揽子选项来修正过滤器的行为.做法是在过滤器尾部加上一个美元符,然后紧接着列出过滤项,并以逗号相隔.示例如下: */ads/*$script,match-case 这里 */ads/* 是真正的过滤器,script和match-case是它的过滤项.目前Adblock Plus的选项有:
  • 类型选项(Type options):决定过滤器可以过滤的网页元素类型(若是白名单则是非过滤元素类型).可以指定多个类型选项来通知过滤器对哪些元素类型下手.支持的类型包括:
    • script(脚本)——经由HTML的script标签对载入 的外部脚本.
    • image(图像)——一般图像,特别是由img标签载入的图 像.
    • background(背景)——背景图片,通常由CSS指定。
    • stylesheet(样式表)——外部层叠样式表文件.
    • object(对象)——由浏览器插件处理的内容.像Flash或Java
    • 链接 (link)——图像链接(需要启用"检查横幅链接"(check banner links)功能)
    • subdocument(子文档)——嵌套的页面,通常由框架载入.
    • document(文档)——页面本身(当且仅当白名单将之划 入保护范围)
    • other(其他)
  • 反类型选项 (Inverse type options):指定过滤器不会下手的网页元素类型。支持的类型包括: ~script,~image,~background,~stylesheet, ~object,~link,~subdocument,~document,~other
  • match-case——让过滤器只对匹配大小写的地址下手,例如过滤器 */BannerAd.gif$match-case 将会干掉 http://server.com/BannerAd.gif 而让http: //server.com/bannerad.gif 幸免于难.

使用正则表达式(Using regular expressions)

如果你想让过滤器匹配更多过滤策略但偏偏它却力有不逮, 你可以使用正则表达式.比如过滤器 /banner\d+/ 将会匹配 banner123baner321 而不是 banners,你可以查阅documentation on regular expressions来学习如何编写正则表达式。
小贴士:别指望用正则表达式来提高过滤器列表的工作效率.你可能经常听到那些建议但它是过时的——从Adblock Plus 0.7开始,基本过滤规则的工作效率已经超过了正则表达 式.

隐藏元素:基本规则(Element hiding: basic rules)

有时你会发现广告竟然干不掉,因为它们嵌入到了作为网页本体的文本当中去了.如果你查看网页的源代码你会发现像这样的玩意儿:
<div class="textad">
Cheapest tofu, only here and now!
</div>
<div id="sponsorad">
Really cheap tofu, click here!
</div>
<textad>
Only here you get the best tofu!
</textad>

你需要下载页面因此你也不得不下载了这些广告.此时你能做的就是隐藏这些广告,这样你就眼不见心不烦,这便是隐藏元素的意义所在. 上述的第一条广告被包含在一个类选择器(class)的属性值为"textad"的div元素里,以下的规则将准确隐藏掉这群乌合之众: #div(textad) .你也可以用同样的办法以它们的id属性隐藏之, #div(sponsorad) 将会隐藏第二条广告.你不需要指定元素名称, 规则 #*(sponsorad) 同样运转良好.你甚至仅凭元素名就隐藏掉元素.比如第三条广告就可以用上 #textad . 那么,如何知道该往元素隐藏规则里放点什么呢?你有两个选择:要么一头扎进网页源代码尝试找到广告在那里,要么使用 DOM Inspector(FFer 可以在安装FF时选择自定义安装并 勾选"Development Tools"来装上该扩展).不管哪条路,HTML的基础知识是 必不可少的.
小贴士:隐藏元素的规则和一般的过滤器非常不同.别说我没告诉你,它不支持通配符、过 滤次数统计以及白名单.

隐藏元素:特定域限定(Element hiding: limiting rules to certain domains)

通常你想要隐藏一个指定站点的指定广告,你不想规则匹配到别的站点上去.比如规则 #*(sponsor) 它将会隐藏到一些站点的无辜代码.不过如果你把它写成 domain.com#(sponsor) 它将会被应用到 http://domain.com http://something.domain.com/ 而不是 http: //otherdomain.com/ .你可以指定多个域——只要用逗号把域分隔开就好: domain1.com,domain2.com,domain3.com#*(sponsor) . 小贴士:由于隐藏元素的实现方式,你真的只能写出域的全称来加以限制.你不能仅使用 地址的一部分或是使用 domain 来替代 domain.com,domain.co.uk .
小贴士:带域限制的隐藏元素规则可以用来隐藏浏览器的用户界面元素.例如过滤规则 browser#menuitem(javascriptConsole) 将会隐藏FF的工具菜单中的错误控制台项。

隐藏元素:属性选择器(Element hiding: attribute selectors)

某些广告对 你而言还真不是吃素的——它们的文字广告既没有id也没有class属性。不过你可以使用 其他属性来隐藏之,比如 #table(width=80%) 将会隐藏width的值设为80%的表 格.如果你不想指明属性值的全部, #div(title*=adv) 将会隐藏所有的title属 性值中含有"adv"字符串的div元素.你也可以检索一个属性的头部或尾部,比如 #div (title^=adv)(title$=ert) 将会隐藏所有的title属性值中以"adv"起头"ert"结尾 的div元素.如你所见,你 还可以使用多属性的过滤策略—— table(width=80%) (bgcolor=white) 会匹配width值为80%bgcolor值为 white的表格.

隐藏元素:使用贫民CSS(Element hiding: using raw CSS)

如果连元素选择器也无计可施,试试 让CSS选择器大展身手.例如以下规则将隐藏所有"adbeader"类的div元素: ##div.adheader+* .两个井字符表明该隐藏元素规则应当被解释为一个 CSS选择器(this particular one is a adjacent sibling selector) 小贴士:此功能仅适用于高级用户,你应当对CSS选择器得心应手才好使用它.Adblock Plus无法对你添加的选择器做语法检查,如果你使用了非法的CSS语法可能导致其他的合 法规则感到郁闷.可以在错误控制台查看CSS错误.

兼容性提示(Adblock以及其他不同的Adblock Plus 版本) (Compatibility notes)

本文档描述了ADblock Plus0.7的各种用法.不过,如果你想 搞腾出自己的过滤器列表并将之共享出来,你可能需要考虑下其他的Adblock Plus版本或 者Adblock.以下是各版本间不同之处的简短总结:
  • 匹配地址的头部/尾部:仅被Adblock Plus 0.6.1.2及更高版本支持.
  • 白名单:在Adblock 0.5和Adblock Plus 0.5前缀为"@@"的白名单仅支 持处理单个目标,不支持多页面,多页面的白名单处理方式是不一样的.注意第一个支持白 名单的Adblock版本是0.5.3.40.
  • 注释:Adblock0.5和Adblock Plus 0.7将会把注释解释为真实的过滤规则.不过这一般不会阻止过滤器写手的使用,注释发生误杀的几率是极其低的.
  • 过滤项:仅被Adblock Plus 0.7.1及更高版本 支持.
  • 隐藏元素:在Adblock Plus0.6.1版本中得到推介,但仅支持基本的 规则.属性选择器,贫民CSS和域限制出现在Adblock Plus 0.7版本中.Adblock Plus 0.5有个"DIV过滤(DIV blocking)"功能可以实现相似功能.虽然语法(有意的)相似,但 实现方式是完全不同的.因此将DIV过滤规则转化成隐藏元素规则或是反过来,都是 前 路曲折的.

译者注:
⑴:本文以斜体表示。
⑵:事实上最好的方式就是FF的"查看选中源代码”,定位迅速准确可视范围大.DOM Inspector的处理效率与页面层次成正比.
⑶what the hell is this?lol

1 comment:

Anonymous said...

翻译的很棒。学到了不少东西。