ScrapyJS - 如何正确等待页面加载?
ScrapyJS - How to properly wait for page load?
我正在使用 ScrapyJS 和 Splash 来模拟表单提交按钮的点击
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
来获得结果。这可能并不总是有效(网络延迟),那么有更好的方法吗?
事实证明,唯一的方法是使用 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)
所以我还没有玩过这个(直到今天才 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/Splash 语法
有更好的方法来检查它,但是您仍然需要一个等待循环。这个想法是在页面更新时使用 splash:on_response(response)
作为回调。请注意,响应回调将被称为异步,因此主循环必须等待所有页面修改,这就是为什么我们有一个 'wait-for' 循环(例如由@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
我正在使用 ScrapyJS 和 Splash 来模拟表单提交按钮的点击
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
来获得结果。这可能并不总是有效(网络延迟),那么有更好的方法吗?
事实证明,唯一的方法是使用 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)
所以我还没有玩过这个(直到今天才 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/Splash 语法
有更好的方法来检查它,但是您仍然需要一个等待循环。这个想法是在页面更新时使用 splash:on_response(response)
作为回调。请注意,响应回调将被称为异步,因此主循环必须等待所有页面修改,这就是为什么我们有一个 'wait-for' 循环(例如由@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