简体   繁体   English

使用cURL和PHP的Facebook登录

[英]Facebook Login using cURL and PHP

I am trying to reach facebook login page using curl. 我正在尝试使用curl访问Facebook登录页面。 My intention is to login to facebook, then do some scaping. 我的意图是登录到Facebook,然后执行一些操作。 I am not using the facebook API because of the latest restrictions... I need to scrape comments on posts and this is impossible by only using the API. 由于最新的限制,我没有使用facebook API。我需要在帖子上留言,而仅使用API​​是不可能的。

Here is some of my code: 这是我的一些代码:

curl_setopt($ch, CURLOPT_URL,"https://web.facebook.com");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

I would want this to redirect to the login page, then when the user fills in login form I would take the credentials and use them to redirect to the homepage and start scraping. 我希望它重定向到登录页面,然后在用户填写登录表单时,我将获取凭据并将其用于重定向到首页并开始抓取。

Anyway, this is what I am getting: 无论如何,这就是我得到的:

我实际上是在chrome上运行的...

(ps, i am the author of the program) this program logs into facebook to send messages. (PS,我是程序的作者), 该程序登录到Facebook以发送消息。 the login code can be found here , the login procedure is done in the constructor function, 登录代码可在此处找到,登录过程在构造函数中完成,

but the gist of it is that you need to do a GET request first to get a cookie and a csrf token and some stuff, parse that out of the lgoin form, then post that back in a application/x-www-form-urlencoded POST request together with the username and password to a login url specific to your cookie session, the url of which you must also parse out of the html received in the first GET request. 但要点是,您需要先执行GET请求以获取cookie和csrf令牌以及其他内容,然后从lgoin形式中解析出该内容,然后将其发布回application/x-www-form-urlencoded POST请求以及用户名和密码,以特定于您的cookie会话的登录URL,您还必须从第一个GET请求中收到的html中解析出该URL。

it'd also be in your best interest to use a user-agent implying that you have shitty javascript support (because in reality, with PHP, you have none.), an example, as used by that code, is 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.570 Mobile Safari/534.8+' (aka, an old blackberry phone) 使用用户代理暗示您拥有糟糕的javascript支持(因为实际上,对于PHP,您根本没有),这也是您的最大利益。该代码使用的示例是'Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.570 Mobile Safari/534.8+' (又名旧黑莓手机)

  • now, if you use a smartphone user-agent, it may sometimes ask you to install an smartphone app, and if you get that question, it will not let you finish logging in until you answer either yes or no, so you need to add code to detect that question, and answer it if present, you can detect that question with the XPath "//a[contains(@href,'/login/save-device/cancel/')]" and protip, a nice way to confirm that you managed to log in, is to look for the logout button, which in XPath looks like //a[contains(@href,"/logout.php")] 现在,如果您使用智能手机用户代理,它有时可能要求您安装智能手机应用程序,如果您遇到此问题,则在回答“是”或“否”之前,它不会让您完成登录,因此您需要添加代码以检测该问题并回答(如果存在),您可以使用XPath "//a[contains(@href,'/login/save-device/cancel/')]"和protip来检测该问题确认您已成功登录,是要查找注销按钮,该按钮在XPath中看起来像//a[contains(@href,"/logout.php")]

the most relevant part of the code is: 该代码最相关的部分是:

function __construct() {
    $this->recipientID = \MsgMe\getUserOption ( 'Facebook', 'recipientID', NULL );
    if (NULL === $this->recipientID) {
        throw new \Exception ( 'Error: cannot find [Facebook] recipientID option!' );
    }
    $this->email = \MsgMe\getUserOption ( 'Facebook', 'email', NULL );
    if (NULL === $this->email) {
        throw new \Exception ( 'Error: cannot find [Facebook] email option!' );
    }
    $this->password = \MsgMe\getUserOption ( 'Facebook', 'password', NULL );
    if (NULL === $this->password) {
        throw new \Exception ( 'Error: cannot find [Facebook] password option!' );
    }
    $this->hc = new \hhb_curl ();
    $hc = &$this->hc;
    $hc->_setComfortableOptions ();
    $hc->setopt_array ( array (
            CURLOPT_USERAGENT => 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.570 Mobile Safari/534.8+',
            CURLOPT_HTTPHEADER => array (
                    'accept-language:en-US,en;q=0.8' 
            ) 
    ) );
    $hc->exec ( 'https://m.facebook.com/' );
    // \hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () ) & die ();
    $domd = @\DOMDocument::loadHTML ( $hc->getResponseBody () );    
    $form = (\MsgMe\tools\getDOMDocumentFormInputs ( $domd, true )) ['login_form'];
    $url = $domd->getElementsByTagName ( "form" )->item ( 0 )->getAttribute ( "action" );
    $postfields = (function () use (&$form): array {
        $ret = array ();
        foreach ( $form as $input ) {
            $ret [$input->getAttribute ( "name" )] = $input->getAttribute ( "value" );
        }
        return $ret;
    });
    $postfields = $postfields (); // sorry about that, eclipse can't handle IIFE syntax.
    assert ( array_key_exists ( 'email', $postfields ) );
    assert ( array_key_exists ( 'pass', $postfields ) );
    $postfields ['email'] = $this->email;
    $postfields ['pass'] = $this->password;
    $hc->setopt_array ( array (
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query ( $postfields ),
            CURLOPT_HTTPHEADER => array (
                    'accept-language:en-US,en;q=0.8' 
            ) 
    ) );
    // \hhb_var_dump ($postfields ) & die ();
    $hc->exec ( $url );
    // \hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () ) & die ();

    $domd = @\DOMDocument::loadHTML ( $hc->getResponseBody () );
    $xp = new \DOMXPath ( $domd );
    $InstallFacebookAppRequest = $xp->query ( "//a[contains(@href,'/login/save-device/cancel/')]" );
    if ($InstallFacebookAppRequest->length > 0) {
        // not all accounts get this, but some do, not sure why, anyway, if this exist, fb is asking "ey wanna install the fb app instead of using the website?"
        // and won't let you proceed further until you say yes or no. so we say no.
        $url = 'https://m.facebook.com' . $InstallFacebookAppRequest->item ( 0 )->getAttribute ( "href" );
        $hc->exec ( $url );
        $domd = @\DOMDocument::loadHTML ( $hc->getResponseBody () );
        $xp = new \DOMXPath ( $domd );
    }
    unset ( $InstallFacebookAppRequest, $url );
    $urlinfo = parse_url ( $hc->getinfo ( CURLINFO_EFFECTIVE_URL ) );
    $a = $xp->query ( '//a[contains(@href,"/logout.php")]' );
    if ($a->length < 1) {
        $debuginfo = $hc->getStdErr () . $hc->getStdOut ();
        $tmp = tmpfile ();
        fwrite ( $tmp, $debuginfo );
        $debuginfourl = shell_exec ( "cat " . escapeshellarg ( stream_get_meta_data ( $tmp ) ['uri'] ) . " | pastebinit" );
        fclose ( $tmp );
        throw new \RuntimeException ( 'failed to login to facebook! apparently... cannot find the logout url!  debuginfo url: ' . $debuginfourl );
    }
    $a = $a->item ( 0 );
    $url = $urlinfo ['scheme'] . '://' . $urlinfo ['host'] . $a->getAttribute ( "href" );
    $this->logoutUrl = $url;
    // all initialized, ready to sendMessage();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM