start_requests в обход правил при работе с CrawlSpider - PullRequest
0 голосов
/ 19 марта 2020

Я пытался использовать Scrapy CrawlSpider для сканирования списков с веб-сайта. Проблема в том, что данные поступают с XMLHttpRequest. Итак, я использовал Puppeteer As A Servivce для правильного рендеринга javascript в скрапе. Теперь, поскольку даже первый запрос поступил от XMLHttpRequest, я хотел использовать метод start_requests вместо обычного start_urls. Но когда я использую метод start_requests, CrawlSpider не следует указанным правилам. И когда я просто использую start_urls, он не рендерит javascript, поэтому ссылки не найдены. Кто-нибудь знает способ обойти это? Вот мой код:

import scrapy
from scrapypuppeteer import PuppeteerRequest, PuppeteerHtmlResponse, PuppeteerJsonResponse
from scrapy.spiders import CrawlSpider,Rule
from scrapy.selector import Selector
from scrapy.linkextractors import LinkExtractor
from scrapy.http import Request, HtmlResponse

class MySpider(CrawlSpider):
    name = "myspider"
    allowed_domains = []
    urls = []            

    def __init__(self, startUrl = None, config_dict = None, path = None,*a, **kw):
        self.config_dict = config_dict
        super(MySpider, self).__init__(*a, **kw)
        MySpider.rules = (Rule(LinkExtractor(allow=set([".*/dresses/.*"])), callback='parse_listing', follow=True,process_request="use_puppeteer"),)
        super(MySpider, self)._compile_rules()
        self.start_urls = ["https://www.mywebsite.com/"]

    def _requests_to_follow(self, response):
        if not isinstance(
                response,
                (HtmlResponse, PuppeteerHtmlResponse, PuppeteerJsonResponse)):
            return
        seen = set()
        for n, rule in enumerate(self._rules):
            links = [lnk for lnk in rule.link_extractor.extract_links(response)
                     if lnk not in seen]
            if links and rule.process_links:
                links = rule.process_links(links)
            for link in links:
                seen.add(link)
                r = self._build_request(n, link)
                yield rule.process_request(r)

    def use_puppeteer(self, request):
        return PuppeteerRequest(request.url, callback=self.parse_listing)

    def start_requests(self):
        yield PuppeteerRequest(self.start_urls[0], callback=self.parse_listing, dont_filter=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...