В Python Celery, как да запазя обекти в последователни работни извиквания?

Използвам Celery за автоматизиране на изстъргване на екрана. Използвам Selenium, за да отворя уебдрайвер на Chrome, да манипулирам страницата, да запазя някои данни и след това да премина към следващата страница в опашката. Проблемът е, че той изгражда и разгражда уеб драйвера за всяка задача в опашката, което отнема много време и ресурси.

Как да запазя обекти в повиквания? Прочетох някои неща за групирането на връзки в Celery, но не ми е ясно как точно работи това - къде да изградя уебдрайвера - във файла със задачи или в основния файл за опашка? Ако е второто, как работниците знаят кой уебдрайвер да използват?

Пример:

scrape.py:

for page in list:  
  scrape.delay(str(row['product_id']), str(row['pg_code']))

tasks.py:

def scrape:
  # do some stuff

person jwoww    schedule 05.11.2013    source източник
comment
Изглежда, че трябва или да конфигурирате множество работници в Celery, или да обедините достъпа до уеб драйвера. Опитвали ли сте да използвате eventlet?   -  person Naftuli Kay    schedule 05.11.2013
comment
Мислили ли сте да използвате scrapy вместо това? Това е рамка, специално проектирана за изстъргване на сайтове и по-подходяща за тази задача от celery.   -  person Wolph    schedule 05.11.2013
comment
Проучих scrapy, но не беше най-подходящият, тъй като трябваше да изтрия данни след взаимодействие с някои управлявани от Javascript елементи на страницата. най-добрият практически подход на scrapy е да симулира извикванията на API и да ги изтрива. Моят случай на използване всъщност е тест за интеграция, така че тестването на API извикванията е възможно, но не е идеално.   -  person jwoww    schedule 06.11.2013


Отговори (1)


Тъй като всеки работник инстанцира задачата като сингълтон, можете да кеширате уеб драйвера в обекта на задачата. Документацията изрично предлага този подход.

http://docs.celeryproject.org/en/latest/userguide/tasks.html#instantiation

person joshua    schedule 05.11.2013
comment
Уау, това работи невероятно добре и беше много просто! Жалко, че това беше заровено в документите в област, която не бих търсил. Някакви предложения как да затворите драйвера (или в случая с документите, връзката с DB)? Бих искал да го затворя, когато работникът бъде освободен, но не видях в документите как да посоча това. Като цяло, това е незначителен проблем за моя случай на употреба, но изглежда ценен в името на пълнотата. - person jwoww; 06.11.2013
comment
Да, може да е трудно да се намерят неща в документите за целина. Трябва да можете да почиствате по метода __del__. - person joshua; 06.11.2013
comment
Можете ли да помогнете да се изясни как правилно да се използва del? Ето какво написах, но без успех като част от моя нов клас ChromeTask: def __del__(self): if self._driver is not None: return self._driver.close() Но когато програмата за автоматично мащабиране на целина убива процесите, драйверът ясно не се затваря, тъй като прозорците на Chrome остават отворени. Когато инструментът за автоматично мащабиране се мащабира отново, получавам още нови прозорци на Chrome в допълнение към оставените зомбита. - person jwoww; 10.11.2013
comment
Методът __del__ се извиква, когато обектът бъде събран. Така че изглежда, че събирачът на боклук не може да затвори екземпляра на chrome. Сега не знам подробностите за това как работи автоматичният скалер, но може да успеете да се свържете с него по някакъв начин, за да извършите почистването си. - person joshua; 11.11.2013