Проблема обхода игровых магазинов с использованием Scrapy-HTML изменений, если есть скидка и дело с нулем


Я пытаюсь использовать Scrapy для обхода ряда игровых магазинов, и у меня была одна и та же проблема со всеми ними. Я использую XPath, и HTML для цен на игры меняется в зависимости от того, помечена ли цена просто как £ 20.09, или £ 20.09 с линией через нее, а затем £ 14.49, чтобы показать скидку. Я рад иметь два столбца, "was 20.09 "(который будет содержать нулевые значения) и один после "now 14.49", но я не могу понять, как получить нулевое значение вместо того, чтобы просто вытеснять все следующие те.

Это мой код для сайта cdkeys - https://www.cdkeys.com/pc/games?limit=50 который имеет обе игры со скидками и без них.

allowed_urls = ['https://www.cdkeys.com/pc/games?limit=50?']
start_urls = ['https://www.cdkeys.com/pc/games/{pageno}?limit=50'.format(pageno=pageno)
    for pageno in range(1, 10)]

def parse(self, response):
    Games = response.xpath('//*[@id="root-wrapper"]/div/div[1]/div[2]/div[3]/div[2]/div[2]/ul/li/h2/a/text()').extract()
    Prices = response.xpath('//span[starts-with(@id, "product-price-")]/span[1]/span/text()').extract()
    for i, (Game, Price) in enumerate(zip(Games, Prices)):
        yield {'index': i, 'Game': Game, 'Price':Price}

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

Что мешает мне просто создать два списка, так это то, что я использую zip и перечисляю его просто перебирает первое x количество игр, пока не закончатся цены, вместо того, чтобы связывать каждую игру с соответствующей ценой.

Любая помощь в отображении только правильной цены в "ценах" или в поиске способа иметь пустые значения вместо того, чтобы вытеснять следующие, была бы очень признательна. Я новичок как в питоне, так и в веб-ползании и просто пытаюсь разобраться во всем этом.

1 2

1 ответ:

Я бы сделал это по-другому-перебирал элементы продукта один за другим, а затем находил названия игр, обычные цены и цены со скидками:

def parse(self, response):
    for game in response.css("ul.products-grid li.item"):
        name = game.css("h2.product-name > a::text").extract_first()
        old_price = game.css(".regular-price .price::text,.old-price .price::text").extract_first()
        discount_price = game.css(".special-price .price::text").extract_first()

        yield {
            "name": name,
            "old_price": old_price,
            "discount_price": discount_price
        }

Для первой страницы вы получите следующие выходные данные:

{'old_price': u'$ 13.59', 'name': u'Stellaris: Utopia PC DLC', 'discount_price': None}
{'old_price': u' $ 9.49 ', 'name': u'Insurgency PC', 'discount_price': u' $ 1.99 '}
...
{'old_price': u' $ 81.59 ', 'name': u'Call of Duty Black Ops II 2 Digital Deluxe Edition PC ', 'discount_price': u' $ 13.59 '}
Обратите внимание, как заполняется Старая цена со скидками и без них.