撰寫 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.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 編碼,去除結尾的
=
字符(如有)。
! 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 或 Javaxmlhttprequest
— requests started using theXMLHttpRequest
object orfetch()
APIobject-subrequest
—— 插件的請求,比如 Flashsubdocument
—— 內嵌的頁面,通常通過 HTML 的框架方式內嵌ping
— requests started by<a ping>
ornavigator.sendBeacon()
(Adblock Plus 2.7.1 or higher required)websocket
— requests initiated viaWebSocket
object (Adblock Plus 2.8 or higher required)webrtc
— connections opened viaRTCPeerConnection
instances to ICE servers (Adblock Plus 1.13.3 for Chrome and Opera, 3.0 for Firefox, or higher required)document
—— 網頁本身(只適用於 例外規則 )elemhide
—— 只適用於例外規則,類似於document
但是只禁用頁面上的隱藏規則而不是所有規則(需要 Adblock Plus 1.2 或更高版本)generichide
— for exception rules only, similar toelemhide
but only disables generic element hiding rules on the page (Adblock Plus 2.6.12 or higher required)genericblock
— for exception rules only, just likegenerichide
but disables generic blocking rules (Adblock Plus 2.6.12 or higher required)popup
— pages opened in a new tab or windowother
—— 其他不在上面的類型的請求The type optionsbackground
,xbl
anddtd
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
。 您可以查看正則表達式的文檔來學習如何寫正則表達式。
注: 由於性能原因,建議儘可能避免使用正則表達式。
元素隱藏
基本規則
有時您可能會發現無法阻擋某些內嵌在網頁中的文字廣告。如果查看源碼的話,可能發現類似這樣的代碼:
Only here you get the best tofu!
因為您必須下載頁面的內容,所以您也必須下載這些廣告。對於這種情況,您可以做的就是把這些廣告藏起來,這樣您就不會看到他們了。這也就是元素隱藏的意義所在。
上面代碼中的第一則廣告是在一個 class 屬性為 “textad” 的 div 容器內。過濾規則 ##.textad
。 這裡的 ## 表明這是一條元素隱藏規則,剩下的就是定義需要隱藏元素的選擇器,同樣的,您可以通過他們的 id 屬性來隱藏 ###sponsorad
會隱藏第二個廣告。您不需要指定元素的名稱, 過濾規則 ##textad
同樣也可以。您也可以僅指定要阻擋的元素名稱來隱藏,例如:{4}
可以隱藏第三則廣告。
在不查看頁面源碼的情況下,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 元素相鄰的元素: ##.adheader + *
。完整的 CSS 列表請查看 W3C CSS 規範 (Firefox 目前並沒有支持所有的選擇器)。 Please keep in mind that browsers are slower to process these selectors than selectors based on class
or id
attribute only.
注:這個功能只是給高級用戶使用的,您可以很舒服地通過 CSS 選擇符去使用它。Adblock Plus 無法檢查您添加的選擇器的語法是否正確,如果您使用無效的 CSS 語法,可能會破壞其它已有的有效過濾規則。建議使用 JavaScript 控制台檢查是否有 CSS 錯誤。
Extended CSS selectors (Adblock Plus specific)
Sometimes the standard CSS selectors aren’t powerful enough to hide an advertisement. For those cases we have added some new selectors, namely :-abp-has()
, :-abp-contains()
and :-abp-properties()
(requires Adblock Plus 1.13.3 or higher for Chrome and Opera).
When writing an element hiding filter that makes use of these extended selectors you must use the #?#
syntax, e.g. example.com#?#selector
. But it’s important to note that doing so carries a performance impact, so do so sparingly and make sure those filters are specific to as few domains and elements as possible.
:-abp-properties()
:-abp-properties(properties)
will select elements based upon stylesheet properties. For example :-abp-properties(width:300px;height:250px;)
will select elements that have a corresponding CSS rule in a stylesheet which sets the width
and height
to the values 300px
and 250px
respectively. Property names are matched case-insensitively. Furthermore, wildcards can be used so that :-abp-properties(width:*px;height:250px;)
will match any width specified in pixels and a height of 250 pixels.
You can also use regular expressions by surrounding the properties expression with “/”. For example, :-abp-properties(/width:30[2-8]px;height:250px;/)
will match widths between 302 and 308 pixels and a height of 250 pixels.
Note: The older syntax for the CSS property filters is deprecated and will be automatically converted to the new format . The syntax to select the style properties remain the same. For example, [-abp-properties='width:300px;height:250px;']
will be converted to :-abp-properties(width:300px;height:250px;)
.
:-abp-properties()
will also select elements using the style properties found in their pseudo-elements, like ::before
and ::after
. For example, :-abp-properties(content:'Advertisment')
will match elements where the string Advertisment is found in either their ::before
or ::after
pseudo element.
:-abp-has()
:-abp-has(selector)
will select elements based on their content. For example :-abp-has(> div > a.advertiser)
will select elements that contain as a direct descendant a <div>
that contains an <a>
with the class advertiser
. The inner selector can be relative to the element scope, and can use any of the pseudo-selectors, including :-abp-has()
and will determine whether the selection will occur.
:-abp-contains()
:-abp-contains(text)
will select elements based on their text content. For example, div.sidebar > span:-abp-contains(Advertisment)
will select the <span>
elements within a <div>
, with a class of sidebar
that contains the word “Advertisment”. In practice, you’d want to combine this with a :-abp-has()
to select the outer container — something like div.sidebar > div:-abp-has(span:-abp-contains(Advertisment))
to select the container that would contain an advertisement label.
例外規則
例外規則的作用是在特定域名中禁用已有的規則。 這對於那些與其他訂閱組配合使用,且無法更改該訂閱組的作者來說較為有用。 例如,如要讓 ##.textad
規則禁用於 example.com
,可以使用 example.com#@#.textad
。 這條組合規則就等同於 ~example.com##.textad
。 建議您僅在無法調整全局隱藏規則時才使用例外規則,否則請首選限定在特定域名的規則。 These exceptions will be applied to advanced pseudo-selector rules as well.
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##.textad
is a specific filter, whereas both ##.textad
and ~example.com##.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 時的默認值)。
本文來自投稿,不代表超哥工作室立場,如若轉載,請註明出處:https://www.chaoneo.cn/zh-hant/archives/3284.html
如果您覺得超哥分享對您有所幫助的話,記得打賞給我😀