Scripyフレームの使用のScrpyドッキングSplash
10081 ワード
前のセクションでは、ScrpyドッキングSeleniumがタオバオ商品を取り込む過程を実現しました.これはJavaScriptのダイナミックなページをキャプチャする方式です.Selenium以外にもSplashは同じ機能を実現します.今回はScrpyドッキングSplashによるページキャプチャの方法を理解します.
一、準備工作
Splashが正しくインストールされて正常に動作していることを確認してください.Slapy-splashライブラリをインストールします.
二、新規プロジェクト
まず新しいプロジェクトを作成します.scrapysplshtestといいます.コマンドは以下の通りです.
Scrpy-splashの構成説明を参考にして、一歩ずつの構成ができます.リンクは以下の通りです.https://github.com/scrapy-plugins/scrapy-splash#configuration.
settings.pyを変更し、
また、
設定が完了したら、Splashを利用してページをつかむことができます.
次のような例を示します.
また、Requestオブジェクトを生成することもできます.Splashの構成は
今回のスナップショットは淘宝商品の情報です.ページのロード待ち、ページのめくりなどの操作に関連しています.まずLuaスクリプトを定義して、ページのロード、アナログクリックでページをめくる機能を実現できます.コードは下記の通りです.
ページをめくる作業も成功しました.下の図のように現在のページ番号です.私達が入ってきたページ番号
私たちはSpiderの中でLuaスクリプトを
他の構成は変更する必要はありません.Item、Item Pipelineなどの設定は前のセッションSeleniumと同じです.
五、運行
次に、以下の命令で爬虫類を実行します.
SplashとScripyは非同期処理をサポートしていますので、同時に複数のキャプチャ成功の結果が見られます.Seleniumのドッキング中に、各ページのレンダリングダウンロードはDownloader Middlewareで行われますので、全体のプロセスはブロックされています.Scripyは、このプロセスが完了するのを待って他の要求を処理し、スケジュールすることができます.これは登山の効率に影響します.そのためSplashを使って登るのはSeleniumより効率が高いです.
最後にもう一度MongoDBの結果を見ます.下の図のように.
結果は同様にMongoDBに正常に保存されています.
六、本節コード
このセクションのコードアドレスは:https://github.com/Python3WebSpider/ScrapySplashTest.
おわりに
したがって、Scripyでは、JavaScript動的にレンダリングされたページをSplashで処理することが推奨されている.このようにScripyにおける非同期処理の過程を破壊することなく、登用効率を大幅に向上させます.またSplashの設置と配置は比較的簡単であり、API呼び出しによりモジュール分離が実現され、大規模なウォーキングの配置もより便利である.
一、準備工作
Splashが正しくインストールされて正常に動作していることを確認してください.Slapy-splashライブラリをインストールします.
二、新規プロジェクト
まず新しいプロジェクトを作成します.scrapysplshtestといいます.コマンドは以下の通りです.
scrapy startproject scrapysplashtest
新しいSpiderを作成します.コマンドは以下の通りです.scrapy genspider taobao www.taobao.com
三、設定を追加するScrpy-splashの構成説明を参考にして、一歩ずつの構成ができます.リンクは以下の通りです.https://github.com/scrapy-plugins/scrapy-splash#configuration.
settings.pyを変更し、
SPLASH_URL
を構成する.ここで私達のSplashは当地で運行していますので、直接地元の住所を設定できます.SPLASH_URL = 'http://localhost:8050'
Splashがリモートサーバで実行されている場合、ここはリモートのアドレスに設定されるべきです.例えば、IPが120.27.34.25のサーバ上で実行される場合、ここでは以下のように構成されるべきである.SPLASH_URL = 'http://120.27.34.25:8050'
いくつかのMiddlewareを配置する必要があります.コードは以下の通りです.DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
ここには三つのDownloader Middlewareと一つのSpider Middlewareが配置されています.これはScripy-splashの中心部分です.私達はもうドッキングSeleniumのようにDownloader Middlewareを実現する必要がありません.Scripy-splashライブラリは全部私達のために準備しました.直接配置すればいいです.また、
DUPEFILTER_CLASS
の重いクラスを構成する必要があります.コードは以下の通りです.DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
最後に1つのCacheを構成してHTTPCACHE_STORAGE
を記憶し、コードは以下の通りである.HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
四、新規要求設定が完了したら、Splashを利用してページをつかむことができます.
SplashRequest
オブジェクトを直接生成して、対応するパラメータを渡すことができます.Scrpyはこの要求をSplashに転送し、Splashはページをレンダリングしてロードし、レンダリング結果を戻します.この時のResonseの内容はレンダリングが完了したページの結果です.最後にSpiderに解析してください.次のような例を示します.
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='' , # optional; overrides SPLASH_URL
)
ここでは、SplashRequest
オブジェクトが構築されており、最初の2つのパラメータは依然として要求されたURLとコールバック関数である.また、args
を介して、待ち時間wait
などのレンダリングパラメータを伝えることもでき、endpoint
パラメータに従ってレンダリングインターフェースを指定することもできます.詳細なパラメータは文書の説明を参照できます.https://github.com/scrapy-plugins/scrapy-splash#requests. また、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': '' , # 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
}
})
SplashRequest
オブジェクトはargs
によって構成され、かつRequestオブジェクトはmeta
によって構成され、両方の方法で達成される効果は同じである.今回のスナップショットは淘宝商品の情報です.ページのロード待ち、ページのめくりなどの操作に関連しています.まずLuaスクリプトを定義して、ページのロード、アナログクリックでページをめくる機能を実現できます.コードは下記の通りです.
function main(splash, args)
args = {
url="https://s.taobao.com/search?q=iPad",
wait=5,
page=5
}
splash.images_enabled = false
assert(splash:go(args.url))
assert(splash:wait(args.wait))
js = string.format("document.querySelector('#mainsrp-pager div.form > input').value=%d;document.querySelector('#mainsrp-pager div.form > span.btn.J_Submit').click()", args.page)
splash:evaljs(js)
assert(splash:wait(args.wait))
return splash:png()
end
要求されたリンクurl
、待ち時間wait
、改ページページページ番号page
の3つのパラメータを定義した.その後、画像のロードを無効にし、タオバオの商品リストページを要求し、evaljs()
方法でJavaScriptコードを呼び出し、ページ番号の充填とページクリックを実現し、最後にスクリーンショットに戻る.スクリプトをSplashに置いて実行します.正常にページのスクリーンショットを取得しました.下の図のように.ページをめくる作業も成功しました.下の図のように現在のページ番号です.私達が入ってきたページ番号
page
のパラメータと同じです.私たちはSpiderの中でLuaスクリプトを
SplashRequest
でドッキングするだけでいいです.次のようにします.from scrapy import Spider
from urllib.parse import quote
from scrapysplashtest.items import ProductItem
from scrapy_splash import SplashRequest
script = """
function main(splash, args)
splash.images_enabled = false
assert(splash:go(args.url))
assert(splash:wait(args.wait))
js = string.format("document.querySelector('#mainsrp-pager div.form > input').value=%d;document.querySelector('#mainsrp-pager div.form > span.btn.J_Submit').click()", args.page)
splash:evaljs(js)
assert(splash:wait(args.wait))
return splash:html()
end
"""
class TaobaoSpider(Spider):
name = 'taobao'
allowed_domains = ['www.taobao.com']
base_url = 'https://s.taobao.com/search?q='
def start_requests(self):
for keyword in self.settings.get('KEYWORDS'):
for page in range(1, self.settings.get('MAX_PAGE') + 1):
url = self.base_url + quote(keyword)
yield SplashRequest(url, callback=self.parse, endpoint='execute', args={'lua_source': script, 'page': page, 'wait': 7})
Luaスクリプトを成長文字列として定義し、SplashRequest
のargs
を介してパラメータを伝達し、インタフェースをexecute
に修正した.また、args
パラメータには、Luaスクリプトの内容を指定するためのlua_source
フィールドがあります.これにより、SplashRequest
を構成することに成功し、Splashとのドッキングが完了しました.他の構成は変更する必要はありません.Item、Item Pipelineなどの設定は前のセッションSeleniumと同じです.
parse()
コールバック関数も完全に一致しています.五、運行
次に、以下の命令で爬虫類を実行します.
scrapy crawl taobao
運転結果は下図のようになります.SplashとScripyは非同期処理をサポートしていますので、同時に複数のキャプチャ成功の結果が見られます.Seleniumのドッキング中に、各ページのレンダリングダウンロードはDownloader Middlewareで行われますので、全体のプロセスはブロックされています.Scripyは、このプロセスが完了するのを待って他の要求を処理し、スケジュールすることができます.これは登山の効率に影響します.そのためSplashを使って登るのはSeleniumより効率が高いです.
最後にもう一度MongoDBの結果を見ます.下の図のように.
結果は同様にMongoDBに正常に保存されています.
六、本節コード
このセクションのコードアドレスは:https://github.com/Python3WebSpider/ScrapySplashTest.
おわりに
したがって、Scripyでは、JavaScript動的にレンダリングされたページをSplashで処理することが推奨されている.このようにScripyにおける非同期処理の過程を破壊することなく、登用効率を大幅に向上させます.またSplashの設置と配置は比較的簡単であり、API呼び出しによりモジュール分離が実現され、大規模なウォーキングの配置もより便利である.