Scrapy ползает, но не царапает

Проблема в том, что если я добавлю URL-адрес продукта непосредственно в «start_urls», все будет работать нормально. Но когда страница продукта появляется во время сканирования (все просканированные страницы возвращают «200»), она не очищается .... Я запускаю паук через:

scrape crawl site_products -t csv -o Site.csv

Код паука:

#-*- coding: utf-8 -*-
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from site.items import SiteItem
import datetime


class SiteProducts(CrawlSpider):
    name = 'site_products'
    allowed_domains = ['www.example.com']
    start_urls = [
        #'http://www.example.com/us/sweater_cod39636734fs.html',
        #'http://www.example.com/us/sweater_cod39693703uh.html',
        #'http://www.example.com/us/pantaloni-5-tasche_cod36883777uu.html',
        #'http://www.example.com/fr/robe_cod34663996xk.html',
        #'http://www.example.com/fr/trousers_cod36898044mj.html',
        'http://www.example.com/us/women/onlinestore/suits-and-jackets',
    ]

    rules = (
        # Extract links matching 'item.php' and parse them with the spider's method parse_item
        Rule(LinkExtractor(allow=('http://www.example.com/us/', 'http://www.example.com/fr/', )), follow=True),
        Rule(LinkExtractor(allow=('.*_cod.*\.html', )), callback='parse_item'),
    )

    def parse_item(self, response):
        self.logger.info('Hi, this is an item page! %s', response.url)
        item = SiteItem()
        item['name'] = response.xpath('//h2[@class="productName"]/text()').extract()
        item['price'] = response.xpath('//span[@class="priceValue"]/text()')[0].extract()
        if response.xpath('//span[@class="currency"]/text()')[0].extract() == '$':
            item['currency'] = 'USD'
        else:
            item['currency'] = response.xpath('//span[@class="currency"]/text()')[0].extract()
        item['category'] = response.xpath('//li[@class="selected leaf"]/a/text()').extract()
        item['sku'] = response.xpath('//span[@class="MFC"]/text()').extract()
        if response.xpath('//div[@class="soldOutButton"]/text()').extract() == True or response.xpath('//span[@class="outStock"]/text()').extract() == True:
            item['avaliability'] = 'No'
        else:
            item['avaliability'] = 'Yes'
        item['time'] = datetime.datetime.now().strftime("%Y.%m.%d %H:%M")
        item['color'] = response.xpath('//*[contains(@id, "color_")]/a/text()').extract()
        item['size'] = response.xpath('//*[contains(@id, "sizew_")]/a/text()').extract()
        if '/us/' in response.url:
            item['region'] = 'US'
        elif '/fr/' in response.url:
            item['region'] = 'FR'
        item['description'] = response.xpath('//div[@class="descriptionContent"]/text()')[0].extract()
        return item

Что мне не хватает?


person Leonid Ivanov    schedule 26.11.2016    source источник


Ответы (1)


Я проверил, и кажется, что этот веб-сайт блокирует все нестандартные пользовательские агенты (возвращая 403). Поэтому попробуйте установить параметр класса user_agent на что-то общее, например:

class SiteProducts(CrawlSpider):
    name = 'site_products'
    user_agent = 'Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0'

или просто установите его в проектах settings.py:

USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0'

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

РЕДАКТИРОВАТЬ:
После дальнейшего изучения я вижу, что ваша логика LinkExtractor ошибочна. Экстракторы ссылок извлекаются в определенном порядке правил, а ваши экстракторы перекрывают друг друга, это означает, что первый экстрактор ссылок с отслеживанием также извлекает страницы продукта, что означает, что экстрактор ссылок на продукт, который у вас есть, будет сканировать страницы, которые уже были сканированы ранее, и будет отфильтрован дубликат.

Вам нужно переработать свой первый экстрактор ссылок, чтобы избежать страниц продукта. Вы можете сделать это, просто скопировав параметр allow из вашего экстрактора ссылок в параметр deny вашего первого экстрактора ссылок.

person Granitosaurus    schedule 26.11.2016
comment
Это уже сделано в settings.py. Я получаю сканирование (200) для всех страниц. Но, как я уже сказал выше, я все еще получаю 0 царапин. Но если я добавлю URL-адрес продукта в start_urls, он будет отлично очищать этот точный продукт. - person Leonid Ivanov; 26.11.2016
comment
@LeonidIvanov Я пробовал ваш паук, и он работает, однако кажется, что ваш первый экстрактор ссылок блокирует извлечение продукта, см. Мое редактирование для получения более подробной информации. - person Granitosaurus; 26.11.2016
comment
Большое спасибо! Это помогло! Потерял почти целый день, чтобы понять, в чем проблема.... Кстати, это "запретить", а не "запретить". - person Leonid Ivanov; 26.11.2016
comment
@LeonidIvanov спасибо, отредактировал. Но да, CrawlSpider иногда может быть немного сложным, поэтому потеря нескольких часов на отладку не является чем-то необычным. Общее эмпирическое правило заключается в тщательном осмотре журнала. Вы можете сохранить журнал паука с помощью модуля scrapy crawl myspider &> myspider.log и записывать как можно больше в своем пауке с помощью модуля logging. - person Granitosaurus; 26.11.2016