Pull to refresh

Comments 26

Ну так все же, а чем это лучше использования lxml+xpath? Ну кроме сохранения пары строк на получение дерева? Лучше б описал преимущества grab, а то я их перед собой не вижу :(

P.S. в опросе только библиотеки для получения данных, а не парсинга ;) я бы проголосовал бы за requests+lxml
Библиотеки для разбора DOM не включал в опрос т.к. это по сути добавило бы два измерения ответов, кто-то например использует requests + lxml, а кто-то requests + beautifulsoup, а кто-то gevent + lxml. А те кто используют Grab или Scrapy скорее всего используют их функции-обёртки для работы с DOM.

> Лучше б описал преимущества grab, а то я их перед собой не вижу :(

Преимущества Grab перед Requests трудно мне перечислить т.к. я Requests практически не использовал никогда. Всё таки Grab и Requests это разные вещи. Grab это комплексный фреймворк, а Requests это конкретно сетевая библиотека. В Grab есть так называемые сетевые транспорты, одним из которых является pycurl. Этот вариант хорошо оттестирован. Другим вариантом может быть Requests. Такой транспорт давно написан, но никто не тестирует его, а мне самому этот вариант не нужен т.к.удовлетворяет pycurl меня.

В голом виде Grab я практически не использую. Использую для всех задач Grab::Spider, вот эту штуку уже смысла нет сравнивать с Requests, только со Scrapy т.к. Spider это:
* интструмент для структуризации логики парсера вашего сайта
* удобный интерфейс для обработки асинхронных запросов
* автоматическая обработка сбойнувших запросов
* работа со списками прокси
* кэширующий слой (жутко полезная штука для отладки и не только)
* инструменты сбора статистических данных о парсинге: количество тех или иных событий, время работы различных слоёв парсера
* интерфейс работы с DOM деревом документа (описаны выше в статье)
* в данный момент я делаю рефакторинг Spider для выполнения обраотчиков на нескольких ядрах, в будущем хочу сделать кластерное решение.
А его как-нибудь можно скрестить с V8, чтоб получить этакий headless-браузер?
Можно. Разобраться как работает V8, разобраться как работает Grab и скрестить.
Советую переходить на lxml+xpath, суп медленный. Хотя если объёмы парсинга небольшие, можно и его парсить.

Плюсы xml:
* более быстрый
* возможно памяти меньше ест, врать не буду, не помню
* позволяет использовать стандарт, который знают все вменяемые специалисты: xpath запросы
* есть дополнительные плюшки см модуль lxml.html
* суп раньше банально падал на некоторых типах страниц, я даже писал простенький регексп, который все javascritp выкусывал, перед тем как передать текст страницы в суп
он все еще падает на «индусско» писаных сайтах, где есть не закрытые тэги, опечатки и т.п.? В этом плане lxml рулит, т.е. уронить его парсер очень тяжело
Bsoup жутко медленный. Плохо работает с PyPy. habrahabr.ru/post/163979/

Когда запускал бенчмарк на индекспейджах TOP1000 ALEXA, увидел странную особенность — на части страниц зависимость скорости парсинга от размера страницы имеет вид примерно Speed = Size * 3 а на некоторых Speed = Size * 10. Т.е. на графике получается не одна линия, а 2. Что говорит о том, что некоторые «типы» страниц он сильно недолюбливает. Возможно там происходит переключение режима из Strict в Compatible, не знаю, в код не заглядывал.
Почему никто не рассматривает PyQuery? Отлично справляется со своими задачами! По названию сами понимаете, на что он похож ;)
Признаю, дурацкий опрос вышел. Я Рассказывал в статье про доступ к DOM-дереву документа, а в опросе пытался выяснить какую либу народу юзает для сетевых операций. Кстати, в Grab есть «поддержка» pyquery, через аттрибут pyqeruy можете делать нужные вам выборки применительно к загруежнному документу.
Кстати, любой язык запросов можно реализровать в селекторах. Сейчас метод select понимает только xpath запросы, можно научить его и CSS запросам через cssselect или pyquery, например, с таким синтаксисом: select(css='....')
Я его тоже использую, однако бесит такой момент, что когда я делаю

for a in pq.find('a.class'):
pass

в цикл передается уже HtmlElement, а не объект класса PyQuery.
Приходится городить такую вот конструкцию:

a_list = pq.find('a.class')
for i in range(len(a_list)):
a_list.eq(i).find…
Собственно, статья и рассказывает о механизме, который решает эту проблему ;-)
Хотел с ходу набросать поддержку pyquery в селекторах но сразу не понял, как оно работает. Нужны ответы на вопросы:

1) Есть ли возможность построить pyquery объект не по html по данной etree.Element ноде?
2) Каким методом осуществляется поиск? find? Что он возвращает, etree.Element ноды?
1) По идее можно, просто передать в конструктор ноду
2) Да, find, возвращает объект класса PyQuery, но итерации в цикле по нему происходят как по массиву HtmlElement (странное немного поведение)

pq.find('a').find('b')
Прикрутил pyquery к селекторам:

>>> from grab import Grab
>>> g = Grab()
>>> g.go('http://habrahabr.ru/post/173509/')
<grab.response.Response object at 0x139d3d0>
>>> for sel in g.doc.select(pyquery='.comment_item'):
...     print sel.select(pyquery='.username').text()
... 
gigimon
itforge
ertaquo
itforge
elky
itforge
gigimon
galkin
itforge
itforge
Arceny
itforge
Arceny
zxmd
itforge
> pq.find('a').find('b')

Здесь найдётся список b детей из первого a родителя или из всех a родителей?
а почему нет в голосовалке lxml?
Да я чё-то думал, селекторы сложнее сделать, может и раньше бы запилил. Оказалось, что всё довольно просто.
А на PHP никто не парсит что ли? Если это так, то почему?
Спасибо за статью. Подскажите, как можно получить значнеие конкретного арибута в найденном селекторе?
element = grab.doc.select('//h1/a')
print element.attr('href')
Уху, в доке нигде нету, залез на гитхаб и там нашел. Но все равно спасибо.
Sign up to leave a comment.

Articles

Change theme settings