Pull to refresh
80
0
asdfasdfasdf@itforge

User

Send message
Хм, даже не знаю, у меня POST-запросы без проблем работают в linux. Напишу попозже тесты на множественные POST-запросы, посмотрим.

Весь трафик кстати можно логировать как с обычным Grab.

bot = SomeSpider(...)
bot.setup_grab(log_dir='/path/to/dir')
А там можно задать условия, например, на текст внутри элемента?

//div/strong[contains(text(), «Google»)]
Если вы задаёте `post` опцию, то писать `method=«post»` уже не обязательно, он таким будет автоматически. Да и disable_cache не нужно, post запросы не кэшируются:

* bitbucket.org/lorien/grab/src/7000b67ff7ad/grab/spider/base.py#cl-409
* bitbucket.org/lorien/grab/src/7000b67ff7ad/grab/spider/base.py#cl-519
Я уже ничо не соображаю. Сейчас спать пойду. Но могу сказать, чего есть в Task объектах: можно передавать сколько угодно именованных параметров и они потом будут доступны как аттрибуты task объекта, который передаётся в обработчик третьим параметром. Наверное это аналог meta из scrapy.
Попробую завтра, башка не варит уже сегодня.
Гыгы, без понятия :) Можно сделать два спайдера и запускать второй после того как первый скачал все картинки. Ну или можно как-то извращаться и в task_images и определять что это последняя картинка и запускать нужный обработчик. Да, не помешала бы какая-то встроенная фича для такой задачи (генерация сигнала после обработки помеченных тасков), но пока ничего такого нет.
distributed mode — это мои эксперименты с выполнением task-обработчиков на нескольких ядрах процессора с помощью multiprocessing, но это всё нереально сырое, лучше эту опцию пока не трогать.
Ага, интересная идея. У меня там кстати щас есть хэндлер на SIGUSR1 — пишется статистика счётчиков в /tmp/spider.log или куда-то туда… Топорно конечно, но вот как бы думаю в этом направлении.
О, любитель ковычек, вы забыли слово лучше в кавычки заключить :)

Я использовал BeatifulSoup до тех пор, пока не созрел до lxml. Это библиотека написанная на C. Она полностью поддерживает поиск через xpath-выражения, а также понимает битый html. Grab использует lxml для парсинга, но вообще ничего не мешает вам в том же Grab:Spider работать с BeautifulSoup.

Плюсы BeautifulSoup:
* pure python
* умещается в одном файле
* допускаю, что новичку проще вникнуть в работу с BS, чем с lxml

Минусы BeautifulSoup
* отвратительно медленный
* возможно жрёт память, мне щас лень писать тесты для памяти
* меня лично напрягает писать два длинных camel case имени в строке импорта: «from BeautifulSoup import BeautifulSoup»

Для скорости мне тесты писать не лень. Запустите у себя на компьютере и ужаснитесь:

from lxml.html import fromstring
from BeautifulSoup import BeautifulSoup
import time
import urllib

data = urllib.urlopen('http://habrahabr.ru').read()

start = time.time()
for x in xrange(10):
    tree = BeautifulSoup(data)
    print tree.find('title').text
print 'BeautifulSoup: %.2f' % (time.time() - start)

start = time.time()
for x in xrange(10):
    tree = fromstring(data)
    print tree.xpath('//title')[0].text
print 'lxml: %.2f' % (time.time() - start)


Если вы ещё не используете lxml для парсинга, то мне вас жаль :)
Задания с сетевые ошибками (в том числе c кодами > 400 and != 404) по-умолчанию засылаются обратно в очередь:

* bitbucket.org/lorien/grab/src/7000b67ff7ad/grab/spider/base.py#cl-520

Количество попыток можно настраивать. Когда количество попыток для задания истекает, то просто логируется ошибка:

* bitbucket.org/lorien/grab/src/7000b67ff7ad/grab/spider/base.py#cl-395

Можно в принципе добависть фичку, чтобы вызывался callback какой-нить настраиваемый в таком случае. Можно будет в этом callback взять и опять запихать задание в очередь, чтобы ещё раз повторить цикл попыток.

> Потом в случае чего выдаю ошибку. Промежуточные структуры данных сохраняю в сериализованном виде на диск, чтобы потом если что можно было перезапуститься с ключиком --continue
Я обычно настраиваю парсер так, чтобы он работал без ошибок и потом запускаю главный парсинг.

Я сейчас эксперементирую с кэшем. Записываю в монго скачанные документы. Это поведение можно так включить: bot = SomeSpider(use_cache=True, cache_db='some-db-name') Кэшируются только GET-запросы. Столкнулся с проблемой, что не влезает всё на винчестер, ну нету у меня винчестера на 2 терабайта. Тогда я придумал на лету применять gzip-компрессию. Включается опцией use_cache_compression=True. Документы сжимаются в 10 раз — это очень круто. Но нужно время CPU на компрессию-декомпрессию — это не круто :( Я пытался через multiprocessing организовать обработку на множестве ядер, вроде как есть ускорение в два раза на 4-ядерном атлоне. Но это пока нихрена не оттестировано даже на эмпирическом уровне. Короче пока работа с кэшем довольно медленная, я вообще пока плохо понимаю что делаю — все эти асинхронности и mongodb — новые для меня области :) Как минимум, работа с кешем очень упрощает отладку парсера на начальном этапе.

Конец brain dump'а :)
Я объясню. Мне нужно было пробежаться по всем этим элементам, не просто достать первый такой элемент, а перебрать их все и у каждого взять несколько свойств. Если вы попробуете это сделать через lxml/xpath, то никаких тормозов не будет, а scrapy делает что-то больно хитрое, такое хитрое, что оно в 200 раз медленнее работает. Судя по всему он каждую ноду из результата заворачивает в какой-то свой класс — это и даёт феерическое замедление.
Там я немного про другую вещь писал, про Grab — это синхронный API к pycurl. А это статья про асинхронный spider, который как раз и является аналогом scrapy — решает абсолютно те же задачи.
Потому что я всегда любил велосипеды. Было интересно попробовать свой собственный асинхронный велосипед. Кроме всего прочего скрапи меня немного пугает свою монструозностью. В моём же модуле spider всего 700 строчек, которые я сам писал. Месяц назад сознательно попытался написать один парсер на скрапи, но его багафича отбила всякое желание делать что-то дальше: groups.google.com/group/scrapy-users/browse_thread/thread/5092eb5cc8695f2a/aa36618c58c539ec Но это всё мелочи жизни. Просто у меня есть время и желание писать свои решения, — я их пишу. А ну и ещё — синхронный интерфейс Grab я уже пишу/использую много лет, поэтому хотелось как-то заюзать эти наработки. Очень здорово получилось, что получилось натянуть старый интерфейс Grab на асинхронность.

А ещё scrapy не поддерживает socks-прокси. Впрочем grab:spider — тоже, в debian stable устаревшая версия curl-библиотеки, в которой есть баг — multicurl не работает с socks. В более новых версиях curl этот баг пофиксили.
Вам приз за внимательность. Поправил.
Каковы ваши успехи в яндекс-директе? Интересно, работают ли они с торрент-сайтами.
Проверяйте, что ip действительно меняется. Провярйте, что cookie-действительно не передаются (смотрите grab.request_headers) Вопросы по грабу лучше в майл-лист писать, ссылка в конце статьи дана.
Он просто прикидывает, достаточно ли он уже оголодал от виртуальных муравьёв, чтобы съесть хозяина.
Я вот подумал, получается, за рыженьких котят проголосовали более шести тысяч человек:

>>> int((549784 / 98.75) * 1.25 — (2 + 1 + 4 + 12))
6940
> Думаю до утра эту ошибку исправлять.

Что это значит?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity