Python中如何使用scrapy-splash读取iframe下的内容?
用 scrapy-splash 读取的源码, iframe 下的内容没有返回, scrapy-splash 有啥好的解决方法么?除了 selenium 和 phantomjs 。
Python中如何使用scrapy-splash读取iframe下的内容?
1 回复
用scrapy-splash抓取iframe内容,关键在于让Splash先执行页面JavaScript,等iframe加载完再提取数据。核心是scrapy_splash.SplashRequest配合正确的Lua脚本。
下面是个完整示例。假设我们要抓取一个包含iframe的页面,iframe的ID是myframe:
import scrapy
from scrapy_splash import SplashRequest
class IframeSpider(scrapy.Spider):
name = 'iframe_spider'
def start_requests(self):
# 目标URL
url = 'http://example.com/page-with-iframe'
# Lua脚本:等待iframe加载并返回其内容
lua_script = """
function main(splash)
splash:go(splash.args.url)
splash:wait(2) -- 等待页面初始加载
-- 等待特定iframe加载
splash:wait_for_resume([[
function main(splash)
local iframe = splash:select('iframe#myframe')
if iframe then
splash:set_viewport_full()
return iframe:info()
end
return nil
end
]])
-- 切换到iframe上下文
local iframe = splash:select('iframe#myframe')
if iframe then
splash:set_viewport_full()
local iframe_url = iframe.node.attributes.src
splash:go(iframe_url)
splash:wait(1)
end
return splash:html()
end
"""
yield SplashRequest(
url,
self.parse,
endpoint='execute',
args={
'lua_source': lua_script,
'timeout': 90
}
)
def parse(self, response):
# 现在response包含的是iframe内的HTML内容
# 可以像平常一样用XPath或CSS选择器提取数据
data = response.css('div.content::text').get()
yield {'data': data}
关键点:
- Lua脚本逻辑:先加载主页面,等待iframe出现,然后获取iframe的src地址,让Splash导航到那个地址。
- 上下文切换:
splash:go(iframe_url)让Splash进入iframe内部,后续操作都在iframe的DOM中进行。 - 等待机制:
splash:wait()和wait_for_resume确保动态内容加载完成。
如果iframe是跨域的,可能需要额外处理。有些网站用JavaScript动态生成iframe,这时得根据具体情况调整等待条件和选择器。
一句话建议: 让Splash执行JS加载iframe后再跳转进去抓取。

