撰写 Adblock Plus 过滤规则

摘自Adblock Plus


撰写 Adblock Plus 过滤规则
AdBlock Plus 过滤规则介绍基本过滤规则
定义例外规则
匹配网址开头/结尾
标记分隔符
注释特殊注释

进阶功能指定过滤规则选项
使用正则表达式

元素隐藏基本规则
限定在特定域名的规则
属性选择符
高级选择符
例外规则
简单元素隐藏语法
Generic / Specific filters

在服务器上实施 sitekey

当前的 Adblock Plus 版本允许您通过许多不同的方法来优化过滤规则。本文档就是告诉您如何做。
声明:这里给出的过滤规则只是示例,不一定能直接使用。
AdBlock Plus 过滤规则介绍
本章节描述的过滤规则属性,对偶尔才写过滤规则的用户来说足矣。
基本过滤规则
最简单的过滤规则当然就是您想阻挡的横幅广告地址,但是这些地址常常会在您每次打开页面时改变。例如: http://example.com/ads/banner123.gif
,其中 123 是一个随机数字。在这里阻挡整个图片地址是没用的,您需要创建一条更通用的过滤规则 —— 如 http://example.com/ads/banner.gif
。或者更为通用一些的,如 http://example.com/ads/


:不要使用通配符来代替过多的字符。过滤规则 http://example.com/*
固然可以阻挡所有的横幅广告, 但也会阻挡 example.com 下其它一些您想看的内容。
定义例外规则
有时您可能会发现某个过滤规则平时挡广告挡得很好,但在某些情况下,会阻挡一些不该挡的内容。您不想移除这条过滤规则,但也不希望它阻挡不该挡的内容。
这就是例外规则的好处——它们允许您定义过滤规则不被使用的情况。例如,您不满意过滤规则 adv
阻挡了 http://example.com/advice.html
,您就可以定义一条例外规则 @@advice
。 例外规则和过滤规则没什么两样,您可以使用通配符或正则表达式。您只需在规则前添加 @@
来声明这是一个例外规则。
Exception rules can do more. If you specify $document
option you will get an exception for the entire page. For example, if your exception rule is @@||example.com^$document
and you open some page from example.com — Adblock Plus will be entirely disabled on this page and nothing will be blocked.
匹配网址开头/结尾
通常 Adblock Plus 处理过滤规则时,会自己假设在过滤规则的开头与结尾都有一个通配符,例如,过滤规则 ad
ad
是一样。 正常情况下这没什么问题,但有时您可能想要定义可以匹配以网址开头或结尾的过滤规则。例如,您想要阻挡所有的 Flash,但如果您添加过滤规则 swf
地址 http://example.com/swf/index.html
同样也将被阻挡。
这个问题的解决方法:使用管线符号(|)来表示地址的最前端或最末端。例如这条过滤规则 swf|
会阻挡 http://example.com/annoyingflash.swf
但不会阻挡 http://example.com/swf/index.html
。这条过滤规则 |http://baddomain.example/
会阻挡 http://baddomain.example/banner.gif
但不会阻挡 http://gooddomain.example/analyze?http://baddomain.example

有时您想阻挡 http://example.com/banner.gif
以及 https://example.com/banner.gif
http://www.example.com/banner.gif
。这时只需在过滤规则的域名前面加上两个管线符号(||):||example.com/banner.gif
将会阻挡上面的地址而不会阻挡 http://badexample.com/banner.gif
或者 http://gooddomain.example/analyze?http://example.com/banner.gif
(需要 Adblock Plus 1.1 或更高版本)。
标记分隔符
通常您需要接受过滤规则的任何分隔符。例如,您可能写这样一个规则阻挡 http://example.com/
http://example.com:8000/
但不能阻挡 http://example.com.ar/
。在这里,符号(^)用作一个分隔符。 http://example.com^
(需要 Adblock Plus 1.1 或更高版本)。
分隔符可以是除了字母、数字或者 _ - . % 之外的任何字符。 这个地址的结尾也是作为一个分隔符,下面的例子中所有的分隔符以红色标记出: http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82。所以这个地址可以通过这些过滤规则过滤 example.com
%D1%82%D0%B5%D1%81%D1%82
foo.bar

注释
任何以感叹号 (!) 开始的规则,都被视为注释。在过滤规则的列表中,仍然会显示这些规则,但会用灰色的字来显示,而不是黑色。Adblock Plus 在判断规则时,会忽略这些注释,所以我们可以写下任何我们想写的东西。您可以在一条规则上面写下这条规则是做什么用的。也可以在过滤列表的上方写上作者信息(大多数过滤列表的作者已经这样做了)。
特殊注释
特殊注释只在下载的过滤规则列表中生效,在自定义列表中无效。 它们可以为该过滤规则列表设置许多参数:
! Homepage: http://example.com/

此注释表明哪个网页是该过滤规则列表的首页。

! Title: FooList

此注释为该过滤规则列表设置一个固定的标题。 如果此注释存在,用户不能再更改该标题。

! Expires: 5 days

此注释设置该过滤规则列表的更新间隔,指定的值为天数(例如5 days
)或者小时数(例如8 hours
)。 可以提供1小时至14天之间的值。 注意:更新并不一定会在指定的间隔到达时发生。 实际的更新时间会稍微随机化并取决于一些额外因素,以减少服务器负载。

! Checksum: OaopkIiiAl77sSHk/VAWDA

此注释确保数据的意外损坏不会导致出现过滤规则的意外损坏。 举例来说,一些防火墙软件可能会在下载时修改像是 /adnetwork/
的过滤规则来试图保护用户免于广告。 但这会导致移除过滤规则的部分内容,Adblock Plus 将只会看到过滤规则像是 **
。 过滤规则列表中的校验和注释就是为了防止这种情况,任何修改将导致该校验和不再与内容相匹配,然后 Adblock Plus 将忽略该数据。
计算该校验和需要执行下列步骤:
移除现存的校验和及注释(如果有)。
使用 UTF-8 编码对过滤规则列表的文本进行编码。
转换所有换行符为 Unix 样式(替换掉 \r
用 \n
,如果有)。
移除空行(用 \n
字符替换掉连续的 \n
字符)。
计算该文本的 MD5 校验和的 Base64 编码,去除结尾的 =
字符(如有)。

您也可以看看基于 Python 实现的 验证校验和添加校验和到文件作为参考。

! Redirect: http://example.com/list.txt

此注释表明该过滤规则列表已被转移到一个新的下载地址。 Adblock Plus 将忽略此注释后的任何文件内容并立即尝试从新的地址下载。 如果成功,过滤规则列表的地址将按此设置被更新。 如果新的地址与当前地址相同,此注释将被忽略,并意味着它可以作为该过滤规则列表的“权威”地址使用。

! Version: 1234

此注释定义过滤规则列表的数字版本。 此版本号将显示在问题报告中,并且可以用于验证报告指向的是否是过滤规则列表的当前版本。

进阶功能
本章节描述的特性通常只有高级用户和维护过滤列表的作者才会看。普通用户可跳过。
指定过滤规则选项
Adblock Plus 允许您指定某些选项来改变某条规则的行为。您列举这些选项的时候将它们放在美元符号 ($) 后面并用逗号 (,) 分割这些选项,放在过滤规则的最后面,例如:
/ads/$script,match-case
这里的 /ads/
是真实的过滤规则 script
和 match-case
是其指定的选项。下面是目前支持的选项:
类型选项:判定过滤规则(或例外规则)过滤元素的类型。过滤规则可以指定多个类型选项来过滤指定的元素类型。可以指定的类型包括:script
—— 外部脚本,由 HTML script 标签加载
image
—— 正常图片,通常由 HTML 的 img 标签所载入
stylesheet
—— 外部 CSS 样式文件
object
—— 由浏览器插件处理的内容,例如 Flash 或 Java
xmlhttprequest
— requests started using the XMLHttpRequest
object
or fetch()
API

object-subrequest
—— 插件的请求,比如Flash
subdocument
—— 内嵌的页面,通常通过 HTML 的框架方式内嵌
ping
— requests started by <a ping>
or navigator.sendBeacon()
(Adblock Plus 2.7.1 or higher required)
websocket
— requests initiated via WebSocket
object
(Adblock Plus 2.8 or higher required)
document
—— 网页本身(只适用于 例外规则
elemhide
—— 只适用于例外规则,类似于document
但是只禁用页面上的隐藏规则而不是所有规则(需要Adblock Plus 1.2 或更高版本)
generichide
— for exception rules only, similar to elemhide
but only disables generic element hiding rules on the page (Adblock Plus 2.6.12 or higher required)
genericblock
— for exception rules only, just like generichide
but disables generic blocking rules (Adblock Plus 2.6.12 or higher required)
other
—— 其他不在上面的类型的请求

The type options background
, xbl
and dtd
are outdated and should no longer be used.
反转类型选项:指定过滤规则应用的元素类型。可以指定的类型选项: ~script
, ~image
, ~stylesheet
, ~object
, ~xmlhttprequest
, ~object-subrequest
, ~subdocument
, ~document
, ~elemhide
, ~other

third-party/first-party 请求限制:如果指定了 third-party
选项, 则过滤规则只适用于来源与当前正在浏览的页面的不同的请求。类似地,~third-party
适用于来源与当前浏览页面相同的请求。
域名限定:选项 domain=example.com
指过滤规则只适用于 "example.com" 下的页面 。多个域名可以用 "|" 分隔: 过滤规则 domain=example.com|example.net
将只适用于 "example.com" 或 "example.net" 的页面。如果一个域名是前面有"~",则该过滤规则适用于这个域名的页面。例如: domain=~example.com
指过滤规则适用于除了 example.com 之外的任何域名的页面而 domain=example.com|~foo.example.com
限定了过滤规则适用于 "example.com" 但不包括 "foo.example.com" 。
Sitekey 限制:选项 sitekey=abcdsitekeydcba
意味着该过滤规则应该只在页面上提供了一个与过滤规则内含有的非常相似的(但没有 = 后缀的)公钥和一个可被验证的签名时应用。可以使用“|”作为分隔指定多个 sitekey:使用 sitekey=abcdsitekeydcba|bcdesitekeyedcb
作为过滤规则的选项时,将只会在页面提供了“abcdsitekeydcba”或者“bcdesitekeyedcb”的 sitekey 时应用。这类似于域名限制,但这允许单条过滤规则应用到相当多的域。注意,sitekey 限制需要服务器侧的修改
match-case
—— 使过滤规则只适用于匹配地址,例如:过滤规则 */BannerAd.gif$match-case
会阻挡 http://example.com/BannerAd.gif
但不会阻挡 http://example.com/bannerad.gif

collapse
— 这个选项将覆盖全局"隐藏已屏蔽元素的占位符"选项,并确保过滤规则总是隐藏这些元素。类似地,~collapse
选项将确保过滤规则不隐藏这些元素。
donottrack
—— 对有该选项的阻挡规则匹配到且有该选项的例外规则未匹配到的地址会发送一个 Do-Not-Track 头 (需要Adblock Plus 1.3.5 或更高版本)。 为了向后兼容,使用此选项时建议使用矛盾的组合类型选项,防止此规则在早期版本的 Adblock Plus 中阻挡任何东西: *$donottrack,image,~image

使用正则表达式
如果您想更好地控制您的过滤规则,什么匹配,什么不匹配,您可以使用正则表达式。例如过滤规则 /banner\d+/
会匹配 banner123
和 banner321
而不会匹配 banners
。 您可以查看正则表达式的文档来学习如何写正则表达式。
: 由于性能原因,建议尽可能避免使用正则表达式。
元素隐藏
基本规则
有时您可能会发现无法阻挡某些内嵌在网页中的文字广告。如果查看源码的话,可能发现类似这样的代码:
<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
可以隐藏第三则广告。
在不查看页面源码的情况下,Element Hiding Helper 扩展 可以帮助选择正确的元素并写出相应的规则。基础的HTML知识还是很有用的。
:元素隐藏规则与普通过滤规则的工作方式有很大的差别。元素隐藏规则不支持通配符。
限定在特定域名的规则
通常您只想要隐藏特定网站的特定广告,而不希望规则会作用于其他网站。例如,过滤规则 ##
.sponsor
可能会把某些网站的有效代码也隐藏了。但如果你把它写成 example.com##.sponsor
就只会在 http://example.com/
http://something.example.com/
生效了,而不是 http://example.org/
。 你也可以指定多个域名——只要用逗号(,)分隔即可:domain1.example,domain2.example,domain3.example##
.sponsor

如果在域名之前有 "~",该过滤规则适用于这个域名的页面(需要 AdBlock Plus 1.1或更高版本)。例如, ~example.com##.sponsor
将适用于除了 "example.com" 之外的域名,example.com,~foo.example.com##
.sponsor
适用于 "example.com" 但不适用于 "foo.example.com" 子域名。
:由于元素隐藏实现方式的关系,您只可以将隐藏规则限定在完整的域名。您不能使用网址的其他部份,也不可用 domain
代替 domain.example,domain.test

: 限定域名的元素隐藏规则也可用来隐藏浏览器的使用界面。例如,过滤规则 browser##menuitem#javascriptConsole
会隐藏 Firefox 工具菜单中的 JavaScript 控制台。
属性选择符
一些广告隐藏起来并不容易——它们广告不仅没有 id 也没有 class 属性。您可以使用其他属性来隐藏,例如 ##table[width="80%"]
可以隐藏 width 属性值为 80% 的表格元素。 如果您不想指定属性的完整值,##div[title*="adv"]
会隐藏所有 title 属性包含 adv 字符的 div 元素。您还可以检查属性的开始和结束字符,例如 ##div[title^="adv"][title$="ert"]
会隐藏 titile 属性以 adv 开始并且以 ert 结束的 div 元素。正如您所见,你可以使用多个条件 —— table[width="80%"][bgcolor="white"]
会匹配到 width 属性为 80%、bgcolor 属性为 white 的表格元素。
高级选择符
通常情况下,Firefox 支持的 CSS 选择器都可用于元素隐藏。例如:下面的过滤规则会隐藏 class 的属性为 adheader 的 div 元素相邻的元素: ##div.adheader + *
。完整的 CSS 列表请查看 W3C CSS 规范 (Firefox 目前并没有支持所有的选择器)。
:这个功能只是给高级用户使用的,您可以很舒服地通过 CSS 选择符去使用它。Adblock Plus 无法检查您添加的选择器的语法是否正确,如果您使用无效的 CSS 语法,可能会破坏其它已有的有效过滤规则。建议使用 JavaScript 控制台检查是否有 CSS 错误。
例外规则
例外规则的作用是在特定域名中禁用已有的规则。 这对于那些与其他订阅组配合使用,且无法更改该订阅组的作者来说较为有用。 例如,如要让 ##div.textad
规则禁用于 example.com
,可以使用 example.com#@#div.textad
。 这条组合规则就等同于~example.com##div.textad
。 建议您仅在无法调整全局隐藏规则时才使用例外规则,否则请首选限定在特定域名的规则。
简单元素隐藏语法
Adblock Plus 支持简单元素隐藏语法(例如: #div(id=foo)
)只是为了向后兼容性。使用这个语法是不好的,CSS 选择器才是首选。对这个语法的支持可能在以后的某个时间就不支持了。
Generic / Specific filters
With the $generichide
and $genericblock
filter options the distinction between generic and specific filters becomes important.
We classify a filter to be specific if it matches one or more domains or matches a sitekey. If a filter has no domains specified (or only domain exceptions) and no sitekey then it counts as generic. For example, example.com##div.textad
is a specific filter, whereas both ##div.textad
and ~example.com##div.textad
are generic.
Note that with blocking rules the domain must be specified under the $domain option for them to be considered specific. For example, ||example.com^
is considered generic whereas /ads/$domain=example.com
is site-specific.
在服务器上实施 sitekey
若想完成一个采用 sitekey 限制的过滤规则,一个网页需要返回 Base64 编码的公钥版本和 Adblock Plus 可以验证的签名。目前来说,这需要在 HTTP 相应头中包含(X-Adblock-Key: abcdpublickeydcba_abcdsignaturedcba
)及 document 的根标签中(<html data-adblockkey="abcdpublickeydcba_abcdsignaturedcba">
)。
首先,您需要创建一个专用的 RSA 密钥(最好是 512 位以保证较低传输负担)和一个公钥的 DER 表示。
创建签名使用的数据是一个请求变量的连续列表(即 URI、Host 和 User Agent),分隔符是 NUL
字符,即“\0”。举例来说:
/index.html?q=foo\0www.example.com\0Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0
最后,使用 SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE 签名算法生成此字符串的签名(是使用 OpenSSL 时的默认值)。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 70,379评论 12 116
  • 中小民营企业里绝对不能缺的职位: 1、财务官(核算就是数字里要效益)。 2、网络官(不用网络就是慢性自杀)。 3、...
    有梦的人在启航阅读 25评论 0 0
  • 每个人都觉得自己会摸到一手好牌。 在赌局上,我们都踌躇满志,认为自己一定是幸运的赢家,仿佛在跟老天打赌...
    渡边志明阅读 57评论 0 1
  • 一时想不起来要说些什么,关于自己的话题太大…… 十年前自从生了女儿,一下子就到了自己是谁 我活着到底是为什么?到底...
    商紫嫆阅读 337评论 9 3