Scrapy - рекурсивная очистка и обработка двойных записей - PullRequest
0 голосов
/ 06 марта 2020

Я довольно новичок в области scrapy и python в целом, и в настоящее время пытаюсь очистить каждую комбинацию языка / игры для каждой категории (наиболее просматриваемая, самая быстрорастущая и т.д. c) с https://www.twitchmetrics.net/channels/viewership

Идея состоит в том, чтобы в каждой строке был канал с такими столбцами, как rank_mostwatched_english_leagueoflegends, rank_fastest_growing_nederlands_dota2 et c.

Пока что мне удалось немного (и только для категории «наиболее просматриваемых») :

  • Получил ранги за комбинацию «все / все»
  • Извлеките ссылки на языки, следуйте за ними и динамически создавайте элементы для сохранения ранга

Пока у меня есть этот код:

import scrapy
import datetime
from abc import ABC
from scrapy.loader import ItemLoader
from scrapy.item import BaseItem


class FlexibleItem(dict, BaseItem):
    pass


class ChannelLeaderboardSpider(scrapy.Spider):
    name = 'channel_leaderboards'
    # Enter first page of the leaderboard URL
    start_urls = [
        'https://www.twitchmetrics.net/channels/viewership'
    ]

    def parse(self, response):
        language_page_links = response.xpath(
            '//div[@class="mb-4"][1]//a//@href').getall()
        lang_page_links_test = language_page_links[:3]
        yield from response.follow_all(lang_page_links_test, self.parse_lang)

    def parse_lang(self, response):
        # Grab all games for currently parsed language
        all_games = response.xpath(
            '//div[@class="mb-4"][1]//a//@href').getall()
        all_games_test = all_games[:3]
        all_channels = response.xpath('//h5')
        language = (response.url).partition('lang=')[2]
        if language == '':
            language = 'all'
        else:
            pass

        for i, channel in enumerate(all_channels, start=1):
            il = ItemLoader(item=FlexibleItem(), selector=channel)
            il.add_xpath('channel_id', './text()')
            il.add_value('rank_mostwatched_'+language+'_all', i)
            il.add_value('date', datetime.date.today().strftime('%y-%m-%d'))
            yield il.load_item()

        yield from response.follow_all(all_games_test, self.parse_games)

    def parse_games(self, response):
        pass

Как вы можете видеть, моей следующей идеей было получить ссылки на все игры на текущем языке. Однако я не совсем уверен, как продолжить. Как мне убедиться, что каналы, которые появляются несколько раз, заполнены правильно? Есть ли лучший, менее грязный способ сделать это?

1 Ответ

1 голос
/ 08 марта 2020

Внутри вашего кода, который отправляет запрос на канал, вы захотите установить dont_filter = True, чтобы гарантировать, что дублирующиеся URL сканируются. Вы также можете отключить дублирующее промежуточное ПО, но я обычно просто использую dont_filter. Я не знаком с новым синтаксисом Follow all, но думаю, что фильтр не работает так же.

yield scrapy.Request(url, callback=self.parse_games, dont_filter=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...