PhantomJS无法打开HTTPS网站。

105
我正在使用基于loadspeed.js示例的以下代码来打开需要HTTP服务器身份验证的https://站点。
var page = require('webpage').create(), system = require('system'), t, address;

page.settings.userName = 'myusername';
page.settings.password = 'mypassword';

if (system.args.length === 1) {
    console.log('Usage: scrape.js <some URL>');
    phantom.exit();
} else {
    t = Date.now();
    address = system.args[1];
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('FAIL to load the address');
        } else {
            t = Date.now() - t;
            console.log('Page title is ' + page.evaluate(function () {
                return document.title;
            }));
            console.log('Loading time ' + t + ' msec');
        }
        phantom.exit();
    });
}  

页面一直无法加载。可能出了什么问题?安全网站需要特别处理吗?但是可以通过浏览器成功访问该网站。

我现在刚开始使用Phantom,发现它太好玩了,即使遇到这个问题也不想停下来。

13个回答

154

我尝试了 Fred 和 Cameron Tinker 的答案,但只有 --ssl-protocol=any 选项似乎对我有帮助:

我尝试了Fred和Cameron Tinker的答案,但只有--ssl-protocol=any选项似乎对我有帮助:

phantomjs --ssl-protocol=any test.js

我认为使用--ssl-protocol=any会更加安全,因为你仍然在使用加密,但--ignore-ssl-errors=true会忽略(显然)所有的SSL错误,包括恶意的。


1
我必须使用这三个参数,才能解决问题: "--web-security=false","--ssl-protocol=any","--ignore-ssl-errors=true"。webdriver.PhantomJS(service_args=['--ignore-ssl-errors=true', "--web-security=false", "--ssl-protocol=any"])。 - Abdul Khalid

123

该问题很可能是由于SSL证书错误引起的。如果您使用--ignore-ssl-errors=yes选项启动phantomjs,则应该可以加载页面,就像没有SSL错误一样:

phantomjs --ignore-ssl-errors=yes [phantomOptions] script.js [scriptOptions]

我看到一些网站在实现SSL证书时出现问题,或者它们已经过期等。PhantomJS的完整命令行选项列表在这里可用:http://phantomjs.org/api/command-line.html


2
谢谢,这也解决了我的问题。我的情况是,在浏览器上没有收到证书错误,所以非常令人困惑,但我使用curl verbose并注意到一个不起作用的是使用通配符证书(即:CN=*.example.com)。如果phantomjs能够返回详细的失败原因,那就太好了。 - naoko
7
天哪,我希望SSL错误能够得到解释,只有堆栈溢出和粉色独角兽帮助我找到了根本原因。谢谢大家。 - SimplGy
我知道我来晚了,但是我发现在脚本名称之后添加选项并不起作用 - 你需要按顺序调用它:phantomjs --ignore-ssl-errors=yes script.js - simonlchilds
是的,--ignore-ssl-errors=yes选项应该在脚本名称之前。感谢您指出这一点。 - Cameron Tinker
它是否给出任何错误消息?我尚未在phantomjs 1.9.7上尝试过这种方法,但应该可以工作,因为--ignore-ssl-errors=yes选项仍然可用。您还可以根据下面Fred的答案建议更改SSL协议。 - Cameron Tinker
显示剩余4条评论

71
请注意,从2014年10月16日开始,PhantomJS默认使用SSLv3打开HTTPS连接。最近POODLE漏洞被公布,许多服务器正在禁用SSLv3支持。
为了解决这个问题,您应该能够通过以下方式运行PhantomJS:
phantomjs --ssl-protocol=tlsv1

希望PhantomJS能够尽快更新,将TLSv1作为默认选项而不是SSLv3。


4
1.9.8版本将默认协议切换为TLSv1:https://github.com/ariya/phantomjs/issues/12670 - Andy Triggs
为我修好了,服务器上禁用了SSLv3。 - Chris Herring
2
请注意,更新到 PhantomJS 1.9.8 会导致一个新的错误(bug)(https://github.com/ariya/phantomjs/issues/12697)。 - Artjom B.
这应该是被接受的答案。在我看来,禁用SSL或允许任何协议都不是好的解决方案。感谢分享。 - Dominic P
3
如何在 SSL 握手问题上获得更详细的调试信息? - wrschneider
显示剩余3条评论

24

我遇到了同样的问题...
--ignore-ssl-errors=yes 对我来说不足以解决它, 我还需要做两件事:
1)更改用户代理
2)尝试所有的ssl协议,唯一有效的是页面所需的tlsv1
希望这可以帮助...


2
将ssl-协议更改为tlsv1对我也起作用了,谢谢! - Dave Stibrany
1
解决了我的问题,幸好你不在我身边,不然我现在会亲吻你,哈哈,干杯。 - Martin
这正是我所需要的。非常感谢!我使用了“any”而不是tlsv1,这也可以正常工作。(如果我访问其他SSL网站,这似乎更安全一些。) - user1841243
1
将用户代理更改为什么? - Lucas Steffen

17

我遇到了同样的问题(casperjs 1.1.0-beta3/phantomjs 1.9.7)。使用--ignore-ssl-errors=yes和--ssl-protocol=tlsv1解决了这个问题。只使用其中一种选项对我来说并没有解决这个问题。


这个技巧解决了我的问题,我在codeship CI上运行phantomjs + behat套件时使用(经过约10小时的调试和尝试)。 - ZeNC
是啊,经过一些愚蠢的小时之后,你的评论让我的一天变得美好了! - Yarimadam
解决了我的问题!!! - wizpig64

0

我收到了来自在CentOS 6.6上运行的phantomJS的"创建SSL上下文错误"。

从源代码构建已经解决了这个问题。不要忘记使用你构建的phantomjs。(而不是 /usr/local/bin/phantomjs,如果你安装了它)

注意保留html标签。

sudo yum -y install gcc gcc-c++ make flex bison gperf ruby openssl-devel freetype-devel fontconfig-devel libicu-devel sqlite-devel libpng-devel libjpeg-devel
git clone git://github.com/ariya/phantomjs.git
cd phantomjs
git checkout 2.0
./build.sh
cd bin/
./phantomjs <your JS file>

1
我不知道为什么人们会对您的回答评价负面。在尝试了上面提到的所有解决方案并经过数天的苦战后,这是唯一对我有效的解决方案。由于qt,编译phantomJS相当麻烦,但它是值得的。 - FlorianB

0

关于shebang怎么样?

如果您正在使用 shebang 执行 phantomjs 脚本,请使用以下 shebang 行:

#!/usr/bin/phantomjs --ignore-ssl-errors=yes
    
var system = require('system');
var webpage = require('webpage');

// ... rest of your script

使用以上任何答案都可以。我个人喜欢--ignore-ssl-errors=yes,因为它与验证我的环回Web服务器的自签名证书无关。


0

这里其他的答案都没有帮到我;可能是因为我正在处理的特定网站对它们的HTTP头太挑剔了。这是有效的方法:

var page = webpage.create();
page.customHeaders = {
    "Connection": "keep-alive"
};

我发现 PhantomJS 正在使用 "Keep-Alive"(大写),但连接并没有被保持。 :)

0
如果有人正在使用Phantomjs和Sahi,--ignore-ssl-errors选项需要放在您的browser_types.xml文件中。对我有效。
<browserType>
    <name>phantomjs</name>
    <displayName>PhantomJS</displayName>
    <icon>safari.png</icon>
    <path>/usr/local/Cellar/phantomjs/1.9.2/bin/phantomjs</path>
    <options>--ignore-ssl-errors=yes --debug=yes --proxy=localhost:9999 /usr/local/Cellar/phantomjs/phantom-sahi.js</options>
    <processName>"PhantomJS"</processName>
    <capacity>100</capacity>
    <force>true</force>
</browserType>

0
在你尝试运行phantomjs连接到远程服务器的机器上,运行"openssl ciphers"命令。将列出的密码复制并粘贴到--ssl-ciphers=""命令行选项中。这会告诉连接的Web服务器可以使用哪些密码与您的客户端进行通信。如果不设置自己机器上可用的密码,它可能会使用任何你的机器不理解的默认现代浏览器所用的密码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接