使用PHP和cURL登录Pinterest不起作用

时间:2014-05-09 15:52:28

标签: php curl login pinterest

我一直试图让cURL在过去的17个小时内登录到pinterest.com,尝试了无数种不同的方式,只是使用了cURL,但它根本不起作用。

我当前的代码只进入页面,但数据没有发布,所以它不会登录只是带我到登录页面。

第一个代码是使用USERPWD,它是我登录页面的地方,但它没有登录。

error_reporting(E_ALL); 
ini_set("display_errors", 1); 

$url = "https://www.pinterest.com/login/";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // allow https verification if true
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // check common name and verify with host name
curl_setopt($ch, CURLOPT_SSLVERSION,3); // 
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "pin.pem"); // allow ssl cert direct comparison
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); // set new cookie session
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies.txt");
curl_setopt($ch, CURLOPT_USERPWD, "email:password");

curl_setopt($ch, CURLOPT_SSLVERSION,3);

// grab URL and pass it to the browser
curl_exec($ch);

// close cURL connection, save cookie file, free up system resources
curl_close($ch);

如果我将其从CURLOPT_USERPWD切换到

curl_setopt($ch, CURLOPT_POSTFIELDS, 'username_or_email=$email&password=$password');

它只显示一个空白页面。

pin.pem是X.509证书(PEM)文件。

任何指导这项工作的人都会非常感激。

修改

新代码但留下空白页面,我得到了一些数组的输出并显示:

Array ( [url] => https://www.pinterest.com/login/ [content_type] => [http_code] => 0 [header_size] => 0 [request_size] => 0 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.036169 [namelookup_time] => 3.3E-5 [connect_time] => 0.036186 [pretransfer_time] => 0 [size_upload] => 0 [size_download] => 0 [speed_download] => 0 [speed_upload] => 0 [download_content_length] => -1 [upload_content_length] => -1 [starttransfer_time] => 0 [redirect_time] => 0 [certinfo] => Array ( ) [redirect_url] => ) 

error_reporting(E_ALL); 
ini_set("display_errors", 1); 

$email = 'email';
$password = 'password';

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://www.pinterest.com/login/');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSLVERSION,3); // 
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . 'pin.pem');
curl_setopt($ch, CURLOPT_COOKIESESSION, TRUE); 
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'username_or_email=$email&password=$password');
curl_setopt($ch, CURLOPT_SSLVERSION,3);

curl_exec($ch);

$output=@curl_exec($ch);
$info = @curl_getinfo($ch);

echo $output;
print_r($info);

curl_close($ch);

2 个答案:

答案 0 :(得分:4)

Pinterest登录过程并不那么简单。他们使用CSRF令牌,您必须使用您的登录信息提取和发送,以及POST正文中的用户名和密码。

以下是Pinterest的实际登录请求,因此您需要使用cURL进行模拟。

POST /resource/UserSessionResource/create/ HTTP/1.1
Host: www.pinterest.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-CSRFToken: 2rjgN4Qv67pN4wX91kTr4eIkgF54CzJH
X-NEW-APP: 1
X-APP-VERSION: 737af79
X-Requested-With: XMLHttpRequest
Referer: https://www.pinterest.com/login/
Content-Length: 300
Cookie: csrftoken=2rjgN4Qv67pN4wX91kTr4eIkgF54CzJH; _pinterest_sess="aPgJnrIBzvSKLUY/4H5UocshliA47GkkGtHLQwo1H4IcQv58vrdazclonByOb4fWCzb3a3nycKjQzDc6SkCB9eBKoejaLiCjkKLk/QAFRn2x1pvHFlFM+1EoD01/yFxmeQKlvULYU9+qf4D6Mkj8A=="; _track_cm=1;
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

source_url=%2Flogin%2F&data=%7B%22options%22%3A%7B%22username_or_email%22%3A%22YOU%40YOUROMAIN.COM%22%2C%22password%22%3A%22YOURPASSWORD%22%7D%2C%22context%22%3A%7B%7D%7D&module_path=App()%3ELoginPage()%3ELogin()%3EButton(class_name%3Dprimary%2C+text%3DLog+In%2C+type%3Dsubmit%2C+size%3Dlarge)

请求中的source_url数据是POST正文(urlencoded)。请注意username_or_email是您的登录信息(我放YOU%40YOURDOMAIN.COM),password是密码。

您需要做的是向/login/发出GET请求,以便在cURL会话中建立会话和Cookie。然后使用相同的cURL句柄,您可以切换到POST请求,使用CURLOPT_POSTFIELDS行中的数据设置source_url......

您可能还需要设置标题X-CSRFTokenX-NEW-APPX-APP-VERSIONX-Requested-With以匹配上述内容(除非您需要弄清楚如何获得正确的CSRF令牌值。)

不幸的是我现在没时间做一个有效的例子,下一段可能有所帮助。您需要使用浏览器来帮助您调试一些HTTP请求,以找出您为获取请求获取所有相关数据而可能需要做的所有请求。

如果您查看this answer,它会显示使用PHP的curl登录,并通过示例链接到许多有用的其他相关答案。

编辑:

以下是使用PHP和cURL登录Pinterest的工作示例。

此代码是一个Pinterest PHP登录示例(从2014-05-11开始工作)。您可能会问自己,我可以用API完成我想要做的事情而不是可能破坏的这个hackish代码在任何时候???

正如您所看到的,我从头文件中解析出CSRF_Token,您可能也应该为APP-VERSION执行此操作,因为它几乎每天都可以更新。现在它的硬编码。

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

$username   = 'you@yoursite.com';  // your username
$password   = 'yourpassword';      // your password

// this is the http post data for logging in - username & password are substituted in later
$login_post     = array(
        'source_url' => '/login/',
        'data' => '{"options":{"username_or_email":"%s","password":"%s"},"context":{}}',
        'module_path' => 'App()>LoginPage()>Login()>Button(class_name=primary, text=Log In, type=submit, size=large',
);
$pinterest_url  = 'https://www.pinterest.com/';  // pinterest home url
$login_url      = $pinterest_url . 'login/';     // pinterest login page url
$login_post_url = $pinterest_url . 'resource/UserSessionResource/create/'; // pinterest login post url

// http headers to send with requests
$httpheaders    = array(
       'Connection: keep-alive',
       'Pragma: no-cache',
       'Cache-Control: no-cache',
       'Accept-Language: en-US,en;q=0.5',
);

// http headers to send when logging in
$login_header   = array(
        'X-NEW-APP: 1',
        'X-APP-VERSION: d2bb370',  // THIS WILL UPDATE FREQUENTLY, CHANGE IT!!!
        'X-Requested-With: XMLHttpRequest',
        'Accept: application/json, text/javascript, */*; q=0.01');

// ----------------------------------------------------------------------------
// request home page to establish cookies and a session, set curl options

$ch = curl_init($pinterest_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Iron/31.0.1700.0 Chrome/31.0.1700.0');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_STDERR, fopen('/tmp/debug.txt', 'w+'));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheaders);

$data = curl_exec($ch);

// ----------------------------------------------------------------------------

// parse the csrf token out of the cookies to set later when logging in
list($headers, $body) = explode("\r\n\r\n", $data, 2);

preg_match('/csrftoken=(.*?)[\b;\s]/i', $headers, $csrf_token);

// next request the login page
curl_setopt($ch, CURLOPT_URL, $login_url);
$data = curl_exec($ch);

// ----------------------------------------------------------------------------
// perform login post    

$login_header[] = 'X-CSRFToken: ' . $csrf_token[1];

$login_post['data'] = sprintf($login_post['data'], $username, $password);
$post               = http_build_query($login_post);

curl_setopt($ch, CURLOPT_URL, $login_post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($httpheaders, $login_header));
curl_setopt($ch, CURLOPT_REFERER, $login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);

$data = curl_exec($ch);

// check response and output status

if (curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
    echo "Error logging in.<br />";
    var_dump(curl_getinfo($ch));
} else {
    $response = json_decode($data, true);

    if ($response === null) {
        echo "Failed to decode JSON response.<br /><br />";
        var_dump($response);
    } else if ($response['resource_response']['error'] === null) {
        echo "Login successful, " . $response['resource_response']['data']['username'] . "<br /><br />";
        echo "You have {$response['resource_response']['data']['follower_count']} followers, are following {$response['resource_response']['data']['following_count']} users.  You have liked {$response['resource_response']['data']['like_count']} pins.";
    }
}

我的输出:

  

登录成功,drew010

     

您有0个粉丝,关注0个用户。你喜欢0针。

答案 1 :(得分:0)

仅供参考,Pinterest具有登录速率限制,因此请不要在每次请求前都运行此操作。

这是我的Pinterest登录/会话机制的Ruby实现。 每天运行一次以保存标题(包括csrftoken)。然后,使用保存的标头执行api(尚未)支持的请求(例如广告报告)。

class PinterestHeadersScheduler

  include Sidekiq::Worker
  sidekiq_options queue: :recurring, retry: 0

  HOMEPAGE    = 'https://ads.pinterest.com/'
  LOGIN_URL   = "#{HOMEPAGE}login/"
  SESSION_URL = "#{HOMEPAGE}resource/UserSessionResource/create/"

  LOGIN_DATA = {
      source_url: '/login/',
      data: { options: { username_or_email: ENV['PI_USERNAME'], password: ENV['PI_PASSWORD'] }, context: {} }.to_json
  }

  HEADERS = {
      'Accept':           'application/json,text/html,image/webp,image/apng,*/*;q=0.8',
      'Origin':           'https://ads.pinterest.com',
      'Referer':          'https://ads.pinterest.com/',
      'User-Agent':       'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
      'Connection':       'keep-alive',
      'Cache-Control':    'no-cache',
      'Accept-Charset':   'utf-8;ISO-8859-1q=0.7,*;q=0.7',
      'Accept-Encoding':  'gzip, deflate',
      'Accept-Language':  'en-US,en;q=0.8'
  }

  SESSION_HEADERS = HEADERS.merge({
      'Accept':           'application/json',
      'Content-Type':     'application/x-www-form-urlencoded; charset=UTF-8',
      'X-Requested-With': 'XMLHttpRequest'
  })

  def perform
    login   = HTTParty.get(LOGIN_URL, { headers: HEADERS })
    cjar    = login.get_fields('Set-Cookie').each_with_object(HTTParty::CookieHash.new) { |cookie, jar| jar.add_cookies(cookie) }
    headers = SESSION_HEADERS.merge({ 'Cookie': cjar.to_cookie_string, 'X-CSRFToken': cjar[:csrftoken] })

    res     = HTTParty.post(SESSION_URL, { headers: headers, body: LOGIN_DATA.to_param })
    session = JSON.parse(ActiveSupport::Gzip.decompress(res.body))
    raise "login error #{session['resource_response']['error']}" if session['resource_response']['error']

    cjar = res.headers.get_fields('Set-Cookie').each_with_object(HTTParty::CookieHash.new) { |cookie, jar| jar.add_cookies(cookie) }
    save_session_headers(HEADERS.merge({ 'Cookie' => cjar.to_cookie_string }))
  end

  def save_session_headers(headers)
    # replace this with your cache/db
    Utils::RedisUtil.set(:pinterest_session_headers, headers.to_json)
  end
end