Задать вопрос
@Quiab

Как сделать CustomContextFactory Scrapy?

Всем привет!
При попытке парсить один ресурс постоянно встает необходимость в ручную перебирать варианты настроек DOWNLOADER_CLIENT_TLS_METHOD и DOWNLOADER_CLIENT_TLS_CIPHERS
Я написал свою ContextFactory, и в исходниках ( scrapy.utils.misc ) добавил передачу паука в ContextFactory.
Написал код, который в случае получение плохого ответа от сервера после нескольких повторений меняет _ssl_method и tls_cipher перебирая все комбинации полученные из itertools.product и метод getCertificateOptions возвращает CertificateOptions() c новыми настройками. Но они будто игнорируются и не применяются.

@implementer(IPolicyForHTTPS)
class FutusContext(ClientContextFactory):

    METHODS = {
        'SSLv2': 1,
        'SSLv3': 2,
        'SSLv23': 3,
        'TLSv1': 4,
        'TLSv1.1': 5,
        'TLSv1.2': 6,
    }


    def __init__(self, method=SSL.TLSv1_1_METHOD, *args, **kwargs):
        self.spider = kwargs.pop('spider')
        super().__init__(*args, **kwargs)
        self._ssl_method = method
        self.tls_ciphers = AcceptableCiphers.fromOpenSSLCipherString(self.CIPHERS)

        self.combinations = list(product(self.spider.custom_settings.get('CUSTOM_TLS', []), self.spider.custom_settings.get('CUSTOM_CIPHER', [])))


    def getCertificateOptions(self):
        method = getattr(self, 'method', getattr(self, '_ssl_method', None))
        if self.spider.count > 3:
            next_comb = self.combinations.pop(0)
            self.spider.count = 0
            self._ssl_method = self.METHODS[next_comb[0]]
            self.tls_ciphers = AcceptableCiphers.fromOpenSSLCipherString(next_comb[1])

        return CertificateOptions(
                                verify=False,
                                method=getattr(self, 'method', getattr(self, '_ssl_method', None)),
                                fixBrokenPeers=True,
                                acceptableCiphers=self.tls_ciphers,
                            )

    def getContext(self, hostname=None, port=None):
        return self.getCertificateOptions().getContext()

    def creatorForNetloc(self, hostname, port):
        return ScrapyClientTLSOptions(hostname.decode("ascii"), self.getContext())
  • Вопрос задан
  • 87 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы