2016-12-10 12 views
5

Python'da Splash for Scrapy kullanarak birkaç dinamik web sitesi kazımayı deniyorum. Ancak, Splash'in tüm sayfaların belirli durumlarda yüklenmesini beklemediğini görüyorum. Bu sorunu çözmek için kaba bir güç yolu, büyük bir wait zaman eklemek (örneğin aşağıdaki snippet'te 5 saniye) oldu. Bununla birlikte, bu son derece verimsizdir ve yine de belirli verileri yüklemekte başarısız olur (bazen içeriği yüklemek için 5 saniyeden uzun sürer). Bu istekler aracılığıyla verilebilecek bir öğe için bekle bir koşul var mı?Python'da bir SplashRequest gerçekleştirirken öğe için bekletme Scrapy

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", 
      } 
) 

cevap

6

Evet, bunu yapmak için bir Lua komut dosyası yazabilirsiniz. Bunun gibi bir şey:

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 2.3 önce yerine not splash:select('.my-element') ait splash:evaljs('!document.querySelector(".my-element")') kullanabilirsiniz.

Bu komut dosyasını bir değişkene kaydedin (lua_script = """ ... """). Sonra böyle bir istek gönderebilir:

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" 
    } 
} 

Bkz komut tutorial ve reference Splash Lua komut yazma konusunda daha fazla ayrıntı için.

+1

çözümüne eklemek için, yukarıdaki komut dosyası çalışırken "endeks nil değerine girişimi" belirten Lua-hataları almak oldu. Sorun şudur:: (var)() 'sıçrama tarafından döndürülen 'nil' değerinde çalıştırılamaz: select ('. My-element')' elemanın henüz işlenmemiş olması. Yani sadece: '(var)() bölümü ile uğraşmak ve sıçrama değilken döngüleri kontrol etmek: seçmek ('. Benim elemanım ') benim için sorunu çözdüm. – NightFury13

+1

İyi bir yakalama @ NightFury13! Örneği değiştiriyorum, böylece gelecekte bu cevaba gelen insanlar bu sorunu alamayacaklar. –

0

Zaman aşımları ile benzer bir gereksinime sahibim. Benim çözümüm yukarıda hafif bir değişikliktir:

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