Scrapy-splash response.css() 无法获取元素

ali*_*lid 3 python scrapy web-scraping python-3.x scrapy-splash

我正在尝试从动态 JS 内容网站中抓取,我正在尝试获取当前页面的面包屑。

在此处输入图片说明

面包屑由 4 个名为 的类组成: '.breadcrumbs-link'

在此处输入图片说明

为此,我使用 scrapy-splash 编写了以下代码:

import scrapy
from scrapy_splash import SplashRequest


class MySpider(scrapy.Spider):
    name = "quotes4"

    start_urls = ["https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas"]

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url=url, callback=self.parse, endpoint='render.html',args= {'wait': 10})
    
    def parse(self, response):
        print ('Result:')
        print(len(response.css('.breadcrumbs-link').extract())) # OUTPUT: 0
        print(response.css('.breadcrumbs-link').extract()) # OUTPUT: []
Run Code Online (Sandbox Code Playgroud)

我的方法可能有什么问题?

Chr*_*ras 5

本网站 ( https://www.woolworths.com.au) 使用 Angular。如果您访问Splash FAQ 页面,我们可以看到“网站未正确呈现”部分:

私有模式下的非工作 localStorage。这是一个常见问题,例如对于基于 AngularJS 的网站。如果渲染不起作用,请尝试禁用私密模式(请参阅如何禁用私密模式?)。

在链接中我们可以看到:

如何禁用私人模式?

使用 Splash>=2.0,您可以禁用私密模式(默认为“开启”)。有两种方法可以解决这个问题:

在启动时,使用--disable-private-mode参数,例如,如果您使用 Docker:

$ sudo docker run -it -p 8050:8050 scrapinghub/splash --disable-private-mode
Run Code Online (Sandbox Code Playgroud)

在运行时使用/execute端点并将splash.private_mode_enabled属性设置 为false

简单的方法是使用 禁用私有模式--disable-private-mode,但如果您不想这样做,那么您可以传递一个 Lua 脚本,临时禁用蜘蛛的私有模式,然后在完成后再次启用它:

$ sudo docker run -it -p 8050:8050 scrapinghub/splash --disable-private-mode
Run Code Online (Sandbox Code Playgroud)

它通过禁用私有模式而对我有用:

import scrapy
from scrapy_splash import SplashRequest

LUA_SCRIPT = """
function main(splash)
    splash.private_mode_enabled = false
    splash:go(splash.args.url)
    splash:wait(2)
    html = splash:html()
    splash.private_mode_enabled = true
    return html
end
"""

class MySpider(scrapy.Spider):
    name = "quotes4"

    start_urls = ["https://www.woolworths.com.au/shop/browse/drinks/cordials-juices-iced-teas/iced-teas"]

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url=url,
                                callback=self.parse,
                                endpoint='execute',
                                args={
                                    'wait': 1,
                                    "lua_source":LUA_SCRIPT})

    def parse(self, response):
        print ('Result:')
        print(".breadcrumbs-link len = %d" % (len(response.css('.breadcrumbs-link').extract()))) # OUTPUT: 4
        print(".breadcrumbs-link = %s" % (response.css('.breadcrumbs-link').extract())) # OUTPUT: [...HTML ELEMENTS...]
Run Code Online (Sandbox Code Playgroud)