Scrapy CrawlSpider не выполняет LinkExtractor, если выполняется через process.crawl () - PullRequest
4 голосов
/ 14 января 2020

Я не могу понять, почему мой паук только сканирует start_url и игнорирует извлечение любых URL, соответствующих параметру allow.

from scrapy.crawler import CrawlerProcess
from scrapy.exceptions import DropItem
from scrapy.settings import Settings
from scrapy.spiders import Rule, CrawlSpider
from scrapy.linkextractors import LinkExtractor

class MySpider(CrawlSpider):
    name = "my_spider"
    allowed_domains = ["website.com/"]
    rules = [Rule(LinkExtractor(allow='/product_page/'), callback='parse', follow=True)]
    start_urls = ["http://www.website.com/list_of_products.php"]    
    custom_settings = {
        "ROBOTSTXT_OBEY": "True",
        "COOKIES_ENABLED": "False",
        "LOG_LEVEL": 'INFO'
    }

    def parse(self, response):
        try:
            item = {
                # populate "item" with data
            }
            yield MyItem(**item)
        except (DropItem, Exception) as e:
            raise DropItem("WARNING: Product item dropped due to obligatory field not being present - %s" % response.url)


if __name__ == '__main__':
    settings = Settings()
    settings.set('ITEM_PIPELINES', {
        'pipelines.csv_pipeline.CsvPipeline': 100
    })
    process = CrawlerProcess(settings)
    process.crawl(MySpider)
    process.start()

Я не уверен, возникает ли проблема из-за того, что она вызывается из __name__.

1 Ответ

4 голосов
/ 20 января 2020

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

Предупреждение

При написании правил паука обхода избегайте использования parse в качестве обратного вызова, поскольку CrawlSpider использует сам метод parse для реализации своей логики c. Поэтому, если вы переопределите метод parse, паук сканирования больше не будет работать.

Поэтому я бы попытался назвать функцию как-нибудь еще (я переименовал ее в parse_item, аналогично CrawlSpider пример из документации, но вы можете использовать любое имя):

class MySpider(CrawlSpider):
    name = "my_spider"
    allowed_domains = ["website.com"]
    rules = [Rule(LinkExtractor(allow='/product_page/.+'), callback='parse_item', follow=True),
             Rule(LinkExtractor(allow='/list_of_products.+'), callback='parse', follow=True)]
    start_urls = ["http://www.website.com/list_of_products.php"]    
    custom_settings = {
        "ROBOTSTXT_OBEY": "True",
        "COOKIES_ENABLED": "False",
        "LOG_LEVEL": 'INFO'
    }

    def parse_item(self, response):
        try:
            item = {
                # populate "item" with data
            }
            yield MyItem(**item)
        except (DropItem, Exception) as e:
            raise DropItem("WARNING: Product item dropped due to obligatory field not being present - %s" % response.url)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...