2016-12-10 15 views
5

私はPythonでScreamのためのSplashを使っていくつかの動的Webサイトを削り取ろうとしています。しかし、スプラッシュが特定のケースで完全なページが読み込まれるのを待たないことが分かります。この問題に対処するための猛烈な方法は、大量のwait時間(たとえば、以下のスニペットでは5秒)を追加することでした。ただし、これは非常に非効率的で、依然として特定のデータをロードできません(コンテンツのロードに5秒以上かかることがあります)。これらの要求を満たすことができる要素待機状態がありますか?PythonのScrapyでSplashRequestを実行しているときに待機中の要素を追加する

yield SplashRequest(
      url, 
      self.parse, 
      args={'wait': 5}, 
      'User-Agent':"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36", 
      } 
) 

答えて

6

はい、そうするためのLuaスクリプトを書くことができます。そのような何か:スプラッシュ2.3前

function main(splash) 
    splash:set_user_agent(splash.args.ua) 
    assert(splash:go(splash.args.url)) 

    -- requires Splash 2.3 
    while not splash:select('.my-element') do 
    splash:wait(0.1) 
    end 
    return {html=splash:html()} 
end 

あなたがsplash:evaljs('!document.querySelector(".my-element")')代わりのnot splash:select('.my-element')を使用することができます。

このスクリプトを変数(lua_script = """ ... """)に保存します。そして、あなたはこのようにリクエストを送信することができます。

yield SplashRequest(
    url, 
    self.parse, 
    endpoint='execute', 
    args={ 
     'lua_source': lua_script, 
     'ua': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36" 
    } 
} 

は、スプラッシュのLuaスクリプトを作成する方法の詳細については、スクリプトtutorialreferenceを参照してください。

+1

ソリューションに追加するには、上記のスクリプトを実行している間に "nil valueのインデックスを作成しようとしています"というLuaエラーが表示されていました。問題は、要素がまだレンダリングされていない場合、スプラッシュ:select( '。my-element') 'によって返された' nil'値に対して ':exists()'を実行できないという問題でした。だから単に ':exists()'の部分を取り除き、while splash:select( '。my-element')do''のループをチェックすることで問題が解決されました。 – NightFury13

+1

良いキャッチ@ NightFury13!私はこの例を変えているので、将来この回答に来る人々はこの問題を起こさないだろう。 –

0

同様の要件があり、タイムアウトがあります。私の解決策は、上記のわずかな変更です:

function wait_css(splash, css, maxwait) 
    if maxwait == nil then 
     maxwait = 10  --default maxwait if not given 
    end 

    local i=0 
    while not splash:select(css) do 
     if i==maxwait then 
      break  --times out at maxwait secs 
     end 
     i=i+1 
     splash:wait(1)  --each loop has duration 1sec 
    end 
end 
関連する問題