Пустой файл json как вывод в Scrapy

Я заявляю, что уже прочитал некоторые ответы на ту же проблему, но не смог решить свою проблему. Я новичок в Python, я пытаюсь извлечь из Aptoide данные о приложениях и магазинах, и я хочу получить результат вывода в виде файла.json (или CSV), но файл, который я получаю, пуст, я не знаю причина.

Это мой код:

    import scrapy

    from scrapy.spiders import CrawlSpider, Rule
    from scrapy.linkextractors import LinkExtractor
    from scrapy.contrib.spiders import CrawlSpider, Rule
    from scrapy.selector import HtmlXPathSelector

    class ApptoideItem(scrapy.Item):
        app_name = scrapy.Field()
        rating = scrapy.Field()
        security_status = scrapy.Field()
        good_flag = scrapy.Field()
        licence_flag = scrapy.Field()
        fake_flag = scrapy.Field()
        freeze_flag = scrapy.Field()
        virus_flag = scrapy.Field()
        five_stars = scrapy.Field()
        four_stars = scrapy.Field()
        three_stars = scrapy.Field()
        two_stars = scrapy.Field()
        one_stars = scrapy.Field()
        info = scrapy.Field()
        download = scrapy.Field()
        version = scrapy.Field()
        size = scrapy.Field()
        link = scrapy.Field()
        store = scrapy.Field()

class AppSpider(CrawlSpider):
    name = "second"
    allowed_domains = ["aptoide.com"]
    start_urls = [ "http://www.aptoide.com/page/morestores/type:top" ]

    rules = (
        Rule(LinkExtractor(allow=(r'\w+\.store\.aptoide\.com$'))),

        Rule(LinkExtractor(allow=(r'\w+\.store\.aptoide\.com/app/market')), callback='parse_item')
        )


def parse_item(self, response):

    item = ApptoideItem()
    item['app_name']= str(response.css(".app_name::text").extract()[0])
    item['rating']= str(response.css(".app_rating_number::text").extract()[0])
    item['security_status']= str(response.css("#show_app_malware_data::text").extract()[0])
    item['good_flag']= int(response.css(".good > div:nth-child(3)::text").extract()[0])
    item['licence_flag']= int(response.css(".license > div:nth-child(3)::text").extract()[0])
    item['fake_flag']= int(response.css(".fake > div:nth-child(3)::text").extract()[0])
    item['freeze_flag']= int(response.css(".freeze > div:nth-child(3)::text").extract()[0])
    item['virus_flag']= int(response.css(".virus > div:nth-child(3)::text").extract()[0])
    item['five_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(1) > div:nth-child(3)::text").extract()[0])
    item['four_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(2) > div:nth-child(3)::text").extract()[0])
    item['three_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(3) > div:nth-child(3)::text").extract()[0])
    item['two_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(4) > div:nth-child(3)::text").extract()[0])
    item['link']= response.url
    item['one_stars']= int(response.css("div.app_ratting_bar_holder:nth-child(5) > div:nth-child(3)::text").extract()[0])
    item['download']= int(response.css("p.app_meta::text").re('(\d[\w\.]*)')[0].replace('.', ''))
    item['version']= str(response.css("p.app_meta::text").re('(\d[\w\.]*)')[1])
    item['size']= str(response.css("p.app_meta::text").re('(\d[\w\.]*)')[2])
    item['store_name']= str(response.css(".sec_header_txt::text").extract()[0])
    item['info_store']= str(response.css(".ter_header2::text").extract()[0])
    yield item

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

Настройки:

CLOSESPIDER_PAGECOUNT = 1000
CLOSESPIDER_ITEMCOUNT = 500
CONCURRENT_REQUESTS = 1
CONCURRENT_ITEMS = 1

BOT_NAME = 'nuovo'


SPIDER_MODULES = ['nuovo.spiders']
NEWSPIDER_MODULE = 'nuovo.spiders'

Может кто-нибудь найти проблему и предложить мне решение?

1 ответ

Ваш код полон ошибок, когда вы запускаете паука, вы можете сохранить журнал и просмотреть его с помощью grep:

scrapy crawl spidername 2>&1 | tee crawl.log

Несколько ошибок, которые я нашел:

  • ваш ApptoideItem пропущены такие поля, как store_name и несколько других.
  • весь ваш int() преобразование небезопасно, то есть если ваш response.css возвращает None, что происходит, если ничего не находит, вы получаете ошибку.

Чтобы разрешить второй пункт, я предлагаю изучить scrap ItemLoaders, который позволит вам указать поведение по умолчанию для некоторых полей, например, включить элементы в полях. _flag логическое и т. д.
Также, как упомянул @Jan в комментариях, вы должны использовать extract_first() метод вместо extract()[0], extract_first позволяет вам указать атрибут по умолчанию, когда ничего не найдено, т.е. .extract_first(default=0)

Другие вопросы по тегам