ScrapyとSplashでのセッションハンドリング
Splashのセッションハンドリング
Splashのみで利用する場合はSelenium同様、内部的に動作するHeadlessブラウザ(Chromium)がセッションハンドリングを行うため、同一のLuaスクリプト内で記述する範囲では意識しなくてもステートは維持されている。
ScrapyとSplashの間
SplashはScrapyからのリクエスト毎にステートレスなので、ScrapyとLuaスクリプトの間でセッションハンドリングが必要になる。
scrapy-splashに説明がある。
セッションハンドリング
Splash itself is stateless - each request starts from a clean state. In order to support sessions the following is required:
- client (Scrapy) must send current cookies to Splash;
- Splash script should make requests using these cookies and update them from HTTP response headers or JavaScript code;
- updated cookies should be sent back to the client;
- client should merge current cookies wiht the updated cookies.
For (2) and (3) Splash provides splash:get_cookies() and splash:init_cookies() methods which can be used in Splash Lua scripts.
Splashはステートレスなので、状態を維持するためのコーディングが必要。
- ScrapyからSplashにCookieを送らなくてはならない
- SplashスクリプトはCookieを使って操作し、Cookieをアップデートする
- アップデートしたCookieをScrapyに返す
- Scrapyは受け取ったCookieをマージする
scrapy-splash provides helpers for (1) and (4): to send current cookies in ‘cookies’ field and merge cookies back from ‘cookies’ response field set request.meta[‘splash’][‘session_id’] to the session identifier. If you only want a single session use the same session_id for all request; any value like ‘1’ or ‘foo’ is fine.
scrapy-splashが自動的にCookie情報をセッション識別子としてrequest.meta['splash']['session_id']
にマージする。
For scrapy-splash session handling to work you must use /execute endpoint and a Lua script which accepts ‘cookies’ argument and returns ‘cookies’ field in the result:
このセッションハンドリングを有効にするには/execute
エンドポイントを使用し、cookies
パラメーターを使用する処理をLuaスクリプトで実装する必要がある。
1 | function main(splash) |
SplashRequest sets session_id automatically for /execute endpoint, i.e. cookie handling is enabled by default if you use SplashRequest, /execute endpoint and a compatible Lua rendering script.
SplashRequestで/execute
エンドポイントを使い、適切なLuaスクリプトを記述すれば、セッションハンドリングを実装することができる。
Splash経由でのresponseの構造
All these responses set response.url to the URL of the original request (i.e. to the URL of a website you want to render), not to the URL of the requested Splash endpoint. “True” URL is still available as response.real_url.
plashJsonResponse provide extra features:
- response.data attribute contains response data decoded from JSON; you can access it like response.data[‘html’].
- If Splash session handling is configured, you can access current cookies as response.cookiejar; it is a CookieJar instance.
- If Scrapy-Splash response magic is enabled in request (default), several response attributes (headers, body, url, status code) are set automatically from original response body:
- response.headers are filled from ‘headers’ keys;
- response.url is set to the value of ‘url’ key;
- response.body is set to the value of ‘html’ key, or to base64-decoded value of ‘body’ key;
- response.status is set from the value of ‘http_status’ key.
response.url
はレンダリングするページのURLが設定されるresponse.real_url
はSplashのURL(http://splash:8050/execute
)となるresponse.data
でSplashから返却したデータにアクセスできる- Cookieは
response.cookiejar
でアクセスすることができる。 - Scrapy-Splash response magicで自動的にレンダリングしたページからの応答が設定される
セッションハンドリングのサンプルコード
1 | import scrapy |
リクエストで注目するポイント
重要なポイントは/execute
エンドポイントを使用していること。
argsでLuaスクリプトやパラメーターをSplashに渡す。
1 | yield SplashRequest(url, self.parse_result, |
SplashRequestで渡したパラメーターを使用してCookieを初期化。
1 | splash:init_cookies(splash.args.cookies) |
レスポンスで注目するポイント
最後のレスポンスのヘッダー情報やCookieを返却。
1 | local entries = splash:history() |