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),
)
后更新
确保你的URL是正确的,我没有得到那个特定的结果(删除/page
?)。
恢复你的start_requests
方法,好像第一页也需要用浏览器下载
除非显式标记(例如 @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):
它也违背了我读过的所有内容,但这让我通过了。
是否可以使用 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),
)
确保你的URL是正确的,我没有得到那个特定的结果(删除
/page
?)。恢复你的
start_requests
方法,好像第一页也需要用浏览器下载除非显式标记(例如
@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):
它也违背了我读过的所有内容,但这让我通过了。