2016-12-10 14 views
5

Я пытаюсь очистить несколько динамических сайтов, используя Splash for Scrapy в python. Однако я вижу, что Splash не может дождаться загрузки полной страницы в определенных случаях. Скорее всего, для решения этой проблемы необходимо добавить большое время wait (например, 5 секунд в нижеприведенном фрагменте). Однако это крайне неэффективно и по-прежнему не загружает определенные данные (иногда загрузка занимает более 5 секунд). Есть ли какое-то условие ожидания для элемента, которое может быть выполнено через эти запросы?Добавление ожидания для элемента при выполнении SplashRequest в python 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", 
      } 
) 

ответ

6

Да, вы можете написать сценарий Lua для этого. Нечто подобное:

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 

Перед Всплеск 2.3 вы можете использовать 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" 
    } 
} 

См был tutorial и reference для получения более подробной информации о том, как писать сценарии Всплеск Lua.

+1

Чтобы добавить к решению, я получал Lua-ошибки, в которых указывалось «попытка индексировать значение nil» при запуске вышеуказанного скрипта. Проблема заключалась в том, что ': exists()' не может быть запущено на значение 'nil', возвращаемое' splash: select ('. My-element') 'incase, что элемент еще не был отображен. Поэтому просто избавиться от части ': exists()' и проверить цикл для 'while not splash: select ('. My-element') действительно решает проблему для меня. – 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 

 Смежные вопросы

  • Нет связанных вопросов^_^