Grab
Grab — это библиотека парсинга вебсайтов для языка Python. Обладает широким набором возможностей.
Основные области использования Grab:
- Извлечение данных с веб-сайтов (site scraping)
- Работа с сетевыми API
- Автоматизация работы с веб-сайтами, например, регистратор профилей на каком-либо сайте
Grab состоит из двух частей:
- Главный интерфейс Grab для создания сетевого запроса и работы с его результатом. Этот интерфейс удобно использовать в простых скриптах, где не нужна большая многопоточность, или непосредственно в python-консоли.
- Интерфейс Spider, позволяющий разрабатывать асинхронные парсеры. Этот интерфейс позволяет, во-первых, более строго описать логику парсера, во-вторых, разрабатывать парсеры с большим числом сетевых потоков.
Установка
[править]Автор библиотеки рекомендует сначала установить зависимость, а потом уже саму библиотеку. Grab нуждается в двух библиотеках: lxml и pycurl.
Windows
[править]Есть некоторые особенности для установки под Windows. Зависимости лучше скачать с http://www.lfd.uci.edu/~gohlke/pythonlibs/
Необходимо найти файл:
- lxml-2.3.3.win32-py2.6.exe
Вторая зависимость, это библиотека pycurl, которую лучше всего скачать с сайта http://grablib.org/ В ней исправлен баг с формированием неправильного post запроса.
Запустить командную строку cmd
Проще всего установить при помощи скрипта easy_install. В командной строке должно получиться что-то вроде этого:
C:\Python27\python.exe C:\Python27\Scripts\easy_install-2.7-script.py grab
Mac OS X
[править]В терминале написать.
sudo easy_install lxml
sudo easy_install -U Grab
sudo easy_install pycurl
Linux
[править]pip install pycurl lxml
pip install Grab
Примеры
[править]from grab import Grab
g = Grab(log_file='out.html')
g.go('yandex.ru')
Разбор программы
- Импорт модуля
- out.html - появится в корневой директории, где расположена ваша программа
- Указываете адрес, куда пройдет программа
Что в результате произойдёт? Grab пройдёт по указанному адресу и создаст файл out.html отладки в корневой директории. Вы можете его открыть, это обычный html.
Поиск на странице
[править]from grab import Grab
g = Grab(log_file='out.html')
g.go('yandex.ru')
g.search(u'яндекс')
Если текст будет найден, то ответ будет True.
Получаем текст
[править]from grab import Grab
g = Grab(log_file='out.html')
g.go('yandex.ru')
print g.xpath_text('//*')
В результате вы получите весь текст со страницы Yandex.
print g.xpath_text('//title')
Получите title страницы.
Часто требуется получения текста из одного элемента. Например, статус пользователя вконтакте или мониторинг цены товара (как промышленный шпион). Поставьте расширение для браузера firebug. Правой клавишей становитесь на тексте и выбираете Inspect element with Firebug.
Пару слов об XPath:
Многим новичкам непонятен, как работает XPath. Самый легкий вариант импортировать путь через Firebug, но в этом случае генерируется много мусора. XPath очень легкий, если понятен его принцип.
XPath расшифровывается как XML Path Language.
print g.xpath_text('//*')
Звёздочка означает импортировать весь текст.
print g.xpath_text('//div')
После двух слешей, вы можете указать из какого конкретно элемента импортировать. Если элемент пуст, то появится ошибка. Это не должно вас пугать, это не значит, что вы неправильно прописали синтаксис, это значит, что просто элемент пуст. Также еще важный момент xPath действует интеллектуально, он ищет элемент по всей странице. Найдёт даже если он в конце вебстраницы. Вы можете конкретизировать элемент. Эта та самая часть, которая путает многих начинающих.
print g.xpath_text('//h1')
print g.xpath_text('//h3')
print g.xpath_text('//ul[@class="tags"]')
print g.xpath_text('//div[@id="post_140164"]')
print g.xpath_text('//a[@class="post_title"]')
После двух слешей вы указываете сам элемент, ухо указывает на атрибут элемента. Например, в html коде написано так:
<div id="post_115825">
А в Грабе следовательно надо написать так:
print g.xpath_text('//div[@id="post_115825"]')
Если мы имеем дело с линком, значит вместо div пишем a. Если он имеет какой-то класс, то конкретизируем.
print g.xpath_text('//a[@class="post_title"]')
Значительную помощь нам оказывает Firebug или встроенный модуль анализа элементов в браузерах.
Получаем линк
[править]Если приведённый пример не сработает, это значит, что grab не может найти класс линка. Они часто меняются. Чтобы узнать новый класс, надо поставить расширение для браузера firebug. Правой клавишей становитесь на линк и выбираете Inspect element with Firebug.
from grab import Grab
import logging
logging.basicConfig(level=logging.DEBUG)
g = Grab()
g.go('python.org')
print g.xpath('//a[@class="reference external"]').get('href')
Мы получим первый линк из класса reference external. >>> /psf/license/
Для получения всех линков, надо писать цикл.
Парсинг файла
[править]Допустим у вас есть уже несколько сохранённых веб-страниц, вам нужно их распарсить.
data = open('my-file.html').read()
g = Grab(data)
Сообщения об ошибках
[править]- 400 Bad Request - может появиться при попытке подключения. Может означать, что исходящий запрос заблокирован вашим провайдером. Часто возникает при множественных запросах на разные домены.
- Error 413 (Request Entity Too Large)!! - провайдером заблокирован исходящий запрос.
- 400 Request Header Or Cookie Too Large - провайдером заблокирован исходящий запрос
Ссылки
[править]- http://grablib.org - официальный сайт библиотеки
- http://habrahabr.ru/post/127584/ - первая презентация библиотеки, приводятся полезные примеры.
- http://habrahabr.ru/post/139435/ - вторая статья, более расширенная.
- http://habrahabr.ru/post/134918/ - описание работы модуля Spider
- http://habrahabr.ru/post/142212/ - вторая статья по Spider
- http://habrahabr.ru/post/142288/ - третья статья по Spider
- http://groups.google.com/group/python-grab/ - группа обсуждения на google groups
- https://bitbucket.org/lorien/grab/overview - Исходники, можно следить за обновлениями.
- http://www.w3schools.com/xpath/xpath_syntax.asp - Документация по xPath
- https://addons.mozilla.org/en-US/firefox/addon/firefinder-for-firebug/ - Аддон позводяющий протестировать правильность выбранных селекторов для xPath