Программа Scrapy не очищает все данные - PullRequest
0 голосов
/ 21 июня 2019

Я пишу программу насквозь, чтобы очистить следующую страницу, https://www.trollandtoad.com/magic-the-gathering/aether-revolt/10066,, и она только очищает первую строку данных, а не остальные. Я думаю, что это как-то связано с моим циклом for, но когда я изменяю цикл на более широкий, он выводит слишком много данных, поскольку в нем выводится каждая строка данных несколько раз.

 def parse(self, response):
        item = GameItem()
        saved_name = ""
        for game in response.css("div.row.mt-1.list-view"):
            saved_name  = game.css("a.card-text::text").get() or saved_name
            item["Card_Name"] = saved_name.strip()
            if item["Card_Name"] != None:
                saved_name = item["Card_Name"].strip()
            else:
                item["Card_Name"] = saved_name
            yield item

ОБНОВЛЕНИЕ # 1



    def parse(self, response):
        for game in response.css('div.card > div.row'):
            item = GameItem()
            item["Card_Name"]  = game.css("a.card-text::text").get()
            for buying_option in game.css('div.buying-options-table div.row:not(:first-child)'):
                item["Condition"] = game.css("div.col-3.text-center.p-1::text").get()
                item["Price"] = game.css("div.col-2.text-center.p-1::text").get()
            yield item

Sample Output

Ответы [ 3 ]

2 голосов
/ 22 июня 2019

Я думаю, вам нужен CSS ниже (позже вы можете использовать его как основу для обработки buying-options контейнера):

 def parse(self, response):
        for game in response.css('div.card > div.row'):
            item = GameItem()
            Card_Name  = game.css("a.card-text::text").get()
            item["Card_Name"] = Card_Name.strip()
            for buying_option in game.css('div.buying-options-table div.row:not(:first-child)'):
                # process buying-option
                # may be you need to move GameItem() initialization inside this loop

            yield item

Как видите, я переместился item = GameItem() внутрь цикла. Также нет необходимости в saved_game здесь.

0 голосов
/ 22 июня 2019

Вы код - он не работает, потому что вы создаете GameItem () вне вашего цикла списка. Должно быть, я пропустил открытку об этих методах .get () и .getall (). Может быть, кто-то может прокомментировать, чем он отличается от экстракта?

Ваш код ошибки

 def parse(self, response):
        item = GameItem() # this line right here only creates 1 game item per page
        saved_name = ""
        for game in response.css("div.row.mt-1.list-view"): # this line fails since it gets all the items on the page. This is a wrapper wrapping all the items inside of it. See below code for corrected selector.
            saved_name  = game.css("a.card-text::text").get() or saved_name
            item["Card_Name"] = saved_name.strip()
            if item["Card_Name"] != None:
                saved_name = item["Card_Name"].strip()
            else:
                item["Card_Name"] = saved_name
            yield item

Исправлен код для решения вашей проблемы:

 def parse(self, response):
        for game in response.css("div.product-col"):
            item = GameItem()
            item["Card_Name"] = game.css("a.card-text::text").get()
            if not item["Card_Name"]:
                continue # this will skip to the next item if there is no card name, if there is a card name it will continue to yield the item. Another way of doing this would be to return nothing. Just "return". You only do this if you DO NOT want code after executed. If you want the code after to execute then use yeid.
            yield item
0 голосов
/ 21 июня 2019

response.css("div.row.mt-1.list-view") возвращает только 1 селектор, поэтому код в вашем цикле выполняется только один раз. Попробуйте это: for game in response.css(".mt-1.list-view .card-text"):, и вы получите список селекторов для зацикливания.

...