2010-03-07 2 views
12

Мне нужно создать настраиваемый веб-паук/искатель, и я думаю об использовании Scrapy. Но я не могу жестко закодировать домены и разрешать URL-адрес regex: es - это вместо этого будет настраиваться в графическом интерфейсе.Использование одного спайдера для нескольких сайтов

Как я могу (как можно проще) создать паука или набор пауков с помощью Scrapy, где домены и разрешенные URL-адреса regex: es динамически настраиваются? Например. Я пишу конфигурацию в файл, и паук читает ее как-то.

+2

@Christian Davén: Не были ответы приемлемы для вашего вопроса? – dangra

ответ

10

ВНИМАНИЕ: Этот ответ был для Scrapy v0.7, с тех пор паук-менеджер сменился с изменением.

Override класс SpiderManager по умолчанию, загрузить свои собственные правила из базы данных или где-нибудь еще и создании экземпляра пользовательского паука с вашими собственными правилами/регулярных выражений и Доменное имя DOMAIN_NAME

в mybot/settings.py:

SPIDER_MANAGER_CLASS = 'mybot.spidermanager.MySpiderManager' 

в mybot/spidermanager.py:

from mybot.spider import MyParametrizedSpider 

class MySpiderManager(object): 
    loaded = True 

    def fromdomain(self, name): 
     start_urls, extra_domain_names, regexes = self._get_spider_info(name) 
     return MyParametrizedSpider(name, start_urls, extra_domain_names, regexes) 

    def close_spider(self, spider): 
     # Put here code you want to run before spiders is closed 
     pass 

    def _get_spider_info(self, name): 
     # query your backend (maybe a sqldb) using `name` as primary key, 
     # and return start_urls, extra_domains and regexes 
     ... 
     return (start_urls, extra_domains, regexes) 

и теперь ваш пользовательский класс паук, в mybot/spider.py:

from scrapy.spider import BaseSpider 

class MyParametrizedSpider(BaseSpider): 

    def __init__(self, name, start_urls, extra_domain_names, regexes): 
     self.domain_name = name 
     self.start_urls = start_urls 
     self.extra_domain_names = extra_domain_names 
     self.regexes = regexes 

    def parse(self, response): 
     ... 

Примечания:

  • Вы можете продлить CrawlSpider тоже, если вы хотите воспользоваться преимуществами своей системы правил
  • Чтобы запустить использование паука: ./scrapy-ctl.py crawl <name>, где name передается в SpiderManager.fromdomain и является ключом к поиску дополнительной информации о пауках из бэкэнд-системы
  • Поскольку решение переопределяет по умолчанию SpiderManager, кодирование классического паука (модуль python для SPIDER) не работает, но, я думаю, это не проблема для вас.Более подробную информацию о менеджере пауков по умолчанию TwistedPluginSpiderManager
+0

Разница с подходом Алекса Мартелли заключается в том, что пауки создаются по требованию, вместо того, чтобы предугадать их все, чтобы использовать их. Этот подход может снизить нагрузку на ваш сервер и объем памяти вашего бобового процесса. – dangra

+0

И как я могу указать настройки на пользовательский паук (ITEM_PIPELINES, USER_AGENT и т. Д.)? Также вы указываете «./scrapy-ctl.py crawl '. Что такое 'scrapy-ctl.py'? – warvariuc

3

Бесстыдная самооценка на domo! вам понадобится создать экземпляр сканера, как указано в примерах, для вашего проекта.

Также вам нужно настроить конфигурацию сканера во время выполнения, которая просто передает конфигурацию искателю и переопределяет настройки во время выполнения при изменении конфигурации.

4

Что вам нужно, чтобы динамически создавать классы паукообразных, подклассов ваш любимый универсальный класс паука, поставляемый scrapy (CrawlSpider подклассов с вашим добавил rules или XmlFeedSpider, или любой другой), и добавление domain_name, start_urls, и, возможно, extra_domain_names (и/или start_requests() и т. д.), так как вы получаете или выводите их из своего графического интерфейса (или файла конфигурации или любого другого).

Python упрощает выполнение такого динамического создания объектов класса; очень простой пример может быть:

from scrapy import spider 

def makespider(domain_name, start_urls, 
       basecls=spider.BaseSpider): 
    return type(domain_name + 'Spider', 
       (basecls,), 
       {'domain_name': domain_name, 
       'start_urls': start_urls}) 

allspiders = [] 
for domain, urls in listofdomainurlpairs: 
    allspiders.append(makespider(domain, urls)) 

Это дает вам список самых обнаженным костей классов паукообразных - вы, вероятно, хотите добавить parse методы к ним, прежде чем их экземпляры. Сезон по вкусу ... ;-).

+0

и где будет жить этот код? Я попытался добавить классы гусеницы динамически к моим паук-модулям, но scrapy не забирает их. – 2011-05-24 13:04:59

0

Теперь очень легко настроить Scrapy для этих целей:

  1. О первых URLs для посещения, вы можете передать его в качестве атрибута вызова паука с -a, а также использовать функцию start_requests для установки, как начать паук

  2. Вам не нужно настроить allowed_domains переменные для пауков. Если вы не включите эту переменную класса, паук сможет разрешить каждый домен.

Он должен в конечном итоге что-то вроде:

class MySpider(Spider): 

    name = "myspider" 

    def start_requests(self): 
     yield Request(self.start_url, callback=self.parse) 


    def parse(self, response): 
     ... 

и вы должны назвать его:

scrapy crawl myspider -a start_url="http://example.com"