【问题标题】:Dynamically loading external javascript resources in Splash HTTP rendering service在 Splash HTTP 渲染服务中动态加载外部 javascript 资源
【发布时间】:2016-12-06 16:59:50
【问题描述】:

我目前使用Splash HTTP API 作为无头浏览器来呈现请求。 我将端点 render.htmljs_source 一起使用,它允许在页面完成加载之后和页面呈现之前在页面上下文中评估自定义 Javascript 代码.

我需要对外部资源发出额外的请求,例如在页面加载后加载 jQuery

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = "https://code.jquery.com/jquery-1.5.1.min.js";
document.getElementsByTagName('head')[0].appendChild(script);

问题是这样做时,对象在页面上下文中不可用。该脚本似乎确实添加到最终呈现的 HTML 源的 HEAD 元素中:

<script type="text/javascript" src="https://code.jquery.com/jquery-1.5.1.min.js"></script>

我尝试使用下面描述的两种方法设置回调,以确保在访问 jQuery 的任何方法之前加载脚本。但是这两种情况下回调都调用失败。

script.onreadystatechange = callback;
script.onload = callback;

Chrome 的控制台中运行上述脚本可以满足我的要求,并立即使 jQuery 资源在页面上下文中可用。

【问题讨论】:

    标签: javascript jquery html scrapy-splash


    【解决方案1】:

    也许你可以让它与js_source一起工作,但作为一个功能js_source是非常有限的; /execute 端点和自定义 Lua 脚本更加通用,而且通常更易于使用:

    function main(splash)
        splash:autoload("https://code.jquery.com/jquery-1.5.1.min.js")
        assert(splash:go(splash.args.url))
        assert(splash:wait(1.0))
        splash:runjs(splash.args.js_source)
        return splash:html()
    end
    

    ^^ 此脚本模拟 render.html 端点,但预加载 jQuery;它支持 'url' 和 'js_source' 参数并将 'wait' 硬编码为 1.0。

    【讨论】:

    • 我目前正在从 Python 上下文发出 Splash 请求。我不会添加额外的依赖项,比如支持 Lua 脚本。在呈现页面之前注入将评估的javascript代码将是我正在寻找的。​​span>
    • 附加依赖是什么意思?您是否使用 Docker 安装 Splash?如果是这样,它已经支持 Lua 脚本 - 请参阅 /execute 端点的“lua_source”参数。您不需要在客户端上安装 Lua。
    • 我对附加依赖项的意思是,如果不是真的需要,我不想支持 Lua 脚本。 Lua 脚本以相同的方式评估 js,唯一的区别是资源是从外部下载的,这在我的情况下不起作用。在我当前的实现中,我需要在页面加载后从浏览器上下文发送一些额外的请求,以在页面上保存一些令牌。
    • 对不起,我不确定我是否关注。 “资源从外部下载”是什么意思?为什么不能使用在 Splash 端执行的 Lua 脚本从浏览器上下文发送这些额外的请求?
    【解决方案2】:

    据我所知,来自 /execute 端点的 autoload 命令通过 Python 中的 HTTP GET 异步下载资源,@987654321 @,然后以与 js_source 类似的方式随意评估 js。 https://github.com/scrapinghub/splash/blob/master/splash/browser_tab.py#L655

    因此,无法像您通常使用 HTML 脚本资源那样从浏览器上下文中添加/下载外部资源 :(

    【讨论】:

      【解决方案3】:

      我终于设法解决了这个问题,看起来 Splash 没有在更改时重新评估 DOM,对我有用的是对资源和评估响应:

      src = "https://code.jquery.com/jquery-1.5.1.min.js";
      
      var request = new XMLHttpRequest();
      request.open('GET', src, false);
      request.send(null);
      
      if (request.status === 200) {
          eval(request.responseText);
      };
      

      【讨论】:

        猜你喜欢
        • 2014-05-15
        • 2019-08-14
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多