撰寫 Adblock Plus 過濾條件

目前的 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.gifhttps://example.com/banner.gifhttp://www.example.com/banner.gif。可以在網域的前面加上兩個管線符號 (||) 來達成:||example.com/banner.gif 將會阻擋上面這些網址,而不會過濾 http://badexample.com/banner.gifhttp://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 會忽略所有註解,所以您可以輸入任何想要的文字。您可以在某過濾條件的上方加上註解來描述其用途。或是放在列表的最上面來聲明您的著作權 (大多條件集作者都會這麼做)。

Special comments

Special comments will only have an effect in downloaded filter lists, not in custom filters. They can set a number of parameters for the filter list:

進階功能

本章節描述了一些進階使用者和條件集作者才會用到的功能。這部份可以跳過。

指定過濾選項

Adblock Plus 允許您指定一些選項來修改過濾條件的行為。若您要列舉這些阻擋類型,請在規則的最後面加上錢幣符號 ($) 並以逗號隔開。舉個例子:

*/ads/*$script,match-case

這裡的 */ads/* 規則,強調 scriptmatch-case 作為它的阻擋類型。以下列出的是目前支援的阻擋類型:

使用正規表示法

若您想要更準確地控制過濾條件,使其只過濾想阻擋的部份,您可以使用正規表示法。此條件 /banner\d+/ 將會阻擋 banner123banner321 而不會過濾 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 將會隱藏工具選單中的Javascript錯誤主控台。

屬性選擇器

有些廣告沒辦法輕鬆的解決 — 這些廣告既沒有 id 也沒有 class 屬性。您可以使用其他的屬性來隱藏它們,如 ##table[width="80%"] 將會隱藏寬度屬性設為 80% 的 table,如果您不明確指定屬性中完整的值,像是 ##div[title*="adv"] 將會隱藏所有 title 屬性含有"adv"字串的 div 元素。您也可以檢查屬性的開頭或結尾,像是 ##div[title^="adv"][title$="ert"]將會隱藏 title 屬性的開頭為"adv"及結尾為"ert"的 div 元素。如您所見,您也可以使用多個條件 — table[width="80%"][bgcolor="white"] 將會匹配寬度屬性設為 80% 且背景顏色為白色的 table 元素。

進階選擇器

一般而言,Firefox 所支援的 CSS 選擇器都可以為元素隱藏規則所用。舉個例子,此規則將會隱藏跟隨在 class 屬性為 adheader 的 div 後方的元素:##div.adheader + *。若要取得完整的 CSS 列表請參考 W3C CSS 規格書 (請記得 Firefox 尚未支援所有的選擇器)。

備註:這個功能僅供進階使用者所用,您應該透過 CSS 選擇器來使用它。當您使用了錯誤的 CSS 語法 Adblock Plus 也不會發現,這可能破壞其他規則。請用Javascript錯誤主控台檢查 CSS 錯誤。

例外規則

例外規則可以在特定的網域上停用現有的隱藏條件。 這對附屬於某些列表,而又無法調整主要列表規則的條件集作者十分有用。 舉個例子,若要讓 ##div.textadexample.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.

Implementing a sitekey on the server

For a sitekey-restricted filter to apply, a webpage needs to return base64-encoded versions of the public key and a signature which Adblock Plus can validate. Currently, this means including them in both the HTTP response header (X-Adblock-Key: abcdpublickeydcba_abcdsignaturedcba) and the root tag of the document (<html data-adblockkey="abcdpublickeydcba_abcdsignaturedcba">).

First you need to create a private RSA key (preferably 512 bit to keep the transfer volume low) and then a DER representation of the public key.

The data used for creating the signature is a concatenated list of request variables (namely URI, host and user agent) separated by the NUL character "\0". For example:

  /index.html?q=foo\0www.example.com\0Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:30.0) Gecko/20100101 Firefox/30.0

Finally, generate the signature for this string by using the signature algorithm SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE (default when using OpenSSL).