我尝试使用PhantomJS从广告服务器运行一些JavaScript并解析响应对象,以获取有关所投放广告的信息。这可以从Firefox / Chrome Dev Tools中获得,但我需要从服务器访问相同的信息。我可以让Phantom运行,但是一旦我尝试包含外部JS page.includeJs("http://www.someadserver.com/config.js?nwid=1909"
并访问通过外部JS someadserver.setup({ domain: 'http://www.someadserver.com'});
设置的变量,它就会失败。任何帮助将不胜感激。
"use strict";
var page = require('webpage').create();
page.content = `
<html>
<head>
<script>
someadserver.setup({ domain: 'http://www.someadserver.com'});
</script>
<title>The title of the web page.</title>
</head>
<body>
<div class="ads_leaderboard">
<!-- position: leaderboard -->
<script>
someadserver.call( "std" , {
siteId: 100806,
pageId: 656377,
target: ""
});
</script>
</div>
<div id="foo">this is foo</div>
</body>
</html>`;
var title = page.evaluate(function (s) {
page.includeJs(
"http://www.someadserver.com/config.js?nwid=1909",
function() {
return document.querySelector(s).innerText;
}, 'title');
});
console.log(title);
phantom.exit(1);
编辑1:
我简化了我的剧本(下方),我明显遗漏了一些东西。当我使用bin/phantomjs /srv/phantom_test.js
运行下面的脚本时,我得到的唯一输出是end page
。为什么还没有执行console.log语句的其余部分?
"use strict";
var page = require('webpage').create();
page.content = "<html>" +
"<head>" +
" <title>The title of the web page.</title>" +
"</head>" +
"<body>" +
"<div id=\"foo\">this is foo</div>" +
"</body>" +
"</html>";
page.includeJs("http://www.someadserver.com/config.js?nwid=1909", function() {
console.log('start function');
var title = page.evaluate(function(s){
return document.querySelector(s).innerText;
}, 'title');
console.log(title);
console.log('end function');
});
console.log('end page');
phantom.exit();
答案 0 :(得分:0)
page.evaluate
内的内容在目标网页的上下文中执行,就好像该代码>> 一样。
page.includeJS(...)
不会是someadserver.com
上的有效代码。
正确的方法反之亦然:
page.includeJs("http://www.someadserver.com/config.js?nwid=1909", function() {
var title = page.evaluate(function(s){
return document.querySelector(s).innerText;
}, 'title');
});
答案 1 :(得分:0)
您的第一个代码段不起作用,因为为page.content
分配值会立即执行它。因此,someadserver.setup(...)
会立即执行,就好像页面实际已加载一样,但此时page.includeJs(...)
来电尚未发生。
您应该能够实际包含要在页面源中运行的脚本:
var content = `
<html>
<head>
<script src="http://www.someadserver.com/config.js?nwid=1909"></script>
<script>
someadserver.setup({ domain: 'http://www.someadserver.com'});
</script>
<title>The title of the web page.</title>
</head>
<body>
<div class="ads_leaderboard">
<!-- position: leaderboard -->
<script>
someadserver.call( "std" , {
siteId: 100806,
pageId: 656377,
target: ""
});
</script>
</div>
<div id="foo">this is foo</div>
</body>
</html>`;
page.setContent(content, "http://www.someadserver.com/");
var title = page.evaluate(function (s) {
return document.querySelector(s).innerText;
}, 'title');
console.log(title);
phantom.exit();
我还使用page.setContent
来设置域名,以便不会破坏进一步的脚本加载。将网页来源分配到page.content
时,默认网址实际上是:空白,您不需要。
第一个代码段的其他问题:
page.evaluate
和page.includeJs
的开头和结尾不匹配!page
内没有page.evaluate
,因为页面上下文是沙箱化的!您的第二个代码段不起作用,因为page.includeJs(...)
是一个异步函数(它有一个回调!),所以您过早退出脚本。