PhantomJS - 等待方法不会执行函数。程序卡住了
PhantomJS - WaitFor Method will not execute function. Programm is stuck
我在 PhantomJS 中使用 waitFor-Method 时遇到了一些问题。
这就是我想要做的:
- 通过生成的 url 加载多个网页
- 使用 jQuery 从该页面解析一些 links
- 将每个解析的 link 存储在同一个数组中(在本例中,我将只记录它们)
我正在使用 waitFor() 方法,所以我可以等到页面被评估。据我了解,此方法将使程序无法继续,直到我作为参数传递的函数返回任何内容。
我的问题:
实际上程序在执行waitFor-Method 后不会继续运行。它只是卡住了。没有任何错误。我作为参数传递的函数不会被执行...至少控制台没有登录。
当我删除 waitFor-Methot 时,它会正确执行代码,但是我无法多次执行 handleSeriesPageListPage()-Method。我真的不太喜欢 js 和回调或异步方法处理。我想我犯了一些严重的错误,一些 javascript 专家将能够很快帮助我 :)。
"use strict";
var page = require('webpage').create();
page.onConsoleMessage = function (msg) {
console.log(msg);
};
var seriesPageBaseUrl = "https://www.example.com?pageid=";
var simpleBaseUrl = "https://www.example.com/";
var seriesPageIds = [0xx, 1xx];
var allSeriesUrls = [];
function handleSeriesPageListPage(url) {
console.log("Open url: " + url);
page.open(url, function (status) {
console.log("status: " + status);
if (status === "success") {
waitFor(
function () {
return page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {
console.log("Included JS");
return page.evaluate(function () {
console.log("evaluate result...");
$('.list_item').each(function () {
var seriesLink = jQuery(this).find("a").first().attr("href");
var seriesUrl = simpleBaseUrl + seriesLink;
console.log(seriesUrl);
return true;
});
});
});
}
);
} else {
phantom.exit(1);
}
});
}
function nextSeriesListPage() {
var seriesPageId = seriesPageIds.shift();
if (typeof seriesPageId === "undefined") {
console.log(allSeriesUrls);
phantom.exit(0);
}
var targetURL = seriesPageBaseUrl + seriesPageId;
handleSeriesPageListPage(targetURL);
}
nextSeriesListPage();
您使用的 waitFor()
函数不是处理异步任务的合适方法,您实际上误解了它的作用:
waitFor(testFx, onReady, timeOutMillis)
接受三个参数(第三个是可选的)。第一个参数是测试函数。它重复执行,但每次都是同步执行,直到它的 return 值为 true
。然后,执行作为第二个参数给出的函数。如果在第三个参数给定的时间段内(或默认为 3 秒)没有 true
值被 returned,该函数将退出并显示一条日志消息 'waitFor()' timeout
.
您只提供了一个参数;一个没有 return 值(基本上是 page.includeJs()
)的函数。因此,waitFor()
应该在 3 秒后退出并显示 timeout
消息。
您真正想要实现的是
- 等待页面加载
- 然后注入jQuery脚本,等待,
- 然后重新评估,等待,
- 然后提取信息
这是四个异步任务。 PhantomJS 规定的基本方法是在上一个回调函数中进行相应的下一步,从而产生四个嵌套回调。
由于这不是一个很好的模式(通常称为 回调地狱),Promise 模式已作为 Javascript 功能(或包含在几个库中)。
要了解如何将回调 API 重新表述为 Promises,请查看
How do I convert an existing callback API to promises?
我在 PhantomJS 中使用 waitFor-Method 时遇到了一些问题。
这就是我想要做的:
- 通过生成的 url 加载多个网页
- 使用 jQuery 从该页面解析一些 links
- 将每个解析的 link 存储在同一个数组中(在本例中,我将只记录它们)
我正在使用 waitFor() 方法,所以我可以等到页面被评估。据我了解,此方法将使程序无法继续,直到我作为参数传递的函数返回任何内容。
我的问题: 实际上程序在执行waitFor-Method 后不会继续运行。它只是卡住了。没有任何错误。我作为参数传递的函数不会被执行...至少控制台没有登录。
当我删除 waitFor-Methot 时,它会正确执行代码,但是我无法多次执行 handleSeriesPageListPage()-Method。我真的不太喜欢 js 和回调或异步方法处理。我想我犯了一些严重的错误,一些 javascript 专家将能够很快帮助我 :)。
"use strict";
var page = require('webpage').create();
page.onConsoleMessage = function (msg) {
console.log(msg);
};
var seriesPageBaseUrl = "https://www.example.com?pageid=";
var simpleBaseUrl = "https://www.example.com/";
var seriesPageIds = [0xx, 1xx];
var allSeriesUrls = [];
function handleSeriesPageListPage(url) {
console.log("Open url: " + url);
page.open(url, function (status) {
console.log("status: " + status);
if (status === "success") {
waitFor(
function () {
return page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {
console.log("Included JS");
return page.evaluate(function () {
console.log("evaluate result...");
$('.list_item').each(function () {
var seriesLink = jQuery(this).find("a").first().attr("href");
var seriesUrl = simpleBaseUrl + seriesLink;
console.log(seriesUrl);
return true;
});
});
});
}
);
} else {
phantom.exit(1);
}
});
}
function nextSeriesListPage() {
var seriesPageId = seriesPageIds.shift();
if (typeof seriesPageId === "undefined") {
console.log(allSeriesUrls);
phantom.exit(0);
}
var targetURL = seriesPageBaseUrl + seriesPageId;
handleSeriesPageListPage(targetURL);
}
nextSeriesListPage();
您使用的 waitFor()
函数不是处理异步任务的合适方法,您实际上误解了它的作用:
waitFor(testFx, onReady, timeOutMillis)
接受三个参数(第三个是可选的)。第一个参数是测试函数。它重复执行,但每次都是同步执行,直到它的 return 值为 true
。然后,执行作为第二个参数给出的函数。如果在第三个参数给定的时间段内(或默认为 3 秒)没有 true
值被 returned,该函数将退出并显示一条日志消息 'waitFor()' timeout
.
您只提供了一个参数;一个没有 return 值(基本上是 page.includeJs()
)的函数。因此,waitFor()
应该在 3 秒后退出并显示 timeout
消息。
您真正想要实现的是
- 等待页面加载
- 然后注入jQuery脚本,等待,
- 然后重新评估,等待,
- 然后提取信息
这是四个异步任务。 PhantomJS 规定的基本方法是在上一个回调函数中进行相应的下一步,从而产生四个嵌套回调。
由于这不是一个很好的模式(通常称为 回调地狱),Promise 模式已作为 Javascript 功能(或包含在几个库中)。
要了解如何将回调 API 重新表述为 Promises,请查看 How do I convert an existing callback API to promises?