用于处理 Adblock Plus 过滤器列表的库。
项目描述
此存储库包含一个用于处理 Adblock Plus 过滤器列表的库、一个用于呈现过滤器列表之间差异的脚本,以及用于将 Adblock Plus 过滤器列表从创作的形式构建为适合于消费的格式的脚本广告拦截软件(又名渲染)。
<nav class="contents" id="contents" role="doc-toc">内容
</nav>安装
先决条件:
Linux、Mac OS X 或 Windows(任何现代 Unix 也应该可以工作),
Python(2.7 或 3.5+),
点。
安装:
$ pip install --upgrade python-abp
过滤器列表的呈现
过滤器列表最初是在相对较小的部分中创作的,重点是特定类型的过滤器,与特定主题相关或与特定地理区域相关。我们将这些部分称为过滤器列表片段(或仅称为片段),以将它们与 Adblock Plus 等广告拦截软件使用的完整过滤器列表区分开来。
渲染是将过滤器列表片段组合成过滤器列表的过程。它从一个片段开始,可以包含其他片段等等。生成的过滤器列表标有版本和时间戳。
Python-abp 包含一个可以执行此操作的脚本,称为flrender:
$ flrender fragment.txt filterlist.txt
这将获取 fragment.txt 中的顶级片段,渲染它并将其保存到filterlist.txt。
flrender脚本也可以通过仅指定fragment.txt来使用:
$ flrender fragment.txt
在这种情况下,渲染结果将被发送到stdout。此外,当它在没有位置参数的情况下运行时:
$ flrender
它将从stdin读取并将结果发送到stdout。
片段可能会引用应该包含在其中的其他片段。引用有两种形式:http(s) 包含和本地包含:
%include http://www.server.org/dir/list.txt% %include easylist:easylist/easylist_general_block.txt%
http 包含包含将在引用点获取和插入的 URL。本地包含包含 easylist 存储库中的路径。 flrender需要能够在本地文件系统上找到存储库的副本。我们使用-i选项将其指向正确的目录:
$ flrender -i easylist=/home/abc/easylist input.txt output.txt
现在,上面引用的本地包含将解析为: /home/abc/easylist/easylist/easylist_general_block.txt ,并且将从该文件加载片段。
包含在渲染期间使用的过滤器列表片段的目录称为源。它们通常是包含过滤器列表片段的存储库的工作副本。每个源都由一个名称标识:这是包含指令中“:”之前的部分,它应该与-i选项中“=”之前的部分相同。
常用来源具有普遍接受的名称。例如,主 EasyList 存储库称为easylist。如果您不知道呈现某些列表所需的所有源名称,只需运行flrender,它将报告缺少的内容:
$ flrender easylist.txt output/easylist.txt Unknown source: 'easylist' when including 'easylist:easylist/easylist_gener al_block.txt' from 'easylist.txt'
您可以将必要的存储库克隆到本地目录并相应地添加-i 选项。
生成差异
差异允许运行 Adblock Plus 等广告拦截软件的客户端逐步更新过滤器列表,而不是在每次更新期间下载完整列表的新副本。这是为了减少更新过滤器列表时使用的资源量(例如网络数据、内存使用、电池消耗等),允许客户端使用更少的资源更频繁地更新其列表。
python-abp 包含一个名为fldiff的脚本,它将查找最新过滤器列表和任意数量的先前过滤器列表之间的差异:
$ fldiff -o diffs/easylist/ easylist.txt archive/*
其中-o diffs/easylist/是应该写入差异的(可选)输出目录,easylist.txt是过滤器列表的最新版本,archive/*是所有归档过滤器列表所在的目录。当这样调用时,shell 应该自动扩展archive/* 目录,分别为脚本提供每个文件名。
在上面的示例中,每个归档list[version].txt的输出将被写入diffs/diff[version].txt。如果省略输出参数,差异将被写入当前目录。
该脚本生成三种类型的行,如技术规范中所述:
表格的特别评论!<名称>:[ <值>]
添加了表单+ <filter-text>的过滤器
删除了表单的过滤器- <filter-text>
库 API
python-abp 也可以用作解析过滤器列表的库。例如读取过滤器列表(我们在这里使用 Python 3 语法,但 API 相同):
from abp.filters import parse_filterlist
with open('filterlist.txt') as filterlist:
for line in parse_filterlist(filterlist):
print(line)
如果filterlist.txt包含此过滤器列表:
[Adblock Plus 2.0] ! Title: Example list abc.com,cdf.com##div#ad1 abc.com/ad$image @@/abc\.com/
输出将类似于:
Header(version='Adblock Plus 2.0')
Metadata(key='Title', value='Example list')
EmptyLine()
Filter(text='abc.com,cdf.com##div#ad1', selector={'type': 'css', 'value': 'div#ad1'}, action='hide', options=[('domain', [('abc .com', True), ('cdf.com', True)])])
Filter(text='abc.com/ad$image', selector={'type': 'url-pattern', 'value': 'abc.com/ad'}, action='block', options=[('image', True)])
Filter(text='@@/abc\\.com/', selector={'type': 'url-regexp', 'value': 'abc\\.com'}, action='allow', options=[])
abp.filters模块还导出了一个较低级别的函数,用于解析过滤器列表的各个行:parse_line。它返回一个解析的行对象,就像parse_filterlist返回的迭代器中的项目一样。
有关库 API 的更多信息,请使用abp.filters上的help()及其在交互式 Python 会话中的内容,阅读文档字符串,或查看一些使用示例的测试。
过滤器块
可以使用abp.filters.blocks 中的 to_blocks函数对由注释分隔的过滤器块进行进一步处理:
from abp.filters import parse_filterlist
from abp.filters.blocks import to_blocks
with open(fl_path) as f:
for block in to_blocks(parse_filterlist(f)):
print(json.dumps(block.to_dict(), indent=2))
使用abp.filters.blocks上的help()获取更多信息。
测试
python-abp的单元测试位于/tests目录中。Pytest 用于在开发过程中快速运行测试。Tox用于在不同环境(Python 2.7、Python 3.5+ 和 PyPy)中进行测试和代码质量报告。
使用 tox 获取单元测试和测试覆盖率的综合报告:
$ tox
发展
添加新功能时,为它添加测试(最好是首先)。如果某些代码在某个版本的 Python 上永远无法访问,则可以通过添加注释来免除覆盖测试,例如#pragma: no py2 cover。
所有公共函数、类和方法都应具有符合 NumPy/SciPy 文档指南的文档字符串。一个例外是不期望用户实例化的类的构造函数(例如异常)。
将库与 R 一起使用
安装
python-abp可以从 PyPI 或源代码直接安装到系统或虚拟环境中。
要从 PyPI 安装:
$ pip install -U python-abp
要从本地源安装,请克隆存储库,然后:
$ pip install -U /path/to/python-abp
要使用虚拟环境,必须首先创建它。Python 2 和 3 使用不同的脚本来创建 virtualenv。
在 Python 2 中:
$ virtualenv env
在 Python 3 中:
$ python3 -m venv env
然后,使用 virtualenv 的 pip 版本从 PyPI 或源代码安装 python-abp(如上所示):
$ env/bin/pip install -U python-abp
用法
在 R 中,python-abp可以使用reticulate导入:
> library(reticulate)
> use_virtualenv(<s>"~/path/to/env"</s>, required=TRUE) # If using virtualenv
> abp <- import(<s>"abp.filters.rpy"</s>)
现在您可以使用带有abp$functionname的函数,例如 abp$line2dict("@@||g.doubleclick.net/pagead/$subdocument,domain=hon30.org")
有关网状包的更多信息,请参阅他们的指南。