我想要解决的问题如下:
我需要通过PHP管理外部网页,例如,登录,然后在我自己的网站上发送ajax请求后更改外部网站上的配置文件信息。
为此,我从PHP调用PhantomJS来完成这些任务,但在登录到外部web之前,我需要填写验证码输入。因此,我想将验证码图像发回我的网站,编写正确的代码,然后将其发送回PhantomJS的WebPage模块,以便使用该代码登录。
换句话说,我需要一个像这样的“同步”程序:
1) PHP ->发起登录请求,获取验证码图片。
2) PhantomJS ->打开WebPage实例,将验证码渲染成图片。
3) PHP ->获取验证码图片,展示给用户,并向PhantomJS发送文本输入。
4) PhantomJS ->从PHP获取文本代码,使用'page.evaluate‘填充验证码输入,然后登录。向PHP发送一些数据(“登录成功”、“登录失败”等)
5) PHP ->获取回调并发送另一个任务或数据。
callback = 'Login successfull' --> Change profile picture or update user info.
callback = 'Login failed' --> Try to login again (like point 1)等等。
有很多事情我不知道该怎么处理。例如:
1)如何保持WebPage模块打开并等待验证码的文本代码?如果我关闭它,下一次会出现一个新的验证码,我需要一种等待代码并获得它的方法。我需要为此启动一个服务器吗?
2)从PHP获取验证码图像不是问题(因为有'page.render'),但我如何将文本发送回PhantomJS的WebPage实例?我认为在两个系统之间双向发送数据更好。再问一次,我需要服务器吗?
我想在PhantomJS中我需要一个套接字服务器(怎么做?)。这个服务器应该有我需要保持打开的WebPage实例,但是我不能完全确定这一点。
谢谢。
发布于 2016-06-12 01:25:57
我最近发布了一个项目,允许PHP访问浏览器。在这里获得它:https://github.com/merlinthemagic/MTS,在引擎盖下是PhantomJS的一个实例。
主要问题是在初始执行后保持资源存活。这是我建议你怎么做的。
下载并设置后,您只需使用以下代码:
开始“设置”会话:
if (isset($_POST['sessionUID']) === false) {
//set the execution timeout long enough to cover the entire process (setup and working time), it dictates when phantomJS shuts down automatically.
ini_set('max_execution_time', 300);
//open the login page:
$myUrl = "http://www.example.com";
$browserObj = \MTS\Factories::getDevices()->getLocalHost()->getBrowser('phantomjs');
//allow the page to live after php shuts down.
$browserObj->setKeepalive(true);
$windowObj = $browserObj->getNewWindow($myUrl);
//find the username input box, here it has id=username
$windowObj->mouseEventOnElement("[id=username]", 'leftclick');
//type your username
$windowObj->sendKeyPresses("yourUsername");
//find the password input box, here it has id=passwd
$windowObj->mouseEventOnElement("[id=passwd]", 'leftclick');
//type your password
$windowObj->sendKeyPresses("yourPassword");
//click on the login button, here it has id=login
$windowObj->mouseEventOnElement("[id=login]", 'leftclick');
//i assume this is when you encounter the CAPTCHA image
//find the CAPTCHA image element, here it has id=captchaImage
$element = $windowObj->getElement("[id=captchaImage]");
$loc = $element['location'];
//tell the screenshot to only get the CAPTCHA image
$windowObj->setRasterSize($loc['top'], $loc['left'], ($loc['right'] - $loc['left']), ($loc['bottom'] - $loc['top']));
$imageData = $windowObj->screenshot("png");
$sessionUID = uniqid();
$saveWindowObj = serialize($windowObj);
//save the window object so we can pick it up again
file_put_contents("/tmp/" . $sessionUID, $saveWindowObj);
}
//now render the CAPTCHA image to the user as part of a form they can resubmit and make sure to keep the $sessionUId as a hidden variable in the form on the page"Setup“会话结束后,php将在此处关闭。
开始“工作”会话:我们假设用户提交了表单,它是一个包含验证码的$sessionUID和文本字符串的帖子。
if (isset($_POST['sessionUID']) === true && isset($_POST['captchaTxt']) === true) {
$savedWindow = file_get_contents("/tmp/" . $sessionUID);
//delete the saved object
unlink("/tmp/" . $sessionUID);
//bring back the object to life
$windowObj = unserialize($savedWindow);
//make sure the browser is now shutdown on exit
$windowObj->getBrowser()->setKeepalive(false);
//find the CAPTCHA input box, here it has id=captchaInput
$windowObj->mouseEventOnElement("[id=captchaInput]", 'leftclick');
//type the CAPTCHA string
$windowObj->sendKeyPresses($_POST['captchaTxt']);
//click on the button to accept CAPTCHA, here it has id=captchaOK
$windowObj->mouseEventOnElement("[id=captchaOK]", 'leftclick');
//now use the clickElement() etc functions on $windowObj to do what you need to do.
}“工作”会话结束后,php将在此处关闭。
https://stackoverflow.com/questions/32362373
复制相似问题