MENU

AdGuard 语法规则——如何创建属于你自己的广告过滤器

声明

本文翻译自AdGuard官方文档How to create your own ad filters,原文链接:https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters

考虑到AdGuard官方文档没有中文简体的AdGuard语法规则,故翻译此文档,本人非专业翻译,部分专业词汇可能存在歧义或错误,若果您在阅读文档过程中发现语法或其他错误,请通过邮箱联系本人进行勘误。

如果本文侵犯到了您的权益,请联系本人删除;未经本人允许,请勿转载本文到其他平台或以此文牟利。

介绍

过滤器是适用于特定内容(横幅、弹出窗口等)的一组过滤规则。AdGuard有一份由我们团队创建的标准过滤器列表。我们的团队不断改进和更新它们,我们希望我们的过滤器能满足大多数用户的需求

同时,AdGuard允许您使用与我们的筛选器中相同类型的规则创建您自己的自定义筛选器

为了描述过滤规则的语法,我们使用了语法规范的增强BNF,但我们并不总是严格遵循此规范

AdGuard语法最初基于Adblock Plus规则的语法,但为了更好地过滤广告,扩展了新类型的规则。本文中有关AdGuard和ABP通用规则的部分内容摘自本文

注释

任何以感叹号开头的行都是注释。在规则列表中,它显示为灰色。AdGuard将忽略此行,因此您可以随心所欲地编写任何内容。注释通常放在规则之上,用于描述规则的作用

示例:

! 这是一条注释,在这条行下面有一条生效的规则
||example.org^

示例

通过域名拦截

这条规则拦截:

  • http://example.org/ad1.gif
  • http://subdomain.example.org/ad1.gif
  • https://ads.example.org:8000/

这条规则不拦截:

  • http://ads.example.org.us/ad1.gif
  • http://example.org/redirect/http://ads.example.org/

拦截确切地址

这条规则拦截:

  • http://example.org/

这条规则不拦截:

  • https://example.org/banner/img

基本规则修饰符

过滤规则支持许多修饰符,使您可以微调规则行为。以下是带有一些简单修饰符的规则示例。

这条规则拦截:

  • http://example.org/script.js 如果这个脚本从 example.com加载

这条规则不会拦截:

  • https://example.org/script.js 如果这个脚本从 example.org加载
  • https://example.org/banner.png 因为这不是一个脚本

取消拦截地址

这条规则不拦截:

  • http://example.org/banner.png 即使这个地址已经有了一条拦截规则

使用$important修饰符的拦截规则可以覆盖异常。

取消拦截网站上所有的内容

这条规则不拦截:

  • 它将禁用 example.com的所有修饰规则
  • 它会解除拦截此网站发送的所有请求,即使存在拦截规则匹配这些请求

修饰规则

修饰规则基于一种使用名为CSS的特殊语言,每个浏览器都能理解。基本上,它为网站添加了一种新的CSS样式,其目的是隐藏特定的元素。您可以在这里了解更多关于CSS的一般信息

AdGuard扩展了CSS,并让过滤器的开发人员处理更复杂的情况。但是,要使用这些扩展规则,您需要流利地使用常规CSS

常见的CSS选择器

CSS选择器示例描述
ID选择器#banners匹配id属性等于banners的所有元素
Class选择器.banners匹配包含bannersclass属性的所有元素
属性选择器div[class="banners"]匹配class属性与banners完全相同的所有div元素
属性子字符串选择器div[class^="advert1"]匹配class属性以advert1字符串开头的所有div元素
属性子字符串选择器div[class$="banners_ads"]匹配class属性以banners_ads字符串结尾的所有div元素
属性子字符串选择器a[href^="http://example.com/"]匹配从http://example.com/域加载的所有链接
属性选择器a[href="http://example.com/"]精确匹配地址为http://example.com/的链接

基本规则

最简单的规则就是所谓的“基本规则”。它们用于拦截对特定URL的请求。或者,如果规则开头有特殊标记“@@”,则取消拦截它。这类规则的基本原则非常简单:您必须指定限制或扩展规则范围的地址和附加参数

子请求

拦截请求的基本规则仅适用于子请求。这意味着它们不会阻止页面加载

响应状态

Browser detects a blocked request as completed with an error.

浏览器检测到被拦截的请求已完成,并返回error状态

基本语法规则

rule = ["@@"] pattern [ "$" modifiers ]
modifiers = [modifier0, modifier1[, ...[, modifierN]]]
  • pattern — 地址掩码,每个请求的URL都根据此掩码进行整理。您也可以在模板中使用特殊字符,其说明如下
  • @@ — 在排除规则中使用的标记。要关闭对请求的过滤,请在您的规则开头使用此标记
  • modifiers — “阐明”基本规则的参数。其中一些限制了规则的范围,一些可以完全改变其工作方式

特殊字符

  • * — 通配符,通配符。它用来表示“任何一组字符”。这也可以是空字符串或任意长度的字符串
  • || — 匹配地址的开头,用此字符,您不必在地址中指定特定的协议和子域。 它意味着|| 代表 http://*., https://*., ws://*., wss://*. 中的一个
  • ^ — 分隔字符标记,分隔符可以是任意字符, 可以是字母、数字或以下字符之一: _ - . %. 在本例中,分隔符以粗体显示: http://example.com/?t=1&t2=t3. 地址末尾也可以使用分隔符
  • | — 指向地址开始或结束的指针,该值取决于地址中的字符位置,例如,规则 swf| 对应于 http://example.com/annoyingflash.swf ,而不对应于http://example.com/swf/index.html. |http://example.org 对应于 http://example.org,而不对应于 http://domain.com?url=http://example.org

视觉表现

我们建议您熟悉这篇文章,以便更好地理解应该如何制定这样的规则。

正则表达式支持

如果您想要更灵活地制定规则,可以使用正则表达式,而不是带有特殊字符的默认简化网址。

性能

使用正则表达式的规则工作较慢,因此建议避免使用它们或将它们的范围限制在特定的域中。

如果你想使用确切的正则表达式拦截,则pattern必须如下所示

pattern = "/" regexp "/"

例如,/banner\d+/$third-party这条规则将对所有第三方请求应用正则表达式banner\d+。正则表达式的排除规则如下所示@@/banner\d+/

不同版本AdGuard的兼容性

由于内容阻止API限制,用于Safari的AdGuard浏览器扩展和用于iOS的AdGuard浏览器扩展不完全支持正则表达式(请参阅“正则表达式格式”部分)

TLD(顶级域)的通配符支持

域的顶级域名(TLD)以修饰符,html和javascript规则的模式支持通配符

例如,修饰规则example.*##.banner将匹配任何example.TLD的请求(example.ruexample.comexample.netexample.org、等)

对于基本规则,所描述的逻辑将仅适用于$domain修饰符中指定的域(例如:||*/banners/*$image,domain=example.*)

基本规则示例

  • ||example.com/ads/* — 一个简单的规则对应于像这样的地址http://example.com/ads/banner.jpg甚至是http://subdomain.example.com/ads/otherbanner.jpg
  • ||example.org^$third-party — 一条拦截第三方请求example.org 及其子域名的规则
  • @@||example.com$document — 常规的排除规则. 它完全禁止对 example.com 及其子域名的过滤。排除规则中可以使用多个修饰符.。想要了解更多细节,请点击下面的[链接]()

修饰符

注意

本节中介绍的功能面向有经验的用户。它们扩展了“基本规则”的功能,但是为了使用它们,您需要对浏览器的工作方式有一个基本的了解。

您可以使用其他修饰符更改“基本规则”的行为。修饰符应位于规则末尾的$符号之后,并用逗号分隔。

示例:

||domain.com^$popup,third-party

基本修饰符

以下修饰符是最简单且经常使用的修饰符

domain

domain将规则应用区域限制为域(及其子域)。要将多个域添加到一个规则,请使用|字符作为分隔符。

domain示例:

  • ||baddomain.com^$domain=example.org — 拦截匹配指定地址的请求的规则,请求来自于example.org域及其子域
  • ||baddomain.com^$domain=example.org|example.com — 相同的规则, 但是同时对 example.orgexample.com生效

如果希望规则对某些域不生效,请将域名以~开头

domain~示例:

  • ||baddomain.com^$domain=~example.org — 排除拦截匹配指定地址的请求的规则,请求来自于example.org域及其子域
  • ||baddomain.com^$domain=example.org|~foo.example.org — 这条规则拦截example.org及其所有子域发送的请求,排除子域 foo.example.org.
third-party

对第三方和自己的请求的限制。第三方请求是来自不同域的请求。例如,从domain.comexample.org的请求是第三方请求。

子域名

请注意,从域到其子域的请求(反之亦然)不被视为第三方请求。例如,从域example.org发送到subdomain.example.org的请求不是第三方请求。

如果存在third-party修饰符,则规则仅适用于第三方请求

third-party示例:

  • ||domain.com^$third-party — 规则适用于所有域,除了domain.com及其子域。第三方请求示例:http://example.org/banner.jpg

如果存在~third-party修饰符,则规则仅适用于不来自第三方的请求,这意味着,请求来自同一域名

~third-party示例:

  • ||domain.com$~third-party — 这条规则适用于 domain.com,但不适用于其它域。例如一个不是来自第三方的请求: http://domain.com/icon.ico.
popup

AdGuard将尝试关闭任何匹配到使用这个修饰符的拦截规则的浏览器选项卡。请注意,这并不会使所有的选项卡关闭

popup示例:

  • ||domain.com^$popup — 如果你在浏览器从任意页面访问 http://domain.com/,通过这条规则会将特定网站打开的新标签页关闭
match-case

此修饰符定义仅适用于与大小写匹配的地址的规则。默认规则不区分大小写

match-case示例:

  • */BannerAd.gif$match-case —这条规则将拦截 http://example.com/BannerAd.gif, 但不会拦截 http://example.com/bannerad.gif.

内容类型修饰符

有一组可适用于将规则的应用区域限制为特定类型的内容的修饰符,还可以组合这些修饰符覆盖例如图像和脚本

不同版本AdGuard的兼容性

请注意,AdGuard在不同平台上确定内容类型的方式存在很大差异。对于浏览器扩展,每个请求的内容类型由浏览器提供。适用于Windows、Mac和Android的AdGuard使用以下方法:首先尝试通过文件扩展名确定请求类型。如果此阶段的请求无法被拦截,将使用服务端响应开头的Content-Type头部来确定类型。

内容类型修饰符示例:

  • ||example.org^$image — 对应 来自于example.org的所有图像
  • ||example.org^$script,stylesheet — 对应来自于example.org的所有脚本和样式
  • ||example.org^$~image,~script,~stylesheet — 对应来自于 example.org 除了图像、脚本和样式的所有请求
image

该规则对应于对图像的请求

stylesheet

该规则对应于对CSS文件请求

script

该规则对应于对脚本请求(例如JavaScript、VBscript)

object

该规则对应于浏览器插件资源(例如Java、Flash)

object-subrequest

该规则对应于对浏览器插件的请求(通常是Flash)

不同版本AdGuard的兼容性

适用于Windows、MacOS和Android的AdGuard通常无法准确确定这种类型,并将其定义为其他类型。

font

该规则对应于对字体请求(例如.woff文件扩展名)

media

该规则对应于对媒体文件请求(音乐和视频,例如.mp4文件)

subdocument

该规则对应于对内置页面的请求(HTML标签frameiframe

ping

该规则对应于由navigator.sendBeacon()或链接上的ping属性引起的请求

不同版本AdGuard的兼容性

此修饰符仅在AdGuard浏览器扩展中受支持

xmlhttprequest

该规则仅适用于Ajax请求(通过javascript对象XMLHttpRequest发送的请求)

不同版本AdGuard的兼容性

适用于Windows、MacOS和Android的AdGuard通常无法准确确定此类型,并将其定义为otherscript

websocket

该规则仅适用于WebSocket连接

other

该规则适用于尚未确定类型或与上面列出的类型不匹配的请求

排除修饰符

排除规则对应于禁止其它基本规则,他们以@@标记,上面列出的所有基本修饰符都可以应用于它们,它们也有一些特殊的修饰符。

视觉表现

我们建议您熟悉本文,以便更好地理解如何制定例外规则。

elemhide

禁用页面上与规则匹配的任何修饰规则,您将进一步找到有关修修饰规则的信息

elemhide示例:

  • @@||example.com^$elemhide —在 example.com 及其所有子域名的页面禁用所有修饰规则
content

禁用页面上与规则匹配的HTML过滤规则,您将进一步找到有关HTML过滤规则的信息

content示例:

  • @@||example.com^$content —在 example.com 及其所有子域名的页面禁用所有HTML过滤规则
jsinject

禁止将javascript代码添加到页面。您可以进一步阅读有关javascript规则的内容

jsinject示例:

  • @@||example.com^$jsinject — 在example.com 及其所有子域名的页面禁用JavaScript
urlblock

禁用拦截从与规则匹配的页面发送的所有请求

urlblock 示例:

  • @@||example.com^$urlblock — 从example.com及其所有子域页面发送的任何请求都不会被拦截。
extension

禁用与此规则匹配的页面上的所有用户脚本

extension示例:

  • @@||example.com^$extension — 在网站example.com的任何界面,用户的脚本都不会起作用
ducument

完全禁用页面上的拦截,相当于同时使用elemhidecontenturlblockjsinjectextension

document示例:

  • @@||example.com^$document — 在example.com 及其所有子域名的所有页面完全禁用拦截
  • @@||example.com^$document,~extension —在example.com 及其所有子域名的所有页面完全禁用拦截,但是会继续运行用户脚本
stealth

禁用所有相应页面和请求的隐藏模式

不同版本AdGuard的兼容性

隐形模式目前在用于Windows的AdGuard、用于Mac的AdGuard和用于Android的AdGuard中可用。我们计划将来把它添加到我们所有的产品中。目前,不支持隐形模式的产品将忽略带有此修饰符的规则。

stealth示例:

  • @@||example.com^$stealth — 禁用example.com及其所有子域名的所有页面的Stealth Mode ,也包括所有请求和子请求
Generic rules

在我们继续下一个修饰符之前,我们必须定义通用规则。如果该规则不限于特定的域,则该规则是通用的

例如,这些规则是通用的:

###banner
~domain.com###banner
||domain.com^
||domain.com^$domain=~example.com

并且这些规则是不通用的:

domain.com###banner
||domain.com^$domain=example.com
generichide

在排除规则中禁用页面所有的通用修饰规则

  • @@||example.com^generichide —在 example.com 及其所有子域名的所有页面禁用通用的修饰规则
genericblock

在排除规则中禁用页面所有的通用基础规则

  • @@||example.com^$genericblock — 在 example.com 及其所有子域名的所有页面禁用通用的基础规则

进阶修饰符

这些修饰符能够完全改变基本规则的行为

important

应用于规则的$important修饰符提高了规则的优先级,,胜过没有$important修饰符的任何其他规则,甚至超过了基本的排除规则

示例1:

||example.org^$important
@@||example.org^

||example.org^$important将会拦截所有请求,尽管有排除规则

示例2:

||example.org^$important
@@||example.org^$important

现在排除规则也有$important修饰符,所以它将占上风

示例3:

如果对文档排除规则应用了document修饰符,那么$important修饰符将会被忽略

||example.org^$important
@@||test.org^$document

如果从test.org域发送了对example.org的请求,那么尽管该规则有$important修饰符,但是它将不会被应用

badfilter

不同版本AdGuard的兼容性

badfilter修饰符当前仅在AdGuard浏览器扩展中可用。它将在稍后添加到其他AdGuard产品中。

带有badfilter修饰符的规则禁用它们所引用的其他基本规则。这意味着禁用规则的文本应该与badfilter规则的文本匹配(不带badfilter修饰符)。

badfilter示例:

  • ||example.com$badfilter 禁用 ||example.com
  • ||example.com$image,badfilter 禁用 ||example.com,image
  • @@||example.com$badfilter 禁用 @@||example.com
  • ||example.com$domain=domain.com,badfilter 禁用||example.com$domain=domain.com

不同版本AdGuard的兼容性

本节中的以下修饰符仅在适用于Windows、MacOS和Android的AdGuard中可用。浏览器扩展功能受到浏览器本身的限制,有些方法对它们是不可用的。

empty

通常,被拦截的请求在浏览器中看起来像是服务器错误。如果您使用empty修饰符,AdGuard将模拟来自服务器的空响应,状态为200 OK

empty示例:

  • ||example.org^$empty — 对来自example.org 及其所有子域名的所有请求返回一个空响应
mp4

作为一个对被拦截请求的响应,AdGuard返回一个短视频占位符

mp4示例:

  • ||example.com/videos/$mp4 — 拦截从||example.com/videos/*的视频下载,并改变响应为一个视频占位符
replace

此修饰符完全更改了规则行为。如果应用了该规则,该规则将不会阻止该请求。相反,响应将被修改。

请注意

您需要一些正则表达式的知识才能使用此修饰符

不同版本AdGuard的兼容性

规则受适用于Windows、Mac、Android的AdGuard和AdGuard的Firefox插件支持
这种类型的规则在其他浏览器的扩展中不起作用,因为它们不能修改网络级别的内容

$replace规则特性

  • $replace规则适用于任何文本响应,但不适用于二进制(mediaimageobject等)
  • 如果原始响应的大小超过3MB,则不适用$replace规则
  • $replace规则优先于其他基础规则(包括排除规则)。因此,如果一个请求对应两个不同的规则,其中一个规则带有$replace修饰符,则会应用此规则。
  • 带有$content$document修饰符的文档级排除规则会对匹配的请求禁用$replace规则
  • 其他文档级排除规则($generichide$elemhide$jsject修饰符)与$replace规则一起应用。这意味着您可以使用$replace规则修改页面内容,同时关闭页面中的修饰规则。

排除规则情况下,$replace值可以为空。有关详细信息,请参阅示例部分。

匹配单个请求的多个规则

如果有多条$replace规则匹配一个请求,我们会逐条应用。顺序按字母顺序定义

$replace语法

一般来说,$replace语法类似于在Perl中用正则表达式替换

replace = "/" regex "/" replacement "/" modifiers
  • regex — 正则表达式
  • replacement — 将用于替换与regex对应的字符串的字符串
  • modifiers — 正则表达式标志。例如,i-不敏感搜索,或者s-单行模式。

$replace值中,必须转义两个字符:逗号,$。使用\来转义它。例如,转义逗号如下所示:\,

$replace示例:

||example.org^$replace=/(<VAST[\s\S]*?>)[\s\S]*<\/VAST>/\$1<\/VAST>/

在这条规则中有三部分:

  • 正则表达式:(<VAST(.|\s)*?>)(.|\s)*<\/VAST>
  • 代替者:\$1<\/VAST> (请注意,$ 已经被转义了)
  • 正则表达式标志: i (不敏感搜索)

你可以在这里了解这些规则 如何运作

多个$replace规则示例:

  1. ||example.org^$replace=/X/Y/
  2. ||example.org^$replace=/Z/Y/
  3. @@||example.org/page/*$replace=/Z/Y/
  • 规则1和规则2都适用于发送到example.org的所有请求
  • 规则3禁用匹配 ||example.org/page/的请求,但是规则1仍然有效

禁用$replace规则示例:

  • @@||example.org^$replace 将会禁用所有匹配到||example.org^$replace规则
  • @@||example.org^$document@@||example.org^$content 将会禁用所有的来自于example.org页面的$replace规则,包括页面本身
csp

此修饰符完全更改了规则行为。如果将其应用于规则,则不会拦截匹配到的请求。相反,响应头将被修改。

为了使用这种类型的规则,需要对Content Security Policy安全层有基本的了解。

对于与$csp规则匹配的请求,我们将通过添加与$csp修饰符内容相等的附加内容安全策略来加强响应的安全策略。$csp规则独立于任何其他规则类型应用。除文档级排除规则外,其他基本规则对其没有影响(请参阅示例部分)

匹配单个请求的多个规则。
如果多个$csp规则与单个请求匹配,我们将分别应用它们。

csp语法

$csp值语法类似于Content Security Policy头语法

在排除规则的情况下,$csp的值可以为空。有关详细信息,请参阅示例部分

局限性

  1. 请注意,在 $csp 值中有几个禁止使用的字符: ,$
  2. $csp 规则支持限定的修饰符列表: domain, important, subdocument
  3. 带有 report-* 指令的规则视为无效

csp示例:

  • ||example.org^$csp=frame-src 'none' — 禁止example.org及其子域的所有frame
  • @@||example.org/page/*$csp=frame-src 'none' — 在与规则模式匹配的所有页面上禁用$csp修饰符完全匹配frame-src‘NONE’的所有规则。例如,上面的规则。
  • @@||example.org/page/*$csp — disables all the $csp rules on all the pages matching the rule pattern.
  • ||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: — disables inline scripts on all the pages matching the rule pattern.
  • @@||example.org^$document@@||example.org^$urlblock — 禁用匹配规则模式的所有页面上的所有$csp规则。
cookie

$cookie修饰符完全改变了规则行为。这个修饰符不会拦截请求,而是让我们隐藏或修改CookieSet-Cookie头部。

匹配单个请求的多个规则

如果有多条$cookie规则匹配一个请求,我们会逐条应用。

$cookie语法:

规则语法取决于我们是要拦截所有Cookie还是删除单个Cookie。可以使用maxAgesameSite修饰符更改规则行为。

  • ||example.org^$cookie=NAME;maxAge=3600;sameSite=lax — AdGuard每次在对example.org的请求中遇到名为NAME的cookie时,都会执行以下操作:

    • 将过期日期设置为当前时间加3600
    • 使Cookie使用Same-Site的”宽松“策略
  • ||example.org^$cookie — 拦截example.org设置的所有cookie,这相当于将maxAge设置为零
  • ||example.org^$cookie=NAME — 拦截名为NAME的单个Cookie
  • ||example.org^$cookie=/regular_expression/ — 拦截与给定正则表达式匹配的每个Cookie

重要提示:如果是正则表达式匹配,必须转义逗号,$两个字符。请使用\。例如,转义逗号如下所示:\,

$cookie规则不受常规排除规则@@的影响,除非是$document排除。要禁用$cookie规则,排除规则还需要有$cookie修饰符。它是这样运作的:

  • @@||example.org^$cookie — 取消拦截由 example.org设置的所有Cookie
  • @@||example.org^$cookie=NAME — 取消拦截名为Name的单个Cookie
  • @@||example.org^$cookie=/regular_expression/ — 取消拦截与给定正则表达式匹配的每个Cookie

局限性

$cookie规则支持限定的修饰符列表:domain~domainimportantthird-party~third-party

现实生活中的示例:

  • $cookie=__cfduid — 到处拦截CloudFlare的Cookie
  • $cookie=/__utm[a-z]/ — 到处拦截Google Analytics的Cookie
  • ||facebook.com^$third-party,cookie=c_user — 阻止Facebook跟踪您,即使您已登录
network

这基本上是一种防火墙类型的规则,允许完全拦截或解除拦截对指定远程地址的访问。

不同版本AdGuard的兼容性

从技术上讲,只有Windows、Mac和Android版的AdGuard才能使用这种类型的规则。

  1. $network规则仅匹配IP地址!您不能使用它来拦截或解除拦截对域的访问。
  2. 要匹配IPv6地址,必须使用折叠的语法,例如使用[2001:4860:4860::8888]$network代替[2001:4860:4860:0:0:0:0:8888]$network
  3. 白名单$network规则使AdGuard将数据绕过到匹配的端点,例如,根本不会有进一步的过滤。

network示例:

  • 174.129.166.49:3478^$network — 阻止访问 174.129.166.49:3478 (但不阻止访问 174.129.166.49:34788)
  • [2001:4860:4860::8888]:443^$network — 阻止访问 [2001:4860:4860::8888]:443.
  • 174.129.166.49$network — 阻止访问 174.129.166.49:*.
  • @@174.129.166.49$network — 使AdGuard将数据绕过端点。不会应用任何其他规则。
app

此修饰符允许您将规则覆盖范围缩小到特定应用程序(或应用程序列表)。这在Windows和Mac上可能不太重要,但在手机上非常重要,其中一些过滤规则必须是特定于应用程序的。

  • Android — 使用APP的包名 (例如 org.example.app)
  • Windows — 使用进程名称(例如 chrome.exe)
  • Mac — 使用进程名称 (例如 firefox-bin).

app示例:

  • ||baddomain.com^$app=org.example.app —屏蔽来自com.adGud.androidAndroid APP中与指定地址匹配的请求的规则
  • ||baddomain.com^$app=org.example.app1|org.example.app2 — 规则相同,但org.example.app1org.example.app2应用都适用。

如果希望规则不应用于某些应用程序,请以~符号应用程序名称的开头

app~示例:

  • ||baddomain.com^$app=~org.example.app — 屏蔽除org.example.app外,从任何APP发送的与指定地址匹配的请求的规则则,||baddomain.com^$domain=~org.example.app1|~org.example.app2 — 同上,但现在排除了org.example.app1org.example.app2两个APP

修饰规则

顾名思义,修饰规则不是用来阻止广告请求的,而是用来改变页面外观的。它们可以隐藏元素,甚至可以转换页面的整体样式。

使用修饰规则需要HTML和CSS的基本知识。因此,如果您想了解如何制定这样的规则,我们建议您熟悉本文档

元素隐藏规则

元素隐藏规则用于隐藏网页中的元素,类似于对选中的元素应用{display:None;}样式。

元素隐藏规则语法

rule = [domains] "##" selector
domains = [domain0, domain1[, ...[, domainN]]]
  • selectorCSS 选择器,定义要隐藏的元素。
  • domains — 规则的域限制

如果要将规则应用区域限制为某些域,只需输入它们,用逗号分隔即可。例如:example.org,example.com##selector

需要注意的是,该规则同样适用于example.orgexample.com的所有子域名。

如果您不想将规则应用于某些域名,请使用~符号作为域名的开头。例如:~example.org##selector.

您可以在单个规则中使用这两种方法。例如example.org,~subdomain.example.org##domain 将会在 example.org 及其所有子域运作, 除了 subdomain.example.org.

请注意

元素隐藏规则彼此不依赖。如果过滤器中有example.org##selector规则,并且您添加了~example.org##selector,则这两个规则将独立应用。

元素隐藏规则示例

  • example.com##.textad — 在example.com及其所有子域中隐藏class名为textaddiv元素
  • example.com,example.org###adblock - hides an element with attribute id equals adblock at example.com, example.org and all subdomains.
  • ~example.com##.textad — 在除example.com及其所有子域外的所有域名中隐藏class名为textaddiv元素

元素隐藏规则例外

Exceptions可以禁用特定域上的某些规则。它们与通常的排除规则非常相似,但是您必须使用#@#而不是##

例如,过滤器中有一条规则:

##.textad

如果你想对 example.com禁用, 你可以创建排除规则:

example.com#@#.textad

我们建议仅在无法更改隐藏规则本身的情况下才使用此类例外。在其他情况下,最好使用域限制更改原始规则

请注意

没有任何特定域的排除规则没有意义,将被忽略

修饰CSS规则

有时,简单地隐藏一个元素并不足以处理广告。例如,阻止广告元素只会破坏页面布局。在这种情况下,AdGuard可以使用比隐藏规则灵活得多的规则。使用此规则,您基本上可以向页面添加任何CSS样式

局限性

禁止使用导致加载任何资源的样式。基本上,这意味着您不能在样式中使用任何<url>类型值。

修饰CSS规则语法

rule = [domains] "#$#" selector "{" style "}"
domains = [domain0, domain1[, ...[, domainN]]]
  • selectorCSS 选择器,定义我们要将样式应用到的元素
  • domains — 规则的域限制
  • style — 要应用于选定元素的CSS样式。

修饰CSS规则示例

example.com#$#body { background-color: #333!important; }

这条规则将对example.com及其所有子域的body元素应用back-color:#333!Important;样式

CSS隐藏规则例外

与元素隐藏一样,有一类规则可以禁用特定域的选定CSS样式规则。
排除规则大同小异,只需要将 #$# 改为 #@$#即可

例如,过滤器中有一条规则:

#$#.textad { visibility: hidden; }

如果你想对 example.com禁用, 你可以创建排除规则:

example.com#@$#.textad { visibility: hidden; }

我们建议仅在无法更改CSS规则本身的情况下才使用此类例外。在其他情况下,最好使用域限制更改原始规则

扩展CSS选择器

CSS3.0并不足以屏蔽广告。为了解决此问题,AdGuard通过添加对新伪元素的支持来扩展CSS功能。为了使用扩展的CSS选择器,我们开发了一个单独的开源模块.

向后兼容性

在普通过滤器中,我们使用所谓的向后兼容语法。问题是,扩展的伪类可能会破坏先前版本的AdGuard或其他不支持扩展CSS的广告拦截器中的美化规则。例如,可以使用[-ext-has=“selector”]属性来代替伪类:has(Selector)

应用区域

扩展选择器可以在任何修饰规则中使用,无论它们是元素隐藏规则还是修饰CSS规则。

扩展CSS规则语法

不管您在规则中使用的是什么CSS伪类,您都可以使用特殊标记来使这些规则使用“扩展CSS”引擎。建议将这些标记用于所有“扩展CSS”修饰规则,以便更容易找到它们

  • #?# — 用于元素隐藏 (#@?# — 用于排除 )
  • #$?# — 用于CSS注入 (#@$?# — 用于排除)

扩展CSS规则示例:

  • example.org#?#div:has(> a[target="_blank"][rel="nofollow"]) —此规则会拦截所有子类的链接中包含 [target="_blank"][rel="nofollow"] 属性的div元素,该规则仅对example.org及其所有子域名有效
  • example.com#$?#h3:contains(cookies) { display: none!important; } — 此规则将为所有包含cookies字符串的h3元素设置样式display:None!Important。该规则仅对example.com及其所有子域名有效。
  • example.net#?#.banner:matches-css(width: 360px) — 此规则将拦截所有包含width:360px样式属性的.banner元素。该规则仅对example.net及其所有子域名有效。
  • example.net#@?#.banner:matches-css(width: 360px) — 此规则将禁用上一规则

请注意,现在您可以使用如下规则使用ExtCss引擎应用简单选择器:

#?#div

伪类:has()

CSS4.0规范草案描述了伪类:has。不幸的是,浏览器还不支持它

:has() 语法:

:has(selector)

向后兼容语法:

[-ext-has="selector"]

支持同义词以提高兼容性::-abp-has, :if

伪类:has()选择包含适合selector的元素

:has() 示例:

选择一个子元素的classbanner的所有div元素

HTML 代码

<div>Do not select this div</div>
<div>Select this div<span class="banner"></span></div>

选择器

div:has(.banner)

向后兼容语法

div[-ext-has=".banner"]

伪类:if-not()

这个伪类基本上是:not(:has())的快捷方式。ExtendedCss支持它,以便与某些筛选器订阅更好地兼容,但不建议在AdGuard筛选器中使用它。其基本原理是,总有一天浏览器会添加:has原生支持,但这永远不会发生在这个伪类上。

伪类:contains()

这个伪类原则非常简单:它允许选择包含指定文本或内容与指定正则表达式匹配的元素。需要注意的是,这个伪类使用的是innerText元素属性进行匹配(而不是innerHTML)。

:contains() 语法:

// 按纯文本匹配
:contains(text)

// 按正则表达式匹配
:contains(/regex/)

向后兼容语法:

// 按纯文本匹配
[-ext-contains="text"]

// 按正则表达式匹配
[-ext-contains="/regex/"]

支持的同义词以实现更好的兼容性: :-abp-contains, :has-text.

:contains() 示例:

选择所有包含banner文本的div元素

HTML 代码:

<div>Do not select this div</div>
<div id="selected">Select this div (banner)</div>
<div>Do not select this div <div class="banner"></div></div>

选择器:

// 按纯文本匹配
div:contains(banner)

// 按正则表达式匹配
div:contains(/this .* banner/)

向后兼容语法:

// 按纯文本匹配
div[-ext-contains="banner"]

// 按正则表达式匹配
div[-ext-contains="/this .* banner/"]

需要注意的是,本例中只会选择id=selecteddiv,因为下一个元素不包含任何文本(banner是代码的一部分,不是文本)

伪类:matches-css()

这些伪类允许根据元素的当前样式属性选择元素。这个伪类的工作基于使用window.getComputedStyle函数

:matches-css() 语法:

/* 元素样式匹配 */
selector:matches-css(property-name ":" pattern)

/* ::before伪类元素样式匹配 */
selector:matches-css-before(property-name ":" pattern)

/* ::after伪类元素样式匹配 */
selector:matches-css-after(property-name ":" pattern)

向后兼容语法

selector[-ext-matches-css="property-name ":" pattern"]
selector[-ext-matches-css-after="property-name ":" pattern"]
selector[-ext-matches-css-before="property-name ":" pattern"]
property-name

要检查元素的CSS属性的名称

pattern

这可以是使用与基本URL过滤规则中相同的简单通配符匹配的值模式,也可以是正则表达式。对于这种类型的匹配,AdGuard始终以不区分大小写的方式进行匹配。

对于正则表达式,模式类似于/regex/

  • 对于非正则表达式模式,,必须未转义,因为我们要求在过滤规则中对它们进行转义。
  • 对于正则表达式模式,应该转义",\因为我们手动转义Extended-css-selector.js中的那些。

:matches-css() 示例:

选择所有::before伪类包含指定内容的div元素

HTML 代码:

<style type="text/css">
    #to-be-blocked::before {
        content: "Block me"
    }
</style>
<div id="to-be-blocked" class="banner"></div>
<div id="not-to-be-blocked" class="banner"></div>

选择器:

// 简单匹配
div.banner:matches-css-before(content: block me)

// 正则匹配
div.banner:matches-css-before(content: /block me/)

向后兼容语法:

// 简单匹配
div.banner[-ext-matches-css-before="content: block me"]

// 正则匹配
div.banner[-ext-matches-css-before="content: /block me/"]

选择器调试模式

有时,您可能需要检查给定选择器或样式表的性能。为了不与javascript直接交互,可以使用特殊的debug样式属性。当ExtendedCss满足此属性时,将根据debug值为单个选择器或所有选择器启用debug模式。

调试单个选择器

#$#.banner { display: none; debug: true; }

启用全局调试

#$#.banner { display: none; debug: global; }

测试扩展选择器

要将ExtendedCss加载到当前页,请在浏览器控制台中复制并执行以下代码:

!function(E,x,t,C,s,s_){C=E.createElement(x),s=E.getElementsByTagName(x)[0],C.src=t,
C.onload=function(){alert('ExtCss loaded successfully')},s.parentNode.insertBefore(C,s)}
(document,'script','https://AdguardTeam.github.io/ExtendedCss/extended-css.min.js')

或者,安装“ExtendedCssDebugger”用户脚本:点击访问

现在可以在全局范围内使用ExtendedCss构造函数,其方法ExtendedCss.query作为document ent.querySelectorAll

var selectorText = "div.block[-ext-has='.header:matches-css-after(content: Anzeige)']";

ExtendedCss.query(selectorText) // 返回与selectorText匹配的元素数组

HTML过滤规则

在大多数情况下,基础规则和修饰规则足以过滤广告。但有时需要在加载页面之前更改页面本身的HTML代码。这时候您需要HTML内容过滤规则。它们允许在浏览器加载页面之前指定要剪切的HTML元素

不同版本AdGuard兼容性

规则受适用于Windows、Mac、Android的AdGuard和AdGuard的Firefox插件支持。
这种类型的规则在其他浏览器的扩展中不起作用,因为它们不能修改网络级别的内容

HTML 过滤规则语法

rule = [domains] "$$" tagName [attributes]
domains = [domain0, domain1[, ...[, domainN]]]      
attributes = "[" name0 = value0 "]" "[" name1 = value2 "]" ... "[" nameN = valueN "]"
  • tagName — 元素的小写名称,例如divscript
  • domains — 规则中的域限制 ,与元素隐藏规则语法相似的原则
  • attributes — 限制元素选择的属性列表。name-属性名称,value-子字符串,这些包含在属性值中

HTML 过滤规则示例

HTML 代码

<script data-src="/banner.js"></script>

规则

example.org$$script[data-src="banner"]

该规则将删除所有具有data-src属性且包含banner子串的script元素。该规则仅对example.org及其所有子域名有效

特殊属性

除了通常的属性(值为检查的每个元素)外,还有一组特殊属性可以更改规则的工作方式。下面是这些属性的列表:

tag-content

这是最常用的特殊属性。它限制选择innerHTML代码包含指定子字符串的元素

例如,让我们看一下这段HTML代码:

<script type="text/javascript">
    document.write('<div>banner text</div>" />');
</script>

以下规则将删除代码中所有带有banner子字符串的script元素:

$$script[tag-content="banner"]

嵌套元素

如果我们要处理多个嵌套元素,并且它们都属于相同的HTML过滤规则,则它们都将被删除

wildcard

这个特殊属性的作用类似于tag-content,允许您检查文档的innerHTML代码。规则将检查元素的Html代码是否适合Search pattern)

示例:

$$script[wildcard="*banner*text*"]

它将检查元素的代码是否包含两个连续的子字符串bannertext

max-length

指定HTML元素内容的最大长度。如果设置了此参数,并且内容长度超过该值,则规则不适用于元素

默认设定

如果不指定该参数,则认为max-Length为8192。

示例:

$$div[tag-content="banner"][max-length="400"]

此规则将删除代码包含子banner且长度不超过400个字符的所有div元素

min-length

指定HTML元素内容的最小长度。如果设置了此参数,并且内容长度小于预设值-则规则不适用于元素

示例:

$$div[tag-content="banner"][min-length="400"]

此规则将删除代码包含子banner且长度超过400个字符的所有div元素

HTML 排除过滤规则

与隐藏规则类似,有一种特殊类型的规则可以禁用特定域的选定HTML过滤规则
语法相同,只需将$$改为$@$即可。

例如,过滤器中有一条规则:

$$script[tag-content="banner"]

如果你想在 example.com禁用它,可以创建排除规则:

example.com$@$script[tag-content="banner"]

JavaScript规则

AdGuard支持一种特殊类型的规则,允许您将任何javascript代码注入网站页面。

限制

请注意,此类规则仅适用于可信过滤器。此类别包括您自己的用户筛选器和AdGuard团队创建的所有筛选器。

JavaScript规则语法

rule = [domains]  "#%#" script
  • domains — 规则的域限制 ,与元素隐藏规则类似
  • script — 任意javascript代码在一个字符串中

JavaScript规则示例

  • example.org#%#window.__gaq = undefined; — 在example.org和所有子域的所有页面上执行代码window.__gaq=unfined;

JavaScript排除规则

与隐藏规则类似,有一种特殊类型的规则可以禁用特定域的选定javascript规则
语法相同,只需将#%#改为#@%#即可

例如,过滤器中有一条规则:

#%#window.__gaq = undefined;

如果你想在 example.com禁用它,可以创建排除规则:

example.com#@%#window.__gaq = undefined;

过滤器维护人员的信息

如果您维护AdGuard已知的第三方筛选器,您可能会对本节中提供的信息感兴趣。请注意,提示将仅应用于已注册的筛选器。如果该筛选器存在于已知筛选器索引中,则认为该筛选器已由AdGuard注册和识别。如果您希望注册您的筛选器,请将问题提交给AdGuardFilters repo

预处理指令

我们提供多个预处理器指令,过滤器维护人员可以使用这些指令来提高与不同广告拦截器的兼容性

语法

!#if condition
Anything goes here
!#include URL_or_a_relative_path
!#endif
  • !#if, !#endif — 过滤器维护人员可以使用这些条件根据广告拦截器类型提供不同的规则
  • condition — 就像在一些流行的编程语言中一样,预处理条件基于广告拦截器声明的常量。广告拦截器作者自己定义他们声明的确切常量
  • !#include — 此指令允许将指定文件的内容包括到筛选器中

条件判断

当广告拦截器遇到!#if指令,最后是!#endif指令时,只有在指定的条件为真时,它才会编译指令之间的代码。条件判断支持所有基本逻辑运算符。

示例:

!#if (adguard && !adguard_ext_safari)
||example.org^$third-party
!#endif

引入一个文件

!#include 指令只支持来自同一来源的文件,以确保过滤器维护程序控制指定的文件。包含的文件还可以包含预处理器指令(甚至其他!#include指令)

广告拦截器应考虑递归!#include的情况,并实现保护机制。

示例

过滤器URL: https://example.org/path/filter.txt

!
! 有效的 (相同来源):
!#include https://example.org/path/includedfile.txt
!
! 有效的 (相对路径):
!#include /includedfile.txt
!#include ../path2/includedfile.txt
!
! 无效的 (其他来源):
!#include https://example.com/path/includedfile.txt

备注

  • 如果未找到引入的文件或该文件不可用,则整个过滤器更新会失败
  • !#if指令开头的条件指令必须以!#endif指令显式终止
  • 空格很重要, !#if 是有效的指令, 而 !# if 不是

特定于管理员的

  • 预处理器指令中的任何错误都将导致AdGuard无法执行过滤器更新,就像过滤器URL不可用一样
  • 预处理器指令可以在用户过滤器(或自定义本地过滤器)中使用,应为本地过滤器禁用同源限制

我们要声明哪些常量

  • adguard — 声明总是如此,让维护人员知道这是AdGuard产品之一,在95%的情况下应该足够了。

当您只需要某个规则在特定产品中工作(或不工作)时,某些极少数情况下的特定于产品的常量:

  • adguard_app_windows -- AG for Windows
  • adguard_app_mac -- AG for Mac
  • adguard_app_android -- AG for Android
  • adguard_app_ios -- AG for iOS
  • adguard_ext_chromium -- AG browser extension for Chrome
  • adguard_ext_firefox -- AG browser extension for Firefox
  • adguard_ext_edge -- AG browser extension for Edge
  • adguard_ext_safari -- AG browser extension for Safari
  • adguard_ext_opera -- AG browser extension for Opera
  • adguard_ext_android_cb -- AG content blocker for Samsung/Yandex

特殊情况:ext_ublock。此常量是在FiltersRegistry,编译过滤器的uBlock版本时声明的

提示

“提示”是对服务器端使用的过滤器编译器的特殊注释和指令(请参阅FiltersRegistry)

提示语法

!+ HINT_NAME1(PARAMS) HINT_NAME2(PARAMS)

请注意,您可以应用多个提示

禁止优化提示

对于大型过滤器,AdGuard编译了两个版本:完全版和优化版。优化版本要小得多,并且不包含根本不使用或很少使用的规则。有关规则优化的更多信息,您可以在这篇文章.]中找到

英语过滤器的优化版本示例: 点击访问

示例:

此规则将不会优化:

!+ NOT_OPTIMIZED
||example.org^

此规则不会进行优化,仅适用于Android:

!+ NOT_OPTIMIZED PLATFORM(android)
||example.org^

PLATFORM和NOT_PLATFORM提示

指定哪些平台可以应用此规则。现有平台列表:

  • windows - 示例:Windows的英语筛选器 - 点击访问
  • mac - 示例:Mac的英语过滤器 - 点击访问
  • android - 示例:Android英语过滤器 - 点击访问
  • ios - 示例:iOS的英语过滤器 - 点击访问
  • ext_chromium - 示例:适用于Chrome的AdGuard浏览器扩展 - 点击访问
  • ext_ff - 示例:适用于Firefox的AdGuard浏览器扩展 - 点击访问
  • ext_edge - 示例:适用于Edge的AdGuard浏览器扩展 - 点击访问
  • ext_opera - 示例:适用于Opera的AdGuard浏览器扩展 - 点击访问
  • ext_ublock - 示例:uBlock源 - 点击访问
  • ext_safari - 示例:适用于Safari的AdGuard浏览器扩展 - 点击访问
  • ext_android_cb - 示例:AdGuard内容阻止程序 - 点击访问

示例:

此规则仅适用于Windows、Mac和Android:

!+ PLATFORM(windows,mac,android)
||example.org^

此规则将适用于除Safari扩展、iOS和Android内容阻止程序之外的所有平台:

!+ NOT_PLATFORM(ext_safari, ext_android_cb, ios)
||example.org^

祝您在创建过滤器时好运!

我们祝您好运,创建您自己的广告过滤器。

如果您需要关于如何正确创建您自己的过滤器的建议,我们的论坛有一个专门的部分介绍如何编写您自己的过滤规则。


版权属于:LeeYD · Blog
本文标题:AdGuard 语法规则——如何创建属于你自己的广告过滤器
本文链接:https://www.leeyiding.com/archives/50/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 4.0 许可协议
若转载本文,请标明出处并告知本人

返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码
添加新评论

打卡

已有 1 条评论
  1. [...]AdGuard 语法规则 —— 如何创建属于你自己的广告过滤器[...]