7

我一直在尝试使用 curl 登录 barnesandnoble.com 移动网站,但到目前为止还没有运气。我返回没有错误的页面,它再次将我的电子邮件默认到登录页面的电子邮件输入表单框中(以 print $result 返回的表单)。

通过将 LOGINURL 更改为指向 ebay 的登录名,相同的代码实际上可以让我正确进入 ebay

唯一的区别是 barnesandnobles 是 https:// 而 ebay 登录是 http://

另外,我相信 barnes 网站是 asp/aspx,所以我不知道如何以不同方式处理 cookie 和 _state

任何帮助将不胜感激,因为我在过去 16 小时内一直在尝试调试它

另外,我的 cookie.txt 是可写的并且可以工作

<?php
    $cookie_file_path = "C:/test/cookie.txt";
    $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
    $agent = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";

    $ch = curl_init(); 

    $headers[] = "Accept: */*";
    $headers[] = "Connection: Keep-Alive";
    $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";

    curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
    curl_setopt($ch, CURLOPT_HEADER,  0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_URL, $LOGINURL);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);

    $content = curl_exec($ch); 

    curl_close($ch); 

    unset($ch); 

    // NAME="path_state" value="6657403">

    if(stristr($content,"path_state")){
        $array1 = explode('path_state" value="',$content);
        $content1 = $array1[1];
        $array2 = explode('">',$content1);
        $content2 = $array2[0];
    }

    $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
    $POSTFIELDS = "d_hidPageStamp=V_3_17&hidViewMode=opSignIn&stage=signIn&previousStage=mainStage&path_state=" .  $content2 . "&emailAddress=YOUREMAILHERE@gmail.com&acctPassword=YOURPASSWORD";
    $reffer = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 

    $ch = curl_init(); 

    $headers[] = "Accept: */*";
    $headers[] = "Connection: Keep-Alive";
    $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";

    curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
    curl_setopt($ch, CURLOPT_HEADER,  0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);   
    curl_setopt($ch, CURLOPT_URL, $LOGINURL); 
    curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_REFERER, $reffer); 
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 

    $result = curl_exec($ch);  

    print $result; 
?>
4

1 回答 1

20

这是我根据您的代码创建的一个工作示例。这使用了getFormFields我为登录 Android 市场的类似问题(本文底部的第一个参考)编写的函数。

我认为您的脚本中可能有几件事阻止了登录工作。首先,您应该对帖子字符串中的 URL 参数(例如电子邮件和密码)进行urlencode(cURL 不会为您执行此操作)。其次,我认为x可能需要用作登录 URL 一部分的值。

这是一个成功登录的解决方案。注意,我重新使用了原来的 cURL 句柄。这不是必需的,但如果您指定 keep-alive,它实际上会重用相同的连接,并且它还使您不必一遍又一遍地指定相同的选项。

获得 cookie 后,您可以创建一个新的 cURL 对象并指定 COOKIEFILE 和 COOKIEJAR,您将无需执行第一步即可登录。

<?php

// options
$EMAIL            = 'you@yoursite.com';
$PASSWORD         = 'yourpassword';
$cookie_file_path = "/tmp/cookies.txt";
$LOGINURL         = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
$agent            = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";


// begin script
$ch = curl_init(); 

// extra headers
$headers[] = "Accept: */*";
$headers[] = "Connection: Keep-Alive";

// basic curl options for all requests
curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
curl_setopt($ch, CURLOPT_HEADER,  0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         
curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 

// set first URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);

// execute session to get cookies and required form inputs
$content = curl_exec($ch); 

// grab the hidden inputs from the form required to login
$fields = getFormFields($content);
$fields['emailAddress'] = $EMAIL;
$fields['acctPassword'] = $PASSWORD;

// get x value that is used in the login url
$x = '';
if (preg_match('/op\.asp\?x=(\d+)/i', $content, $match)) {
    $x = $match[1];
}

//$LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
  $LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?x=$x";

// set postfields using what we extracted from the form
$POSTFIELDS = http_build_query($fields); 

// change URL to login URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL); 

// set post options
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 

// perform login
$result = curl_exec($ch);  

print $result; 


function getFormFields($data)
{
    if (preg_match('/(<form action="op.*?<\/form>)/is', $data, $matches)) {
        $inputs = getInputs($matches[1]);

        return $inputs;
    } else {
        die('didnt find login form');
    }
}

function getInputs($form)
{
    $inputs = array();

    $elements = preg_match_all('/(<input[^>]+>)/is', $form, $matches);

    if ($elements > 0) {
        for($i = 0; $i < $elements; $i++) {
            $el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);

            if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name)) {
                $name  = $name[1];
                $value = '';

                if (preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
                    $value = $value[1];
                }

                $inputs[$name] = $value;
            }
        }
    }

    return $inputs;
}

这对我有用,希望对你有所帮助。

以下是我的其他一些 cURL 答案,可能有助于学习:

于 2012-04-25T00:46:17.713 回答