суббота, 6 марта 2010 г.

Создание фильтров для privoxy

Для создания фильтров в Privoxy используется синтаксис регулярных выражений. Регулярные выражения в полном объеме изучать конечно не стоит, но в общих чертах ориентироваться необходимо.

Терминология

Фильтр — фрагмент кода, используемый Privoxy для фильтрации контента. Фильтр может состоять из одного или нескольких шаблонов.

Шаблон — фрагмент кода, составленый на основании синтаксиса регулярных выражений. Он непосредственно указывает то, что нужно искать и на что это нужно заменить.

Регулярные выражения (regular expressions, RegExp, RegEx) — формальный язык поиска и замены в текстовых строках.

Создание косметических фильтров, основанных на внедрении кода CSS.

Скрытие фрагментов html страницы широко используется как в Opera, так и в AdBlock. Каким образом это реализуется в Privoxy мы сейчас и рассмотрим.

Для начала в user.filter запишем строчку:

FILTER: site-specific-u Site specific user filters

этой строчкой мы создаем «site-specific-u» фильтр. Все, что последует после этой строчки и до объявления следующего фильтра будет принадлежать «site-specific-u» фильтру.

Шаблон CSS фильтра прост

s@(</head>)@\n<style type="text/css">\n\
[Стиль 1], [Стиль 2], [Стиль 3], [Стиль ...], [Стиль n]\n\
{ display: none !important; outline:1px solid !important }\n\
</style>\n$1@si

пользователю остается только воспользоваться консолью разработчика, имеющегося практически в каждом вменяемом браузере, определиться какой стиль управляет отображением рекламного блока и вписать его в шаблон фильтра. К примеру, рекламный блок на images.google.ru управляется стилем id*="tads" (<div id="tads">), вписав который в шаблон фильтра мы избавимся от рекламного блока навсегда.

Шаблон для скрытия рекламного блока на images.google.ru будет выглядеть следующим образом:

#images.google.ru
s@(</head>)@\n<style type="text/css">\n\
[id*="tads"]\n\
{ display: none !important; outline:1px solid !important }\n\
</style>\n$1@si

Остается только активировать этот фильтр для images.google.ru и все. Шаблоны на основе CSS для других сайтов делаются аналогично.

Создание фильтров контента

Все шаблоны фильтров Privoxy имеют следующее строение:

s/Поиск/Замена/Модификаторы

Модификаторы определяют режим поиска:
g — поиск и замена производится до тех пор, пока условие соблюдается.
i — производится регистронезависимый поиск/замена
s — производится многострочный поиск/замена

Рассмотрим простой вариант, к примеру, нам нужно удалить следующий фрагмент:

<a href="http://site.com/promo/2421.htm"><img src="/img/2421.jpg" /></a>

Шаблон будет выглядеть следующим образом:

s@<a\s+[^>]*site\.com/promo/[^>]*.*</a>@@sig

где:
«<a\s+» - начало тега «а» с гарантированным пробелом
«[^>]*» - любое количество символов за исключением границы открывающего тега «a»
«site\.com/promo/» - ключевой фрагмент адреса
«.*</a>» - любое количество символов до закрывающего тега «a»

Отсутствие символов в замене говорит о том, что найденный шаблон будет удаляться полностью.
Модификаторы «sig» показывают, что поиск должен продолжаться много раз, быть многострочным и регистронезависимым.

Рассмотрим вариант немного сложнее — нам нужно удалить рисунок, но оставить ссылку с описанием из alt тега.

<a href="http://site.com/promo/2421.htm" alt="Promo links"><img src="/img/2421.jpg" /></a>

s@(<a\s+[^>]*site\.com/promo/[^>]*alt="([^"]*)[^>]*>).*(</a>)@$1Blocked: $2$3@sig

где:
в переменную $1 заносится весь открывающий тег «<a ...>»
в переменную $2 заносится содержимое тега «alt="..."»
в переменную $3 заносится закрывающий тег «</a>»

После все эти переменные используются в замене, вначале открывающий тег «<a ...>», затем текст, содержащийся в теге «alt="..."», а затем и закрывающий тег «</a>».

В итоге из графической ссылки мы получили обычную текстовую.

Самый сложный вариант — когда нам надо удалить из контента javascript с определенным ключевым словом.

Сложность состоит в том, что при обычной фильтрации может случиться так, что будет удалено все от открывающего тега первого скрипта до закрывающего тега последнего.

Решается все на редкость просто:
1.Помечается закрывающий тег каждого скрипта специальным символом.
2.Производится фильтрация, ограничением которой служит как раз этот специальный символ.
3.Удаляется из закрывающих тегов скриптов все специальные символы.

Фильтр будет состоять из трех шаблонов, функционал каждого из них описан выше:

s@</(script)@\e</$1@sig
s@<script[^\e]*?banner[^\e]*?\e</\script>@<!-- Blocked ad-script -->@sig
s@\e</(script)@</$1@sig

где «[^\e]*?» как раз и определяет любое количество символов до появления символа ограничения «\e» - обозначающего начало закрывающего тега.

Заключение.

Не стоит сразу бросаться на написание собственных фильтров, они становятся последним рубежом, когда обычная блокировка по URL (адресу) уже не помогает.

Комментариев нет: