使用CURL登录PHP不起作用
我想登录bukalapak.com网站,但我遇到了问题,在执行此php后,我得到了一个空白页面,下面是我的代码:使用CURL登录PHP不起作用,php,curl,Php,Curl,我想登录bukalapak.com网站,但我遇到了问题,在执行此php后,我得到了一个空白页面,下面是我的代码: var_dump(login_bukalapak()); function login_bukalapak(){ $data_login = array( 'user_session[username]' => 'myusername', 'user_session[password]' => 'mypassword' );
var_dump(login_bukalapak());
function login_bukalapak(){
$data_login = array(
'user_session[username]' => 'myusername',
'user_session[password]' => 'mypassword'
);
$url = "https://www.bukalapak.com/user_sessions";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$cookie = 'cookies.txt';
$timeout = 30;
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout );
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS,$data_login);
$result = curl_exec($ch);
/*$url = "https://www.bukalapak.com/products/new?from=dropdown";
curl_setopt ($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);*/
curl_close($ch);
return $result;
}
我搞不清楚我刚才有没有返回空白,如何正确回答才能使它运行良好并返回成功登录?
谢谢。你在这里做了很多错事 1:他们的登录系统对登录POST请求主体使用application/x-www-form-urlencoded编码,但您的代码尝试使用多部分/表单数据编码登录 2:他们的登录系统要求您在登录之前拥有一个预先存在的cookie会话,但是您的代码在发送登录请求之前没有获得cookie会话 3:他们使用CSRF令牌方案来保护他们的登录,您需要从页面获取CSRF令牌,并在发送登录请求之前将其添加到您的登录帖子字段中,称为
真实性\u令牌
(在他们的html中为
),您的代码在登录之前不会尝试获取和提取此令牌
4:您缺少一系列登录参数,即utf8
,user\u session[记住我]
,come
,按钮
,正如我前面所说,authenticity\u token
-可能不需要所有这些参数,或者可能需要所有参数,但至少需要其中一些参数(authenticity\u token
)100%肯定是必需的,只需将它们全部添加,除非您想浪费时间弄清楚哪些参数是必需的,哪些参数不是必需的,否则这可能不值得付出努力
5:您的代码缺少错误检查,如果设置设置有问题,curl_setopt返回bool(false);如果传输过程中出现问题,curl_exec返回bool(false)
考虑到这一点,下面是一个示例实现,我认为它可以使用真实的用户名/密码:
<?php
require_once ('hhb_.inc.php');
$hc = login_bukalapak ( "foo@bar.com", "password" );
var_dump ( $hc->exec ( 'https://www.bukalapak.com/' )->getStdOut () );
function login_bukalapak(string $username, string $password): \hhb_curl {
$hc = new hhb_curl ( '', true );
$html = $hc->exec ( 'https://www.bukalapak.com/' )->getStdOut ();
$domd = @DOMDocument::loadHTML ( $html );
$data_login = getDOMDocumentFormInputs ( $domd, true, false ) ['new_user_session'];
// var_dump ( $data_login ) & die ();
assert ( isset ( $data_login ['user_session[username]'], $data_login ['user_session[password]'] ), 'username/password field not found in login form!' );
$data_login ['user_session[username]'] = $username;
$data_login ['user_session[password]'] = $password;
$url = "https://www.bukalapak.com/user_sessions";
$html = $hc->setopt_array ( array (
CURLOPT_URL => 'https://www.bukalapak.com/user_sessions',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query ( $data_login )
) )->exec ()->getStdOut ();
//var_dump ( $html );
$domd = @DOMDocument::loadHTML ( $html );
$xp = new DOMXPath ( $domd );
$loginErrorEles = $xp->query ( '//*[contains(@class,"__error") and not(contains(@class,"hidden"))]' );
$loginErrors = '';
foreach ( $loginErrorEles as $loginError ) {
if (empty ( $loginError->textContent )) {
continue;
}
$loginErrors .= trim ( $loginError->textContent );
}
if (! empty ( $loginErrors )) {
throw new RuntimeException ( 'failed to log in: '.$loginErrors);
}
// assuming logged in successfully
// note that its highly unreliable, they sometimes say "wrong username/password", and someitmes not, seemingly randomly.
return $hc;
}
function getDOMDocumentFormInputs(\DOMDocument $domd, bool $getOnlyFirstMatches = false, bool $getElements = true): array {
// :DOMNodeList?
if (! $getOnlyFirstMatches && ! $getElements) {
throw new \InvalidArgumentException ( '!$getElements is currently only implemented for $getOnlyFirstMatches (cus im lazy and nobody has written the code yet)' );
}
$forms = $domd->getElementsByTagName ( 'form' );
$parsedForms = array ();
$isDescendantOf = function (\DOMNode $decendant, \DOMNode $ele): bool {
$parent = $decendant;
while ( NULL !== ($parent = $parent->parentNode) ) {
if ($parent === $ele) {
return true;
}
}
return false;
};
// i can't use array_merge on DOMNodeLists :(
$merged = function () use (&$domd): array {
$ret = array ();
foreach ( $domd->getElementsByTagName ( "input" ) as $input ) {
$ret [] = $input;
}
foreach ( $domd->getElementsByTagName ( "textarea" ) as $textarea ) {
$ret [] = $textarea;
}
foreach ( $domd->getElementsByTagName ( "button" ) as $button ) {
$ret [] = $button;
}
return $ret;
};
$merged = $merged ();
foreach ( $forms as $form ) {
$inputs = function () use (&$domd, &$form, &$isDescendantOf, &$merged): array {
$ret = array ();
foreach ( $merged as $input ) {
// hhb_var_dump ( $input->getAttribute ( "name" ), $input->getAttribute ( "id" ) );
if ($input->hasAttribute ( "disabled" )) {
// ignore disabled elements?
continue;
}
$name = $input->getAttribute ( "name" );
if ($name === '') {
// echo "inputs with no name are ignored when submitted by mainstream browsers (presumably because of specs)... follow suite?", PHP_EOL;
continue;
}
if (! $isDescendantOf ( $input, $form ) && $form->getAttribute ( "id" ) !== '' && $input->getAttribute ( "form" ) !== $form->getAttribute ( "id" )) {
// echo "this input does not belong to this form.", PHP_EOL;
continue;
}
if (! array_key_exists ( $name, $ret )) {
$ret [$name] = array (
$input
);
} else {
$ret [$name] [] = $input;
}
}
return $ret;
};
$inputs = $inputs (); // sorry about that, Eclipse gets unstable on IIFE syntax.
$hasName = true;
$name = $form->getAttribute ( "id" );
if ($name === '') {
$name = $form->getAttribute ( "name" );
if ($name === '') {
$hasName = false;
}
}
if (! $hasName) {
$parsedForms [] = array (
$inputs
);
} else {
if (! array_key_exists ( $name, $parsedForms )) {
$parsedForms [$name] = array (
$inputs
);
} else {
$parsedForms [$name] [] = $tmp;
}
}
}
unset ( $form, $tmp, $hasName, $name, $i, $input );
if ($getOnlyFirstMatches) {
foreach ( $parsedForms as $key => $val ) {
$parsedForms [$key] = $val [0];
}
unset ( $key, $val );
foreach ( $parsedForms as $key1 => $val1 ) {
foreach ( $val1 as $key2 => $val2 ) {
$parsedForms [$key1] [$key2] = $val2 [0];
}
}
}
if ($getElements) {
return $parsedForms;
}
$ret = array ();
foreach ( $parsedForms as $formName => $arr ) {
$ret [$formName] = array ();
foreach ( $arr as $ele ) {
$ret [$formName] [$ele->getAttribute ( "name" )] = $ele->getAttribute ( "value" );
}
}
return $ret;
}
他们允许自动登录吗?@rlfm是的,他们不支持他们的服务条款says@rtfm真的吗?我在他们的TOS中找不到任何相关的部分,我只找到了一个基本上说“TOS也适用于bupalak应用程序”的部分(可能是指一些智能手机应用程序),当你说他们不允许时,你指的是哪一部分?从阅读TOS中我可以看出,他们根本没有任何关于它的政策。嗨,谢谢你的回答,我在HP Parse error中遇到了错误:语法错误,意外的“:”,期待“{'in':\hhb_curl'在直线上5@CSMMedia这是因为您试图在php5.x中运行它-这段代码是为PHP7编写的-我如何仅为特定文件PHP运行PHP7?@CSMMedia google it-一种方法是为*.PHP文件和*.PHP7文件设置不同的fpm处理程序,并让php5.6-fpm和PHP7.0-fpm同时运行,grea工作对于我来说,在nginx+php fpm-.php文件中,t作为php5执行,.php7文件作为php7执行