2016-04-04 2 views
5

Я использую ScrapyJS и выплеск для имитации отправки формы кнопку мышиScrapyJS - Как правильно подождать загрузки страницы?

def start_requests(self): 
     script = """ 
     function main(splash) 
      assert(splash:autoload("https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")) 
      assert(splash:go(splash.args.url)) 

      local js = [[ 
       var $j = jQuery.noConflict(); 
       $j('#USER').val('frankcastle'); 
       $j('#password').val('punisher'); 
       $j('.button-oblong-orange.button-orange a').click(); 
      ]] 

      assert(splash:runjs(js)) 

      local resumeJs = [[ 
       function main(splash) { 
        var $j = jQuery.noConflict(); 
        $j(document).ready(function(){ 
         splash.resume(); 
        }) 
       } 
      ]] 

     assert(splash:wait_for_resume(resumeJs)) 

      return { 
       html = splash:html() 
      } 
     end 
     """ 
     splash_meta = {'splash': {'endpoint': 'execute', 'args': {'wait': 0.5, 'lua_source': script}}} 

     for url in self.start_urls: 
      yield scrapy.Request(url, self.after_login, meta=splash_meta) 

def after_login(self, response): 
     print response.body 
     return 

После этого splash:runjs(js), я прибегая к splash:wait(5) пытался splash:wait_for_resume, чтобы получить результат. Это может не всегда работать (задержка сети), так есть ли лучший способ?

+1

Довольно уверен, что всплеск позволяет ждать элемент быть видимым –

+0

@PadraicCunningham Пожалуйста, проверьте мой выбор, пытался фурор: wait_for_resume (не уверен, если я делаю это правильно), но не повезло – Krishnaraj

+0

не нашел подобный вопрос - https://github.com/scrapinghub/splash/issues/200 – Krishnaraj

ответ

4

Оказывается, единственный способ - использовать splash:wait(), но сделать это в цикле и проверить наличие некоторого элемента (например, нижнего колонтитула).

def start_requests(self): 
     script = """ 
     function main(splash) 
      assert(splash:autoload("https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")) 
      assert(splash:go(splash.args.url)) 

      local js = [[ 
       var $j = jQuery.noConflict(); 
       $j('#USER').val('frankcastle'); 
       $j('#password').val('punisher'); 
       $j('.button-oblong-orange.button-orange a').click(); 
       $j('body').empty() // clear body, otherwise the wait_for footer will always be true 
      ]] 

      assert(splash:runjs(js)) 

      function wait_for(splash, condition) 
       while not condition() do 
        splash:wait(0.05) 
       end 
      end 

      wait_for(splash, function() 
       return splash:evaljs("document.querySelector('#footer') != null") 
      end) 

      return { 
       html = splash:html() 
      } 
     end 
     """ 
     splash_meta = {'splash': {'endpoint': 'execute', 'args': {'wait': 0.5, 'lua_source': script}}} 

     for url in self.start_urls: 
      yield scrapy.Request(url, self.after_login, meta=splash_meta) 
0

Так что я еще не играл с этим (получил Lua и некоторые успешные попытки с Splash только сегодня).

если вы делаете что-то вроде этого:

recheck = True 

html = splash:html() 
splash:wait(0.5) 
while recheck = True: 
    splash:wait(0.5) 
    html2 = splash:html() 
    if html != html2: 
     pass 
    elif: 
     recheck = False 
     return { 
      html = splash:html(), 
     } 

Собирается использовать подобную вещь для бесконечных страниц прокрутки, которые населяют элементы списка в ответ на свитки (или Page_downs)

Извини за неосведомленности с Lua/Синтаксис всплеска

0

Есть немного лучший способ проверить его, но тем не менее вам нужен цикл с ожиданиями. Идея заключается в использовании splash:on_response(response) в качестве обратного вызова при обновлении страницы. Обратите внимание, что ответный вызов ответа будет вызван async, поэтому основной цикл должен ждать всех изменений страницы, поэтому у нас есть цикл ожидания (например, данный @Krishnaraj).

Ниже приведен пример с нажатием кнопки button_id 10 раз, для загрузки дополнительного контента.

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

    function wait_for(splash, condition) 
     while not condition() do 
      splash:wait(0.2) 
     end 
    end 

    local clicks = 0 

    splash:on_response(function(res) 
     clicks = clicks + 1 

     if clicks < 10 then 
      assert(splash:runjs("document.getElementById(\"button_id\").click();")) 
     end 
    end) 

    assert(splash:runjs("document.getElementById(\"button_id\").click();")) 

    wait_for(splash, function() 
     return clicks >= 10 
    end) 

    return splash:html() 
end 
Смежные вопросы