Splash的JavaScript支持,用于Scrapy
项目描述
此库提供了使用Scrapy和Splash进行JavaScript集成的功能。许可证是BSD 3条款。
安装
使用pip安装ScrapyJS
$ pip install scrapyjs
ScrapyJS使用Splash HTTP API,因此您还需要一个Splash实例。通常安装和运行Splash,以下内容就足够了
$ docker run -p 8050:8050 scrapinghub/splash
检查 Splash 安装文档 获取更多信息。
配置
将 Splash 服务器地址添加到 Scrapy 项目的 settings.py 中,如下所示:
SPLASH_URL = 'http://192.168.59.103:8050'
通过将其添加到 settings.py 文件中的 DOWNLOADER_MIDDLEWARES 来启用 Splash 中间件
DOWNLOADER_MIDDLEWARES = { 'scrapyjs.SplashMiddleware': 725, }
设置自定义 DUPEFILTER_CLASS
DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'
如果你使用 Scrapy HTTP 缓存,则需要自定义缓存存储后端。ScrapyJS 提供了 scrapy.contrib.httpcache.FilesystemCacheStorage 的子类。
HTTPCACHE_STORAGE = 'scrapyjs.SplashAwareFSCacheStorage'
如果你使用其他缓存存储,则需要将其子类化,并将所有 scrapy.util.request.request_fingerprint 调用替换为 scrapyjs.splash_request_fingerprint。
使用方法
要使用 Splash 渲染请求,请使用 'splash' 请求 meta 键
yield Request(url, self.parse_result, meta={ 'splash': { 'args': { # set rendering arguments here 'html': 1, 'png': 1, # 'url' is prefilled from request url }, # optional parameters 'endpoint': 'render.json', # optional; default is render.json 'splash_url': '<url>', # overrides SPLASH_URL 'slot_policy': scrapyjs.SlotPolicy.PER_DOMAIN, } })
meta['splash']['args'] 包含发送给 Splash 的参数。ScrapyJS 会自动将请求的 url 添加到这些参数中。
请注意,默认情况下 Scrapy 使用 AJAX 转义方案转义 URL 片段。如果你想将带有片段的 URL 传递给 Splash,请手动在 args 字典中设置 url。
meta['splash']['endpoint'] 是要使用的 Splash 端点。默认情况下使用 render.json。
有关可用端点和参数的完整列表,请参阅 Splash HTTP API 文档。
meta['splash']['splash_url'] 覆盖了在 settings.py 中设置的 Splash URL。
meta['splash']['slot_policy'] 用于自定义维护 Splash 请求的并发性和礼貌性的方式。
目前有 3 种策略可用
scrapyjs.SlotPolicy.PER_DOMAIN (默认) - 根据正在渲染的 URL 向下载器槽位发送 Splash 请求。如果你想保持每个域的礼貌性和并发设置,这很有用。
scrapyjs.SlotPolicy.SINGLE_SLOT - 向单个下载器槽位发送所有 Splash 请求。如果你想限制对 Splash 的请求,这很有用。
scrapyjs.SlotPolicy.SCRAPY_DEFAULT - 不对槽位做任何事情。这与 SINGLE_SLOT 策略类似,但如果您访问与 Splash 相同地址上的其他服务,则可能会有所不同。
示例
获取 HTML 内容
import scrapy class MySpider(scrapy.Spider): start_urls = ["http://example.com", "http://example.com/foo"] def start_requests(self): for url in self.start_urls: yield scrapy.Request(url, self.parse, meta={ 'splash': { 'endpoint': 'render.html', '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 class MySpider(scrapy.Spider): # ... yield scrapy.Request(url, self.parse_result, meta={ 'splash': { 'args': { 'html': 1, 'png': 1, 'width': 600, 'render_all': 1, } } }) # ... def parse_result(self, response): data = json.loads(response.body_as_unicode()) body = data['html'] png_bytes = base64.b64decode(data['png']) # ...
运行简单的 Splash Lua 脚本
import json import base64 class MySpider(scrapy.Spider): # ... script = """ function main(splash) assert(splash:go(splash.args.url)) return splash:evaljs("document.title") end """ yield scrapy.Request(url, self.parse_result, meta={ 'splash': { 'args': {'lua_source': script}, 'endpoint': 'execute', } }) # ... def parse_response(self, response): doc_title = response.body_as_unicode() # ...
HTTP 基本认证
如果您需要使用 HTTP 基本认证访问 Splash,请使用 Scrapy 的 HttpAuthMiddleware。
为什么不直接使用 Splash HTTP API 呢?
ScrapyJS 的明显替代方案是直接向 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}) 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. # ...
它工作得很好,而且足够简单,但有一些问题你应该注意
有一些样板代码。
从 Scrapy 的角度来看,我们正在向 RENDER_HTML_URL 而不是目标 URL 发送请求。它影响了并发性和礼貌性设置:CONCURRENT_REQUESTS_PER_DOMAIN、DOWNLOAD_DELAY 等可能会以预期之外的方式表现,因为延迟和并发设置不再是按域的。
一些选项相互依赖 - 例如,如果您使用 timeout Splash 选项,那么您可能还想设置 download_timeout scrapy.Request 元数据键。
ScrapyJS 工具允许处理此类边缘情况并减少模板代码。
贡献
源代码和错误跟踪器在github上: https://github.com/scrapy-plugins/scrapy-splash
要运行测试,安装“tox”Python包,然后从源代码签出中运行 tox 命令。
更改
0.2 (2016-03-26)
Scrapy 1.0 和 1.1 支持;
Python 3 支持;
文档改进;
0.1.1 (2015-03-16)
修复了非字符串元值的指纹计算问题。
0.1 (2015-02-28)
初始发布
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源代码分发
构建分发
scrapyjs-0.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1833ea816daaa91c362c7d1c86d8f97269f70cbfdf783b2b946378936e944057 |
|
MD5 | b6d9c3d1f20a461543e4d0d871d82572 |
|
BLAKE2b-256 | 897315a3cb81e96438a2e7ced2a1938a9dd9b798d633e9c7c84f1d31dd6e8812 |
scrapyjs-0.2-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2c0000d40d6c081360757c578fd70fa997f8b548b8083d06f6b2eca94935d150 |
|
MD5 | 59912f0495e92811212db93ac66a70d1 |
|
BLAKE2b-256 | 1a5fdcfb268903063cc8265e86f211e3e2d03cb05fe37bf8e6531fa6f4a8921f |