【问题标题】:How to resend a request on resource timeout in PhantomJS?如何在 PhantomJS 中重新发送资源超时请求?
【发布时间】:2015-01-17 10:59:28
【问题描述】:

我有一个 PHP 脚本,它可以抓取网页并使用 PhantomJS 将抓取的数据插入到数据库中。
目前,在 PhantomJS 中的资源超时时,我取消了页面的整个请求并通过 PHP 再次请求整个页面。
这是我的代码:

page.settings.resourceTimeout = 5000; // 5 seconds
page.onResourceTimeout = function(e) {
  console.log(e.errorCode);   // it'll probably be 408 
  console.log(e.errorString); // it'll probably be 'Network timeout on resource'
  console.log(e.url);         // the url whose request timed out
  phantom.exit(1);
};

我只想向超时的资源重新发送请求,而不是重新请求整个页面。 这可能吗?

【问题讨论】:

  • 我最近一直在使用Spiderling 从 PHP 驱动 PhantomJS。我想知道它是否有一些东西可以确定依赖资源是否成功加载,以及它们没有在哪里重新加载它们(我相信有一个 JS 加载器)。然而,正如 Artjom 所说,由于后续脚本可能会因初始失败而失败,因此您可能必须在失败之后(包括)重新加载所有脚本。

标签: php timeout web-scraping phantomjs


【解决方案1】:

您可以重新发送(GET)请求,但这对您没有多大帮助,因为请求的原因不同。

资源请求会在 <script> 标记中引用 JavaScript 文件时自动发生。您可以通过 XHR 使用 PhantomJS 下载它,但很可能其他依赖它的脚本已经尝试运行但失败了。您将不得不再次重新运行所有这些。这真的很乏味。
CSS 文件或图像等其他资源对时间不敏感,可以重新下载。但是当你这样做时,你必须将它们插入到正确的位置。我们以一个 CSS 文件为例。

  1. 您可以从请求标头或 url 中检测到它是 CSS 资源,
  2. 检查资源实际引用的 DOM,
  3. 将 DOM 节点及其所有属性(和 innerHTML)复制到新的 DOM 节点,
  4. 移除旧的并插入新的。什么都没有改变,但它应该提示浏览器再次下载资源。所有这些都必须在 page.evaluate 回调的页面上下文中完成。

XHR 请求 是通过页面显式发送的。所以每个请求都有一个完成/错误回调。您无法从外部访问这些回调,因此重新运行这些请求将不起作用,因为不会调用这些请求之后发生的操作。

您可能希望使用 --disk-cache=true 选项运行 PhantomJS,以便再次运行页面请求所需的时间更少。

【讨论】:

  • 我明白了。那么每次遇到依赖资源时我应该只请求整个页面吗?
  • 是的。似乎没有办法解决。
  • 我为第一部分添加了说明。
  • 感谢您的澄清。
猜你喜欢
  • 2013-12-07
  • 1970-01-01
  • 2020-07-27
  • 2020-12-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
相关资源
最近更新 更多