Установка Grab
Доброго времени суток
понадобилось средство парсинга сайта, попытался установить grab, скачал обе зависимости. однако при написании import lxml.html
import pycurl
from grab import Grab
выдает ошибку: ImportError: No module named grab
подскажите пожалуйста как установить — таки grab
а то на официальном сайте нет такой информации
и вообще так и хочется задать вопрос разработчикам: неужели нельзя было сделать ОДИН файл который распаковывал-бы инсталер, который, в свою очередь, устанавливал-бы все необходимое. да и вообще почему-бы не встроить все эти библиотеки в питон. а то вечно надо что-то скачивать что-то искать. (я просто даже питон третий поставил параллельно со своим 2.7 но всеравно не помогло). к чему все эти сложности. Весь день убил и ничего не добился всеравно.
Python+grab
При попытке авторизоваться на mail.ru при помощи библиотеки grab. Логин указаны верно. Всю голову.
Не ставится Grab
Здравствуйте! 🙂 Дано: Windows 8.1 x64, Python 3.4.1 (MSC v.1600 64 bit (AMD64)), Grab 0.4.13.
Grab Python 3
Привет. Python 3.4. Установил Grab. Пытаюсь получить код любой странички( в примере жж) и вот что.
Grab: кодировка текста
Накидал парсер новостей с lenta.ru и gazeta.ru. Использовал grab 0.4.13. python 3.3.5 под w8.1.
поставьте pip. И устанавливайте модули из него
все сделал за исключением одного но:
я в основном пишу на работе поэтому прав администратора у меня нет, и посему перейти в папку с питоном я не могу, поэтому я перетащил установщик grab в папку открываемую cmd по умолчанию (User) и вобщем-то запустил её там. однако python setup.py install не сработало (файла такого нет) есть файл setup.py (его я собственно и установил setup.py install) в консольке написало много всего в том числе что установка завершена. однако при запуске выдало ошибку.
оу)) пришел сегодня с утреца и все заработало )))) таки нужно было просто комп перезагрузить как и посоветовал Паштет-кун блин. спасибо большое
ОЧЕНЬ помог!))) а то я с горя уже полез Лутца читать(( прочел про встроенные парсеры и вообще расстроился
Добавлено через 2 минуты
PATH это системная переменная
На правах антирекламы. Несколько слов о Grab, pycurl и культуре программирования.
В одном некоммерческом проекте понадобилось делать скрап определенных сайтов.
Воодушевленный публикациями типа http://ivan-shamaev.ru/python-grab/ и открытостью продукта http://grablib.org/, принялся пробовать Grab (Windows 7, Python 2.7, для развертывания на Google App Engine).
Почти сразу, дуриком получилась пробная сборка. Но рано радовался, повторить не удалось. В реальном проекте это ни разу не заработало.
Сначала постоянно лезло «не найден модуль pycurl» — http://stackoverflow.com/quest. -not-found. Была изучена документация, перепробованы десятки комбинаций софта и библиотек Python. Безуспешно.
Потом занялся инсталляциями Grab и pycurl из исходного кода и был неприятно удивлен большим количеством нелепых ошибок в предлагаемом продукте. Упс.
В итоге самостоятельно реализовал web crawler c использованием urllib и pyspider. От знакомства с Grab остался тяжелый осадок, жаль потраченных усилий и времени.
В чем причина широкого распространения в сети сырых неряшливых поделок?
Grab — python библиотека для парсинга сайтов
Что такое grab?
Это библиотека для парсинга сайтов. Её основные функции:
- Подготовка сетевого запроса (cookies, http-заголовки, POST/GET данные)
- Запрос на сервер (возможно через HTTP/SOCKS прокси)
- Получение ответа сервера и его первоначальная обработка (парсинг заголовков, парсинг cookies, определение кодировки документа, обработка редиректа (поддерживаются даже редирект в meta refresh тэге))
- Работа с DOM-деревом ответа (если это HTML-документ)
- Работа с формами (заполнение, автозаполнение)
- Отладка: логирование процесса в консоль, сетевых запросов и ответов в файлы
Далее я расскажу о каждом пункте более подробно. Для начала поговорим об инициализации рабочего объекта и подготовке сетевого запроса. Приведу пример кода, который запрашивает страницу с яндекса и сохраняет её в файл:
На самом деле параметр `log_file` предназначен для отладки — он указывает куда сохранить тело ответа для дальнейшего изучения. Но можно и для скачивания файла его использовать.
Мы увидели как можно отконфигурировать объкт Grab — прямо в конструкторе. А вот ещё варианты того же кода:
Резюмирую: можно задать конфигурацию Grab через конструктор, через метод `setup` или через методы `go` и `request`. В случае метода `go`, запрашиваемый URL можно передать позиционным аргументом, в других случаях нужно передавать его как именованный аргумент. Отличие методов `go` и `request` в том, что `go` требует обязательным первым параметром URL, в то время как request ничего не требует и использует URL, который мы задали ранее.
Помимо опции `log_file`, есть опция `log_dir`, которая невероятно облегчает отладку многошагового парсера.
Видите? Каждый запрос получил свой номер. Ответ на каждый запрос был записан в файл /tmp/[номер].html, также был создан /tmp/[номер].log файл, в котором записаны http-заголовки ответа. А что вообще делает вышеприведённый код? Он идёт на главную страницу яндекса. А затем делает бессмысленный POST-запрос на эту же страницу. Обратите внимание, что во втором запросе мы не указываем URL — по-умолчанию используется url предыдущего запроса.
Давайте рассмотрим ещё одну настройку Grab, предназначенную для отладки.
Мы сделали запрос к youporn.com. Опция `debug` включает запоминание заголовков исходящих запросов. Если мы в чём-то не уверены, можно посмотреть, что именно мы отослали на сервер. В аттрибуте `request_headers` сохранён словарь с ключами и значениями http-заголовков запроса.
Рассмотрим базовые возможности по составлению запросов.
Методы http-запроса
POST-запрос. Всё довольно просто. Укажите в опции `post` словарь с ключами и значениями. Grab автоматически изменит типа запроса на POST.
GET-запрос. Если явно не были заданы POST-данные или метод запроса, то Grab сгенерирует GET-запрос.
PUT, DELETE, HEAD методы. Теоритически всё будет работать, если вы зададите опцию method=’delete’, method=’put’ или method=’head’. Практически же я мало работал с этими методами и не уверен в их работоспособности.
Важное замечание о POST-запросах. Grab устроен так, что сохраняет все заданные опции и использует их в следующих запросах. Единственная опция, которую он не сохраняет — это `post` опция. Если бы он сохранял её, то в следущем примере вы бы отправили POST-запрос на второй URL, а это вряд ли то, что вы хотели:
Настройка http-заголовков
Теперь рассмотрим, как можно настраивать отправляемые http-заголовки. Просто задайте словарик заголовков опцией `headers`. По-умолчанию, Grab генерирует некоторые заголовки, чтобы больше быть похожим на браузер: Accept, Accept-Language, Accept-Charset, Keep-Alive. Их вы также можете менять опцией `headers`:
Работа с cookies
По-умолчанию, Grab сохраняет полученные cookies и отсылает их в следующем запросе. Вы получаете эмуляцию пользовательских сессий из коробки. Если вам это не нужно, отключите опцию `reuse_cookies`. Вы можете задать cookies вручную опцией `cookies`, она должна содержать словарик, обработка которого аналогична обработке данных, переданных в `post` опции.
Вы можете указать файл, который следует использовать как хранилище cookies, опцией `cookiefile`. Это позволит вам сохранять cookies между запусками программы.
В любой момент вы можете записать cookies Grab объекта в файл методом `dump_cookies` или загрузить из файла методом `load_cookies`. Чтобы очистить cookies Grab объекта используйте метод `clear_cookies`.
User-Agent
По-умолчанию, Grab претворяется настоящим браузером. У него есть список различных User-Agent строк, одна из которых выбирается случайным образом при создании Grab объекта. Конечно, вы можете задать свой User-Agent опцией `user_agent`.
Работа с прокси-сервером
Всё банально. В опции `proxy` нужно передать адрес прокси в виде «server:port», в опции `proxy_type` передаём её тип: «http», «socks4» или «socks5» Если ваши прокси требуют авторизации, используйте опцию `proxy_userpwd`, значение которой имеет вид «user:password».
Простейший поисковик прокси-серверов на базе Google поиска:
Работа с ответом
Допустим, вы сделали сетевой запрос с помощью Grab. Что дальше? Методы `go` и `request` вернут вам объект Response, который также доступен через аттрибут `response` объекта Grab. Вас могут заинтересовать следующие аттрибуты и методы объекта Response: code, body, headers, url, cookies, charset.
- code — HTTP-код ответа. Если ответ отличяется от 200-го, никаких ислючений не будет сгенерировано, имейте это в виду.
- body — это собственно тело ответа, исключая http-заголовки
- headers — а это заголовки в словарике
- url — может отличаться от исходного, если был редирект
- cookies — куки в словарике
- charset — кодировка документа, ищется в META тэге документа, также в Content-Type http-заголовке ответа и xml-декларации XML-документов.
Grab объект имеет метод `response_unicode_body`, который возвращает тело ответа, преобразованное в unicode, учтите, что HTML entities типа «&» не преобразовывается в уникодовые аналоги.
Response объект последнего запроса всегда хранится в аттрибуте `response` Grab объекта.
Работа с текстом ответа (grab.ext.text расширение)
Метод `search` позволяет установить присутствует ли заданная строка в теле ответа, метод `search_rex` принимает в качестве параметра объект регулярного выражения. Методы `assert_substring` и `assert_rex` генерируют DataNotFound исключение, если аргумент не был найден. Также в этом расширении находятся такие удобные функции как `find_number — ищет первое числовое вхождение, `drop_space` — удаляет любые пробельные символы и `normalize_space` — заменяет последовательности пробелов одним пробелом.
Работа с DOM-деревом (grab.ext.lxml расширение)
Подходим к самому интересному. Благодаря замечательной библиотеке lxml Grab предоставляет вам возможность работать с xpath-выражениями для поиска данных. Если очень кратко: через аттрибут `tree` вам доступно DOM-дерево с ElementTree интерфейсом. Дерево строится с помощью парсера библиотеки lxml. Работать с DOM-деревом можно используя два языка запросов: xpath и css.
Методы работы с xpath:
- xpath — вернуть первый элемент удовлетворяющий запросу
- xpath_list — вернуть все элементы xpath_text — вернуть текстовое содержимое элемента (и всех вложенных элементов)
- xpath_number — вернуть первое числовое вхождение из текста элемента (и всех вложенных элементов)
Если элемент не был найден, то функции `xpath`, `xpath_text` и `xpath_number` сгенеририруют DataNotFound исключение.
Функции `css`, `css_list`, `css_text` и `css_number` работают аналогично, за одним исключением, аргументом должен быть не xpath-путь, а css-селектор.
Формы (grab.ext.lxml_form расширение)
Когда я реализовал функциональность по автоматическому заполнению форм я был очень рад. Порадуйтесь и вы! Итак, есть методы `set_input` — заполняет поле с указанным именем, `set_input_by_id` — по значению аттрибута id, и `set_input_by_number` — просто по номеру. Эти методы работают с формой, которую можно задать руками, но обычно Grab сам угадывает правильно, с какой формой нужно работать. Если форма одна — всё понятно, а если несколько? Grab возьмёт ту форму, в которой больше всего полей. Чтобы задать форму вручную используйте метод `choose_form`. Методом `submit` можно отправить заполненную форму. Grab сам построит POST/GET запрос для полей, которые мы не заполнили явно (например hidden поля), вычислит action формы и метод запроса. Есть также метод `form_fields` который вернёт в словарике все поля и значения формы.
Транспорты
По-умолчанию, Grab использует pycurl для всех сетевых операций. Эта фунциональность реализована тоже в виде расшерения и можно подключить другое транспорт-расширение, например, для запросов через urllib2 библиотеку. Есть только одна проблема, это расширение нужно предварительно написать 🙂 Работы по urllib2 расширению ведутся, но весьма неспешно — меня на 100% устраивает pycurl. Я думаю, pycurl и urllib2 расширения по-возможностям будут аналогичны, за исключением того, что urllib2 не умеет работать с SOCKS-проксями. Все примеры, приведённые в данной статье используют pycurl-транспорт, который включен по-умолчанию.
Режим молотка (hammer-mode)
Этот режим включен по-умолчанию. Для каждого запроса у Grab есть таймаут. В режиме молотка в случае таймаута Grab не генерирует сразу исключение, а пытается ещё несколько раз сделать запрос с возростающими таймаутами. Этот режим позволяет значительно увеличить стабильность программы т.к. микро-паузы в работе сайтов или разрывы в канале встречаются сплошь и рядом. Для включения режима испльзуйте опцию `hammer_mode`, для настройки количества и длины таймаутов используйте опцию `hammer_timeouts`, в которую должен быть передан список числовых пар: первое число это таймаут на соединение с сокетом сервера, второе число — таймаут на всё время операции, включая получение ответа.
Django-расширение (grab.ext.django)
Да-да. Есть и такое 🙂 Допустим, у вас есть модель Movie с ImageField-полем `picture`. Вот как можно скачать картинку и сохранить её в объект Movie.
Что есть ещё в Grab?
Есть и другие фишки, но я боюсь, что статья слишком большая получится. Главное правило пользователя библиотеки Grab — если что-то непонятно, нужно смотреть в код. Документация пока слабая
Планы развития
Я использую Grab уже много лет, в том числе и в production сайтах, например в агрегаторе, где можно купить купоны на скидку в Москве и других городах. В 2011 году я начал писать тесты и документацию. Возможно напишу функционал для асинхронных запросов на базе multicurl. Также было бы неплохо допилить urllib-транспорт.
Как можно помочь проекту? Просто используйте его, шлите багрепорты и патчи. Также можете заказывать у меня написание парсеров, граберов, скриптов обработки информации. Регулярно пишу подобные вещи с использованием grab.