Полезные утилиты¶
В пакете grab.tools содержится множество различных вспомогательных утилит, которые оказываются полезными в разработке Grab и парсеров на основе Grab. Здесь приведён обзор наиболее важных утилит.
Пул заданий¶
Используя функцию work.make_work()
вы можете организовать выполнение множества заданий в параллельных тредах, причём количеством тредов можно управлять:
def worker(url):
g = Grab()
g.go(url)
return url, g.xpath_text('//title')
task_iterator = open('urls.txt')
for url, title make_work(worker, task_iterator, limit=5):
print url, title
Обратите внимание, что вы можете передавать не только статический список заданий, но и итератор. Результат работы функции work.make_work()
выполнен также в виде итератора. Если вы хотите использовать процессы, вместо тредов, вам нужна функция pwork.make_work()
. Она аналогична вышерассмотренной, за тем исключением, что она порождает не треды (threading.Thread), но процессы (multiprocessing.Process)
Блокировка файла¶
Для того, чтобы гарантировать то, что в любой момент времени выполняется только один экземпляр вашего парсера, можно использовать функцию lock.assert_lock()
. Её аргумент - путь до файла, который должен быть залочен. Если залочить файл не удаётся, функция генерирует исключение и программа прекращается. Естественно, в разных скриптах нужно лочить различные файлы.
Логирование Grab-активности в файл¶
Функция logs.default_logging()
настраивает logging-систему так, чтобы все сообщения библиотеки Grab направлялись в файл, по-умолчанию, это “/tmp/grab.log”. Удобно вызвать эту функцию в начале программы и наблюдать за активностью парсинга с помощью команды tail -f /tmp/grab.log, оставляя себе возможность выводить в консоль, где был запущен скрипт, более важные данные.
Фильтрация строк в файле¶
Функция files.unique_file()
читает строки из файла, оставляет уникальные строки и записывает их обратно в файл. Функция files.unique_host()
читайет список URL-строк из файла и оставляет только строки с уникальным hostname, далее записывает строки обратно в файл.
Обработка HTML¶
html.decode_entities()
- преобразовывает все &XXX; и &#XXX; последовательности в тексте в уникод.html.strip_tags()
- вырезает все тэги из текста простым регекспом.html.escape()
- преобразовывает ряд “небезопасных” HTML-символов в “&xxx;” последовательности.
Работа с LXML-элементами¶
lxml_tools.get_node_text()
- возвращает текстовое содержимое элемента и всех его под-элементов, за ислючением элементов script и style.lxml_tools.find_node_number()
- возвращает первое найденное число в текстовом содержимом переданного элемента.
Работа с регулярными выражениями¶
Функция rex.rex()
позволяет искать регулярное выражение. Вы можете передать ей как скомпилированный объект регулярного выражения, так и просто текст из которого будет построен объект регулярного выражения. Объекты регулярных выражений кэшируются, так что вам не нужно беспокоитсья о том, что выражение будет перекомпилироваться. Если выражение не найдено, функция rex.rex()
сгенерирует grab.error.DataNotFound
исключение. Вы можете изменить это поведение, передав в аргументе default значение, которое нужно вернуть по-умолчанию:
>>> from grab.tools import rex
>>> import re
>>> rex.rex('*** foo +++', re.compile('\w+')).group(0)
'foo'
>>> rex.rex('*** foo +++', '\w+').group(0)
'foo'
>>> rex.rex('***', '\w+')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/grab/tools/rex.py", line 44, in rex
raise DataNotFound('Could not find regexp: %s' % regexp)
grab.error.DataNotFound: Could not find regexp: <_sre.SRE_Pattern object at 0xb83c10>
>>> rex.rex('***', '\w+', default='default value')
'default value'
Функция rex.rex_list()
вернёт список всех найденных регулярных выражений. Функция rex.rex_text()
найдёт указанный текст и затем вырежет из него все тэги. Функция rex.rex_text_list()
вернёт список всех найденных текстовых фрагментов с вырезанными тэгами.
Работа с текстом¶
text.find_number()
- поиск числа в строкеtext.drop_space()
- удаление всех пробелов в строкеtext.normalize_space()
- удаление начальных и конечных пробелов, приведение последовательности пробелов к одному пробелу.
Работа с http-заголовками¶
http.urlencode()
- сериализация словаря или списка пар в строку, которую можно отправить в GET или POST-запросе. В отличие от стандартного urllib.urlencode может обрабатывать unicode, None иgrab.upload.UploadFile
объекты.