Scrapy Playwright:使用scrapy playwright执行CrawlSpider

Scrapy Playwright: execute CrawlSpider using scrapy playwright

是否可以使用 Playwright 集成 Scrapy 来执行 CrawlSpider?我正在尝试使用以下脚本来执行 CrawlSpider,但它不会抓取任何内容。它也没有显示任何错误!

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class GumtreeCrawlSpider(CrawlSpider):
    name = 'gumtree_crawl'
    allowed_domains = ['www.gumtree.com']
    def start_requests(self):
        yield scrapy.Request(
            url='https://www.gumtree.com/property-for-sale/london/page',
            meta={"playwright": True}
        )
        return super().start_requests()

    rules = (
        Rule(LinkExtractor(restrict_xpaths="//div[@class='grid-col-12']/ul[1]/li/article/a"), callback='parse_item', follow=False),
    )

    async def parse_item(self, response):
        yield {
            'Title': response.xpath("//div[@class='css-w50tn5 e1pt9h6u11']/h1/text()").get(),
            'Price': response.xpath("//h3[@itemprop='price']/text()").get(),
            'Add Posted': response.xpath("//dl[@class='css-16xsajr elf7h8q4'][1]/dd/text()").get(),
            'Links': response.url
        }

从规则中提取的请求没有 playwright=True 元键,如果它们需要由浏览器呈现以包含有用的内容,就会出现问题。您可以使用 Rule.process_request 来解决这个问题,例如:

def set_playwright_true(request, response):
    request.meta["playwright"] = True
    return request

class MyCrawlSpider(CrawlSpider):
    ...
    rules = (
        Rule(LinkExtractor(...), callback='parse_item', follow=False, process_request=set_playwright_true),
    )

后更新
  1. 确保你的URL是正确的,我没有得到那个特定的结果(删除/page?)。

  2. 恢复你的start_requests方法,好像第一页也需要用浏览器下载

  3. 除非显式标记(例如 @classmethod@staticmethod)Python 实例方法接收调用对象作为隐式第一个参数。惯例是称此为 self(例如 def set_playwright_true(self, request, response))。但是,如果这样做,您将需要更改创建规则的方式:

    • Rule(..., process_request=self.set_playwright_true)
    • Rule(..., process_request="set_playwright_true")

    来自 the docs:“process_request 是可调用的(或字符串,在这种情况下,将使用具有该名称的蜘蛛对象的方法)”

    我原来的例子在spider之外定义了处理函数,所以不是实例方法。

根据 elacuesta 的建议,我只会将您的“parse_item”定义从异步定义更改为标准定义。

def parse_item(self, response):

它也违背了我读过的所有内容,但这让我通过了。