Подтвердить что ты не робот

Использование одного патча Scrapy для нескольких веб-сайтов

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

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

4b9b3361

Ответ 1

ПРЕДУПРЕЖДЕНИЕ: этот ответ был для Scrapy v0.7, с тех пор паук-менеджер api сильно изменился.

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

в 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

Ответ 2

Вам нужно динамически создавать классы пауков, подклассифицируя ваш любимый общий паук-класс, предоставляемый подклассами 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, прежде чем создавать их. Сезон по вкусу...; -).

Ответ 3

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

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

Ответ 4

В настоящее время очень легко настроить скрипинг для этих целей:

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

  • Вам не нужно настраивать переменную 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"