跳转到主要内容

Scrapy使用Splash的JavaScript支持

项目描述

PyPI Version Test Status Code Coverage

本库提供使用 ScrapySplash 集成 JavaScript 的功能。许可证为 BSD 3 条款。

安装

使用 pip 安装 scrapy-splash

$ pip install scrapy-splash

Scrapy-Splash 使用 Splash HTTP API,因此您还需要一个 Splash 实例。通常,安装和运行 Splash,以下内容就足够了

$ docker run -p 8050:8050 scrapinghub/splash

有关更多信息,请参阅 Splash 的 安装文档

配置

  1. 将 Splash 服务器地址添加到 Scrapy 项目的 settings.py 中,如下所示

    SPLASH_URL = 'http://192.168.59.103:8050'
  2. 通过在 settings.py 文件中将 Splash 中间件添加到 DOWNLOADER_MIDDLEWARES 中并更改 HttpCompressionMiddleware 的优先级来启用 Splash 中间件

    DOWNLOADER_MIDDLEWARES = {
        'scrapy_splash.SplashCookiesMiddleware': 723,
        'scrapy_splash.SplashMiddleware': 725,
        'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
    }

    默认 Scrapy 设置中,723 的顺序是在 HttpProxyMiddleware (750) 之前。

    需要更改 HttpCompressionMiddleware 的优先级以允许高级响应处理;有关详细信息,请参阅 https://github.com/scrapy/scrapy/issues/1895

  3. 通过在 settings.py 中添加它来启用 SplashDeduplicateArgsMiddleware

    SPIDER_MIDDLEWARES = {
        'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
    }

    此中间件是支持 cache_args 功能所必需的;它通过在磁盘请求队列中多次存储重复的 Splash 参数来节省磁盘空间。如果使用 Splash 2.1+,则此中间件还可以通过多次不向 Splash 服务器发送这些重复参数来节省网络流量。

  4. 设置自定义 DUPEFILTER_CLASS

    DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
  5. 如果您使用 Scrapy HTTP 缓存,则需要自定义缓存存储后端。scrapy-splash 提供了 scrapy.contrib.httpcache.FilesystemCacheStorage 的子类

    HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

    如果您使用其他缓存存储,则需要对其进行子类化,并用 scrapy_splash.splash_request_fingerprint 替换所有 scrapy.util.request.request_fingerprint 调用。

还有一些其他选项可供选择。如果您想更改默认设置,请将它们放入 settings.py

  • SPLASH_COOKIES_DEBUG 默认为 False。将其设置为 True 以启用 SplashCookiesMiddleware 中的调试 cookies。此选项类似于内置的 scarpy cookies 中间件的 COOKIES_DEBUG:它记录所有请求发送和接收的 cookies。

  • SPLASH_LOG_400 默认为 True - 它指示记录来自 Splash 的所有 400 错误。这些错误很重要,因为它们显示了执行 Splash 脚本时发生的错误。将其设置为 False 以禁用此日志记录。

  • SPLASH_SLOT_POLICY 默认为 scrapy_splash.SlotPolicy.PER_DOMAIN(作为对象,而不是字符串)。它指定了 Splash 请求的并发性和礼貌性如何保持,并为 SplashRequestslot_policy 参数指定默认值,如下所述。

使用

请求

使用 scrapy_splash.SplashRequest 渲染请求是最简单的方法

yield SplashRequest(url, self.parse_result,
    args={
        # optional; parameters passed to Splash HTTP API
        'wait': 0.5,

        # 'url' is prefilled from request url
        # 'http_method' is set to 'POST' for POST requests
        # 'body' is set to request body for POST requests
    },
    endpoint='render.json', # optional; default is render.html
    splash_url='<url>',     # optional; overrides SPLASH_URL
    slot_policy=scrapy_splash.SlotPolicy.PER_DOMAIN,  # optional
)

或者,您可以使用常规的 scrapy.Request 并使用 'splash' 请求 meta

yield scrapy.Request(url, self.parse_result, meta={
    'splash': {
        'args': {
            # set rendering arguments here
            'html': 1,
            'png': 1,

            # 'url' is prefilled from request url
            # 'http_method' is set to 'POST' for POST requests
            # 'body' is set to request body for POST requests
        },

        # optional parameters
        'endpoint': 'render.json',  # optional; default is render.json
        'splash_url': '<url>',      # optional; overrides SPLASH_URL
        'slot_policy': scrapy_splash.SlotPolicy.PER_DOMAIN,
        'splash_headers': {},       # optional; a dict with headers sent to Splash
        'dont_process_response': True, # optional, default is False
        'dont_send_headers': True,  # optional, default is False
        'magic_response': False,    # optional, default is True
    }
})

在中间件或使用 scrapy.Request 子类的情况下,使用 request.meta['splash'] API(下文还将描述 SplashFormRequest)。例如,meta['splash'] 允许创建一个中间件,默认情况下启用 Splash 以处理所有外发请求。

SplashRequest 是一个方便的工具,用于填充 request.meta['splash'];在大多数情况下,它应该更容易使用。对于每个 request.meta['splash'] 键,都有一个对应的 SplashRequest 关键字参数:例如,要设置 meta['splash']['args'],请使用 SplashRequest(..., args=myargs)

  • meta['splash']['args'] 包含发送给 Splash 的参数。scrapy-splash 会向 args 添加一些默认的键/值。

    • ‘url’ 被设置为 request.url;

    • 对于 POST 请求,‘http_method’ 被设置为 ‘POST’;

    • 对于 POST 请求,‘body’ 被设置为 request.body。

    您可以通过明确设置它们来覆盖默认值。

    请注意,默认情况下 Scrapy 使用 AJAX 转义方案对 URL 片段进行转义。如果您想传递包含片段的 URL 给 Splash,请手动在 args 字典中设置 url。如果您使用 SplashRequest,这将自动处理,但如果您使用原始的 meta['splash'] API,则需要记住这一点。

    处理 POST 请求需要 Splash 1.8+;在早期版本的 Splash 中,忽略 ‘http_method’ 和 ‘body’ 参数。如果您使用 /execute 端点并且想支持 POST 请求,您必须手动在 Lua 脚本中处理 ‘http_method’ 和 ‘body’ 参数。

  • meta['splash']['cache_args'] 是要缓存到 Splash 端的参数名称列表。这些参数只发送一次给 Splash,然后使用缓存值;这可以节省网络流量并减少请求队列磁盘内存的使用。仅对每个请求都不变的较大参数使用 cache_argslua_source 是一个好的选择(如果您不使用字符串格式化来构建它)。要使此功能正常工作,需要 Splash 2.1+。

  • meta['splash']['endpoint'] 是要使用的 Splash 端点。对于 SplashRequest,默认使用 render.html。如果您使用原始的 scrapy.Request,则默认为 render.json(出于历史原因)。最好始终明确传递端点。

    有关可用端点和参数的完整列表,请参阅 Splash HTTP API 文档

  • meta['splash']['splash_url'] 覆盖了在 settings.py 中设置的 Splash URL。

  • meta['splash']['splash_headers'] 允许添加或更改发送到 Splash 服务器的头信息。请注意,此选项 不是 用于设置发送到远程网站的头部。

  • meta['splash']['slot_policy'] 用来定制 Splash 请求的并发性和礼貌性维护方式。

    目前有 3 种策略可用

    1. scrapy_splash.SlotPolicy.PER_DOMAIN(默认)- 根据要渲染的 URL 向下载器槽发送 Splash 请求。如果您想维护每个域的礼貌性和并发设置,这很有用。

    2. scrapy_splash.SlotPolicy.SINGLE_SLOT - 将所有Splash请求发送到单个下载器槽位。如果您想限制对Splash的请求量,这非常有用。

    3. scrapy_splash.SlotPolicy.SCRAPY_DEFAULT - 不对槽位进行任何操作。它与SINGLE_SLOT策略类似,但如果您在相同的地址上访问Splash以外的其他服务,可能会有所不同。

  • meta['splash']['dont_process_response'] - 当设置为True时,SplashMiddleware不会将响应转换为自定义的scrapy.Response子类。默认情况下,对于Splash请求,会将SplashResponse、SplashTextResponse或SplashJsonResponse之一传递给回调函数。

  • meta['splash']['dont_send_headers']: 默认情况下,scrapy-splash会将请求头传递给Splash,并在“headers”JSON POST字段中。对于所有render.xxx端点,这意味着默认情况下Scrapy头选项被尊重(http://splash.readthedocs.org/en/stable/api.html#arg-headers)。在Lua脚本中,您可以使用splash:goheaders参数来应用传递的头部:splash:go{url, headers=splash.args.headers}

    将“dont_send_headers”设置为True以防止将headers传递给Splash。

  • meta['splash']['http_status_from_error_code'] - 当assert(splash:go(..))失败时,将响应的状态设置为HTTP错误代码;它需要meta['splash']['magic_response']=True。如果使用原始meta API,则默认情况下http_status_from_error_code选项为False;SplashRequest默认将其设置为True。

  • meta['splash']['magic_response'] - 当设置为True且从Splash收到JSON响应时,响应的几个属性(头部、正文、URL、状态码)将使用JSON返回的数据填充。

    • 响应头部从headers键填充;

    • 响应的URL设置为url键的值;

    • 响应正文设置为html键的值,或body键的base64解码值;

    • 响应状态设置为http_status键的值。当meta['splash']['http_status_from_error_code']为True且assert(splash:go(..))失败并返回HTTP错误时,响应的状态也会设置为HTTP错误代码。

    原始URL、状态和头部作为response.real_urlresponse.splash_response_statusresponse.splash_response_headers可用。

    如果使用SplashRequest,则默认设置为True。对于非JSON端点,无论magic_response设置如何,仅填充url。

使用scrapy_splash.SplashFormRequest来通过splash进行FormRequest。它接受与SplashRequest相同的参数,还包括formdata,类似于scrapy中的FormRequest

>>> SplashFormRequest('http://example.com', formdata={'foo': 'bar'})
<POST http://example.com>

SplashFormRequest.from_response也受到支持,其工作方式如scrapy文档中所述。

响应

scrapy-splash为Splash请求返回Response子类

  • 对于二进制Splash响应(例如,/render.png响应),返回SplashResponse;

  • 当结果是文本时(例如,/render.html响应),返回SplashTextResponse;

  • 当结果是JSON对象时(例如,/render.json响应或/execute响应,当脚本返回Lua表时),返回SplashJsonResponse。

要使用标准响应类,设置 meta['splash']['dont_process_response']=True 或向 SplashRequest 传递 dont_process_response=True 参数。

所有这些响应都将 response.url 设置为原始请求的 URL(即您要渲染的网站的 URL),而不是请求的 Splash 端点的 URL。真实的 URL 仍然可以作为 response.real_url 获取。

SplashJsonResponse 提供了额外的功能

  • response.data 属性包含从 JSON 解码的响应数据;您可以像 response.data['html'] 这样访问它。

  • 如果配置了 Splash 会话处理,您可以通过 response.cookiejar 访问当前 cookie;它是一个 CookieJar 实例。

  • 如果请求中启用了 Scrapy-Splash 响应魔法(默认),则几个响应属性(标题、正文、URL、状态码)将自动从原始响应体中设置

    • 响应头部从headers键填充;

    • 响应的URL设置为url键的值;

    • 响应正文设置为html键的值,或body键的base64解码值;

    • response.status 是从 'http_status' 键的值设置的。

当在 SplashJsonResponse 中更新 response.body 时(无论是从 'html' 还是 'body' 键),可以使用熟悉的 response.cssresponse.xpath 方法。

要关闭对 JSON 结果键的特殊处理,要么设置 meta['splash']['magic_response']=False,要么向 SplashRequest 传递 magic_response=False 参数。

会话处理

Splash 本身是无状态的 - 每个请求都是从干净状态开始的。为了支持会话,需要以下内容

  1. 客户端(Scrapy)必须将当前 cookie 发送到 Splash;

  2. Splash 脚本应使用这些 cookie 进行请求,并从 HTTP 响应头或 JavaScript 代码中更新它们;

  3. 更新的 cookie 应发送回客户端;

  4. 客户端应将当前 cookie 与更新的 cookie 合并。

为了 (2) 和 (3),Splash 为 Splash Lua 脚本提供了 splash:get_cookies()splash:init_cookies() 方法。

scrapy-splash 为 (1) 和 (4) 提供了辅助工具:要在 'cookies' 字段中发送当前 cookie 并从 'cookies' 响应字段中合并 cookie,将 request.meta['splash']['session_id'] 设置为会话标识符。如果您只想使用单个会话,则对所有请求使用相同的 session_id;任何值如 '1' 或 'foo' 都可以。

为了使 scrapy-splash 会话处理正常工作,您必须使用 /execute 端点和接受 'cookies' 参数并返回 'cookies' 字段的结果的 Lua 脚本。

function main(splash)
    splash:init_cookies(splash.args.cookies)

    -- ... your script

    return {
        cookies = splash:get_cookies(),
        -- ... other results, e.g. html
    }
end

SplashRequest 会自动为 /execute 端点设置 session_id,即如果使用 SplashRequest、/execute 端点和兼容的 Lua 渲染脚本,则默认启用 cookie 处理。

如果您想从相同的 cookie 集合开始,但后来“分叉”会话,则在 session_id 之外设置 request.meta['splash']['new_session_id']。请求 cookie 将从 session_id cookiejar 中获取,但响应 cookie 将合并回 new_session_id cookiejar。

可以与 SplashRequest 一起使用标准的 Scrapy cookies 参数来向当前 Splash cookiejar 添加 cookie。

示例

获取 HTML 内容

import scrapy
from scrapy_splash import SplashRequest

class MySpider(scrapy.Spider):
    start_urls = ["http://example.com", "http://example.com/foo"]

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url, self.parse, args={'wait': 0.5})

    def parse(self, response):
        # response.body is a result of render.html call; it
        # contains HTML processed by a browser.
        # ...

获取 HTML 内容和屏幕截图

import json
import base64
import scrapy
from scrapy_splash import SplashRequest

class MySpider(scrapy.Spider):

    # ...
        splash_args = {
            'html': 1,
            'png': 1,
            'width': 600,
            'render_all': 1,
        }
        yield SplashRequest(url, self.parse_result, endpoint='render.json',
                            args=splash_args)

    # ...
    def parse_result(self, response):
        # magic responses are turned ON by default,
        # so the result under 'html' key is available as response.body
        html = response.body

        # you can also query the html result as usual
        title = response.css('title').extract_first()

        # full decoded JSON data is available as response.data:
        png_bytes = base64.b64decode(response.data['png'])

        # ...

运行简单的 Splash Lua 脚本

import json
import base64
from scrapy_splash import SplashRequest


class MySpider(scrapy.Spider):

    # ...
        script = """
        function main(splash)
            assert(splash:go(splash.args.url))
            return splash:evaljs("document.title")
        end
        """
        yield SplashRequest(url, self.parse_result, endpoint='execute',
                            args={'lua_source': script})

    # ...
    def parse_result(self, response):
        doc_title = response.text
        # ...

更复杂的 Splash Lua 脚本 示例 - 通过 CSS 选择器获取 HTML 元素的屏幕截图(需要 Splash 2.1+)。注意如何将参数传递给脚本

import json
import base64
from scrapy_splash import SplashRequest

script = """
-- Arguments:
-- * url - URL to render;
-- * css - CSS selector to render;
-- * pad - screenshot padding size.

-- this function adds padding around region
function pad(r, pad)
  return {r[1]-pad, r[2]-pad, r[3]+pad, r[4]+pad}
end

-- main script
function main(splash)

  -- this function returns element bounding box
  local get_bbox = splash:jsfunc([[
    function(css) {
      var el = document.querySelector(css);
      var r = el.getBoundingClientRect();
      return [r.left, r.top, r.right, r.bottom];
    }
  ]])

  assert(splash:go(splash.args.url))
  assert(splash:wait(0.5))

  -- don't crop image by a viewport
  splash:set_viewport_full()

  local region = pad(get_bbox(splash.args.css), splash.args.pad)
  return splash:png{region=region}
end
"""

class MySpider(scrapy.Spider):


    # ...
        yield SplashRequest(url, self.parse_element_screenshot,
            endpoint='execute',
            args={
                'lua_source': script,
                'pad': 32,
                'css': 'a.title'
            }
         )

    # ...
    def parse_element_screenshot(self, response):
        image_data = response.body  # binary image data in PNG format
        # ...

使用Lua脚本获取带有cookies、headers、body和正确设置方法的HTML响应;lua_source参数值在Splash服务器上缓存,不会随每个请求发送(需要Splash 2.1+)

import scrapy
from scrapy_splash import SplashRequest

script = """
function main(splash)
  splash:init_cookies(splash.args.cookies)
  assert(splash:go{
    splash.args.url,
    headers=splash.args.headers,
    http_method=splash.args.http_method,
    body=splash.args.body,
    })
  assert(splash:wait(0.5))

  local entries = splash:history()
  local last_response = entries[#entries].response
  return {
    url = splash:url(),
    headers = last_response.headers,
    http_status = last_response.status,
    cookies = splash:get_cookies(),
    html = splash:html(),
  }
end
"""

class MySpider(scrapy.Spider):


    # ...
        yield SplashRequest(url, self.parse_result,
            endpoint='execute',
            cache_args=['lua_source'],
            args={'lua_source': script},
            headers={'X-My-Header': 'value'},
        )

    def parse_result(self, response):
        # here response.body contains result HTML;
        # response.headers are filled with headers from last
        # web page loaded to Splash;
        # cookies from all responses and from JavaScript are collected
        # and put into Set-Cookie response header, so that Scrapy
        # can remember them.

HTTP基本认证

如果您需要使用HTTP基本认证访问Splash,请使用SPLASH_USERSPLASH_PASS可选设置

SPLASH_USER = 'user'
SPLASH_PASS = 'userpass'

另一种选项是meta['splash']['splash_headers']:它允许设置发送到Splash服务器的自定义headers;如果您想按请求更改凭据,请将Authorization header添加到splash_headers

import scrapy
from w3lib.http import basic_auth_header

class MySpider(scrapy.Spider):
    # ...
    def start_requests(self):
        auth = basic_auth_header('user', 'userpass')
        yield SplashRequest(url, self.parse,
                            splash_headers={'Authorization': auth})

警告:不要使用HttpAuthMiddleware(即http_user / http_pass 爬虫属性)进行Splash认证:如果您偶尔从您的爬虫发送非Splash请求,可能会将Splash凭据暴露给远程网站,因为HttpAuthMiddleware无条件地为所有请求设置凭据。

为什么不直接使用Splash HTTP API呢?

scrapy-splash的明显替代方案是直接向Splash HTTP API 发送请求。查看下面的示例,并确保阅读其后的观察结果

import json

import scrapy
from scrapy.http.headers import Headers

RENDER_HTML_URL = "http://127.0.0.1:8050/render.html"

class MySpider(scrapy.Spider):
    start_urls = ["http://example.com", "http://example.com/foo"]

    def start_requests(self):
        for url in self.start_urls:
            body = json.dumps({"url": url, "wait": 0.5}, sort_keys=True)
            headers = Headers({'Content-Type': 'application/json'})
            yield scrapy.Request(RENDER_HTML_URL, self.parse, method="POST",
                                 body=body, headers=headers)

    def parse(self, response):
        # response.body is a result of render.html call; it
        # contains HTML processed by a browser.
        # ...

它工作得很好,并且足够简单,但有一些问题您应该注意

  1. 有一些样板代码。

  2. 从Scrapy的角度来看,我们正在向RENDER_HTML_URL发送请求,而不是目标URL。它影响并发和礼貌设置:CONCURRENT_REQUESTS_PER_DOMAINDOWNLOAD_DELAY等可能会以意想不到的方式表现,因为延迟和并发设置不再是按域设置的。

  3. 从Scrapy的角度来看,response.url是Splash服务器的URL。scrapy-splash将其修复为请求页面的URL。“真实”URL仍然可以通过response.real_url获得。scrapy-splash还允许在Scrapy端透明地处理response.statusresponse.headers

  4. 一些选项相互依赖 - 例如,如果您使用timeout Splash选项,那么您可能还想设置download_timeout scrapy.Request元数据键。

  5. 很容易出错 - 例如,如果您在准备JSON body时不使用sort_keys=True参数,那么即使所有键和值都相同,二进制POST body内容也可能不同,这意味着dupefilter和cache将无法正常工作。

  6. 默认的Scrapy重复过滤器没有考虑Splash的具体情况。例如,如果URL在JSON POST请求体中发送,Scrapy将计算请求指纹而不规范化此URL。

  7. Splash错误请求(HTTP 400)错误难以调试,因为默认情况下Scrapy不会显示响应内容。SplashMiddleware默认情况下会记录HTTP 400 Splash响应的内容(可以通过设置SPLASH_LOG_400 = False选项关闭)。

  8. 处理cookie很繁琐,并且在与Splash一起工作时不能使用Scrapy内置的Cookie中间件来处理cookie。

  9. 不会随每个请求改变的大Splash参数(例如lua_source)在保存到Scrapy磁盘请求队列时可能会占用大量空间。scrapy-splash提供了一种仅保存一次此类静态参数的方法。

  10. Splash 2.1+提供了一种通过在服务器上缓存大型静态参数来节省网络流量的方式,但这需要客户端支持:客户端应发送适当的save_argsload_args值,并处理HTTP 498响应。

scrapy-splash 工具允许处理此类边缘情况并减少样板代码。

获取帮助

获取任何其他帮助的最佳方法是在 Stack Overflow 上提问

贡献

源代码和错误跟踪器在 github 上:https://github.com/scrapy-plugins/scrapy-splash

要运行测试,安装“tox”Python 包,然后从源代码签出处运行 tox 命令。

要运行集成测试,启动 Splash 并在运行 tox 命令之前设置 SPLASH_URL 环境变量为 Splash 地址。

docker run -d --rm -p8050:8050 scrapinghub/splash:3.0
SPLASH_URL=http://127.0.0.1:8050 tox -e py36

更改

0.9.0 (2023-02-03)

  • 移除了对 Python 2.7、3.4、3.5 和 3.6 的官方支持,并添加了对 Python 3.9、3.10 和 3.11 的官方支持。

  • 弃用了 SplashJsonResponse.body_as_unicode(),将被 SplashJsonResponse.text 替换。

  • 移除了对已废弃的 to_native_str 的调用,Scrapy 2.8 中已移除。

0.8.0 (2021-10-05)

  • 安全漏洞修复

    如果您使用 HttpAuthMiddleware(即 http_userhttp_pass 爬虫属性)进行 Splash 认证,则任何非 Splash 请求都会将您的凭据暴露给请求目标。这包括当 ROBOTSTXT_OBEY 设置为 True 时,Scrapy 发送的 robots.txt 请求。

    请使用新的 SPLASH_USERSPLASH_PASS 设置来安全地设置您的 Splash 认证凭据。

  • 响应现在暴露了来自 Splash 的 HTTP 状态码和头信息,作为 response.splash_response_statusresponse.splash_response_headers (#158)

  • 传递给 scrapy_splash.request.SplashRequest 构造函数的 meta 参数不再修改 (#164)

  • HTTP 状态码为 400 或 498 的网站响应不再被处理为等效的 Splash 响应 (#158)

  • 不再向 Splash 本身发送 Cookie (#156)

  • scrapy_splash.utils.dict_hash 现在也支持 obj=None (225793b)

  • 我们的测试套件现在包括集成测试 (#156),并且可以并行运行测试 (6fb8c41)

  • README.rst 文件中新增了“获取帮助”部分 (#161, #162),改进了关于 SPLASH_SLOT_POLICY 的文档 (#157),并修正了一个错误 (#121)

  • 进行了一些内部改进 (ee5000d, 25de545, 2aaa79d)

0.7.2 (2017-03-30)

  • 修复了响应类型检测问题。

0.7.1 (2016-12-20)

  • Scrapy 1.0.x 支持 已恢复;

  • 更新 README。

0.7 (2016-05-16)

  • SPLASH_COOKIES_DEBUG 设置允许在 cookies 请求/响应字段中记录发送和接收给/从 Splash 的 Cookie。它与 Scrapy 的内置 COOKIES_DEBUG 类似,但适用于 Splash 请求;

  • 清理 README。

0.6.1 (2016-04-29)

  • 对于非 Splash 请求不再记录有关 HTTP 方法的警告。

0.6 (2016-04-20)

  • SplashAwareDupeFiltersplash_request_fingerprint 得到改进:它们现在规范 URL 并考虑 URL 片段;

  • cache_args 值指纹现在计算速度更快。

0.5 (2016-04-18)

  • cache_args SplashRequest 参数和 request.meta['splash']['cache_args'] 键允许通过不在磁盘请求队列中存储重复的 Splash 参数以及不多次将它们发送到 Splash 来节省网络流量和磁盘存储。此功能需要 Splash 2.1+。

要从 v0.4 升级,请在 settings.py 中启用 SplashDeduplicateArgsMiddleware

SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

0.4 (2016-04-14)

  • 添加了 SplashFormRequest 类;它是一种使用 Splash 的 FormRequest 变体;

  • Splash 参数不再在 request.meta 中存储两次;此更改应减少磁盘队列数据大小;

  • SplashMiddleware 现在在重新调度请求时增加请求优先级;这应该减少磁盘队列数据大小并有助于处理过期的 cookie 问题。

0.3 (2016-04-11)

包名称已从 scrapyjs 更名为 scrapy-splash

升级的最简单方法是替换 scrapyjs 导入为 scrapy_splash,并更新 settings.py 中的新默认值(请参阅 README)。

有许多新的助手来透明地处理 JavaScript 渲染;现在推荐使用 scrapy_splash.SplashRequest 而不是 request.meta['splash']。如果您是从 scrapyjs 升级,请务必阅读 README - 您可能能够从项目中删除一些代码,尤其是如果您想访问响应 html、处理 cookie 和头部。

  • 新增了 SplashRequest 类;它可以作为 scrapy.Request 的替代品,以提供更好的与 Splash 的集成;

  • 添加了对 POST 请求的支持;

  • SplashResponse、SplashTextResponse 和 SplashJsonResponse 允许透明地处理 Splash 响应,处理 response.url、response.body、response.headers 和 response.status。SplashJsonResponse 允许将解码后的响应 JSON 数据作为 response.data 访问。

  • cookie 处理改进:现在可以透明地处理 Scrapy 和 Splash cookie;当前的 cookiejar 作为 response.cookiejar 暴露;

  • 默认情况下将头部传递给 Splash;

  • 在使用 SplashRequest 时自动处理带有片段的 URL;

  • 日志改进:SplashRequest.__repr__ 显示请求的 URL 和 Splash URL;

  • 默认情况下,当发生 Splash HTTP 400 错误时,响应会被记录;

  • 修复了 dupefilters 的问题:之前 JSON 请求体中键的顺序可能不同,使得请求看起来不是重复的;

  • 现在可以向 Splash 服务器本身传递自定义头部;

  • 启用了测试覆盖率报告。

0.2 (2016-03-26)

0.1.1 (2015-03-16)

修复了非字符串元值指纹计算的问题。

0.1 (2015-02-28)

初始发布

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码发行版

scrapy-splash-0.9.0.tar.gz (59.6 kB 查看哈希)

上传时间 源代码

构建发行版

scrapy_splash-0.9.0-py2.py3-none-any.whl (27.2 kB 查看哈希)

上传时间 Python 2 Python 3

支持者