2016-12-10 88 views
5

我想在python中使用Splash for Scrapy来抓取一些动态网站。但是,我发现Splash无法在某些情况下等待加载完整页面。解决这个问题的一种蛮力方法是增加一个大的wait时间(例如,在下面的片段中5秒)。但是,这是非常低效的,并且仍然无法加载某些数据(有时需要花费超过5秒的时间来加载内容)。通过这些请求是否存在某种等待元素条件?在python中执行SplashRequest时添加一个等待元素的元素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" 
    } 
} 

见脚本tutorialreference关于如何写飞溅Lua脚本的详细信息。

+1

要添加到解决方案中,我在运行上述脚本时遇到了“尝试索引nil值”的Lua错误。问题在于':exists()'不能在'splash:select('。my-element')''返回的'nil'值上运行,因为元素还没有被渲染。因此,简单地去掉':exists()'部分并检查循环,而不是使用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 
相关问题