php使用curl抓取qq空间的访客信息示例


Posted in PHP onFebruary 28, 2014

config.php

<?php
define('APP_DIR', dirname(__FILE__));
define('COOKIE_FILE', APP_DIR . '/app.cookie.txt'); //会话记录文件
define('VISITOR_CAPTURE_INTERVAL', 3); //QQ采集间隔
define('VISITOR_DATA_UPLOAD_INTERVAL', '');
define('THIS_TIME', time());
define('REQUEST_TIMEOUT', 20); //请求超时20秒
define('END_LINE', "\n");
define('DEBUG', true); //开启调试
$login_users = array(
    array('user' => '2064556526', 'password' => '909124951'),
    array('user' => '483258700', 'password' => '909124951'),
    array('user' => '1990270522', 'password' => '909124951'),
    array('user' => '2718711637', 'password' => '909124951'),
    array('user' => '2841076562', 'password' => '909124951'),
);

qy.visitor.php

<?php
include('./config.php');
include(APP_DIR . '/qy.visitor.php');
$sessions = array();
$user = $login_users[array_rand($login_users)];
$visitor_capture = new QQVisitorCapture($user['user'], $user['password'], COOKIE_FILE, REQUEST_TIMEOUT, DEBUG, END_LINE);
$visitors = $visitor_capture->getVisitorInfo();
if (empty($visitors)) {
    $this->clearCookies(true);
} else {
    $cckf_service = new CCKFService(SECURITY_KEY,SERVICE_ID,SERVICE_ADDRESS,'', REQUEST_TIMEOUT, DEBUG, END_LINE);
}

qy.class.php

<?php

class Trace
{
    public static function nl($num = 1)
    {
        $str = '';
        for ($i = 0; $i < $num; $i++) {
            $str .= "\n";
        }
        return $str;
    }
    public static function br($num = 1)
    {
        $str = '';
        for ($i = 0; $i < $num; $i++) {
            $str .= "<br/>";
        }
        return $str;
    }
    public static function write($content, $end_line, $title = null)
    {
        $close = '^^^^^^^^^^^^^^^^^';
        if ($title) {
            $start = '--------' . $title . '---------';
        } else {
            $start = '-----------------';
        }
        echo $start . $end_line;
        if (is_array($content)) {
            print_r($content);
            echo $end_line;
        } else {
            echo $content;
            echo $end_line;
        }
        if (empty($content)) {
            echo $end_line;
        } else {
            echo $close . $end_line;
        }
    }
}

class Utils
{
    public static function getMicroTime()
    {
        list($mic, $time) = explode(" ", microtime());
        return intval($time) + floatval(sprintf('%.3f', $mic));
    }
    public static function getUTCMilliseconds()
    {
        return round(rand(1, 9) / 10 * 2147483647) * round(1, 999) % 10000000000;
    }
    public static function decodeURIComponent($content)
    {
        return urldecode(preg_replace("/\\\\x([0-9a-z]{2,3})/i", "%$1", $content));
    }
    public static function  jsRandom()
    {
        list($mic, $time) = explode(" ", microtime());
        return $mic;
    }
    function loginJsTime()
    {
        list($mic, $time) = explode(" ", microtime());
        return $time . sprintf('%3d', $mic * 1000);
    }
    protected static function utf8_unicode($c)
    {
        switch (strlen($c)) {
            case 1:
                return ord($c);
            case 2:
                $n = (ord($c[0]) & 0x3f) << 6;
                $n += ord($c[1]) & 0x3f;
                return $n;
            case 3:
                $n = (ord($c[0]) & 0x1f) << 12;
                $n += (ord($c[1]) & 0x3f) << 6;
                $n += ord($c[2]) & 0x3f;
                return $n;
            case 4:
                $n = (ord($c[0]) & 0x0f) << 18;
                $n += (ord($c[1]) & 0x3f) << 12;
                $n += (ord($c[2]) & 0x3f) << 6;
                $n += ord($c[3]) & 0x3f;
                return $n;
        }
    }
    public static function  getGTK($str)
    {
        $hash = 5381;
        for ($i = 0, $len = strlen($str); $i < $len; ++$i) {
            $hash += ($hash << 5) + self::utf8_unicode($str[$i]);
        }
        return $hash & 2147483647;
    }
    protected static function hexchar2bin($str)
    {
        $arr = '';
        $temp = null;
        for ($i = 0; $i < strlen($str); $i = $i + 2) {
            $arr .= "\\x" . substr($str, $i, 2);
        }
        eval('$temp="' . $arr . '";');
        return $temp;
    }
    protected static function getUid($uid)
    {
        $temp = null;
        eval('$temp="' . $uid . '";');
        return $temp;
    }
    public static function getEncryption($password, $uin, $vcode)
    {
        $uin = self::getUid($uin);
        $str1 = self::hexchar2bin(strtoupper(md5($password)));
        $str2 = strtoupper(md5($str1 . $uin));
        return strtoupper(md5($str2 . strtoupper($vcode)));
    }
}
class CookieFileExtract
{
    protected $cookie_file;
    protected $cookie_list;
    protected function  __construct($cookie_file)
    {
        $this->cookie_file = $cookie_file;
        $this->cookie_list = $this->extractFile();
    }
    protected function isValidateCookieFile()
    {
        if ($this->cookie_file && file_exists($this->cookie_file)) {
            return true;
        } else {
            return false;
        }
    }
    protected function extractFile()
    {
        $cookie_list = array();
        if ($this->isValidateCookieFile($this->cookie_file)) {
            $content = file($this->cookie_file);
            if (is_array($content)) {
                foreach ($content as $line) {
                    $line = trim($line);
                    if (strlen($line) > 0 && $line[0] != '#') {
                        $cookie = (preg_split("/\s+/", $line));
                        if (count($cookie) == 7) {
                            $cookie_list[$cookie[5]] = $cookie[6];
                        } else {
                            $cookie_list[$cookie[5]] = '';
                        }
                    }
                }
            }
        }
        return $cookie_list;
    }
    protected function buildCookieStr($cookies)
    {
        $arr = array();
        if (is_array($cookies)) {
            foreach ($cookies as $k => $cookie) {
                $line = $cookie['domain'] . "\t" . "TRUE" . "\t" . $cookie['path'] . "\t" . "FALSE" . "\t" . $cookie['expires'] . "\t" . $k . "\t" . $cookie['value'];
                $arr[] = $line;
            }
        }
        return $arr;
    }
    protected function __setCookies($cookies)
    {
        $new_line = array();
        if (is_array($cookies)) {
            if ($this->isValidateCookieFile($this->cookie_file)) {
                $content = file($this->cookie_file);
                if (is_array($content)) {
                    foreach ($content as $line) {
                        $line = trim($line);
                        if (strlen($line) > 0 && $line[0] != '#') {
                            $cookie = (preg_split("/\s+/", $line));
                            if (!in_array($cookie[5], $cookies)) {
                                $new_line[] = $line;
                            }
                        } else {
                            $new_line[] = $line;
                        }
                    }
                }
            }
            file_put_contents($this->cookie_file, implode("\n", array_merge($new_line, $this->buildCookieStr($cookies))));
        }
    }
    protected function __getAllCookies($refresh = false)
    {
        if ($refresh) {
            $this->cookie_list = $this->extractFile();
        }
        return $this->cookie_list;
    }
    protected function __getCookie($cookie_name, $refresh = false)
    {
        $cookie_list = $this->__getAllCookies($refresh);
        if (is_array($cookie_list) && array_key_exists($cookie_name, $cookie_list)) {
            return $cookie_list[$cookie_name];
        } else {
            return null;
        }
    }
    protected function __clearAllCookies()
    {
        $this->cookie_list = null;
        @unlink($this->cookie_file);
    }
}
class BaseRequest extends CookieFileExtract
{
    protected $curl_instance;
    protected $request_timeout;
    protected $debug;
    protected $end_line;
    protected $user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0';
    protected function __construct($cookie_file, $request_timeout, $debug, $end_line)
    {
        parent::__construct($cookie_file);
        $this->request_timeout = $request_timeout;
        $this->debug = $debug;
        $this->end_line = $end_line;
        $this->initInstance();
    }
    protected function initInstance()
    {
        $this->curl_instance = curl_init();
        if ($this->isValidateCookieFile()) {
            curl_setopt($this->curl_instance, CURLOPT_COOKIEJAR, $this->cookie_file);
            curl_setopt($this->curl_instance, CURLOPT_COOKIEFILE, $this->cookie_file);
        }
        curl_setopt($this->curl_instance, CURLOPT_TIMEOUT, $this->request_timeout);
        curl_setopt($this->curl_instance, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl_instance, CURLOPT_HEADER, 1);
        curl_setopt($this->curl_instance, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($this->curl_instance, CURLOPT_SSL_VERIFYHOST, 0);
        curl_exec($this->curl_instance);
    }
    function setCookies($cookies)
    {
        $this->closeInstance();
        $this->__setCookies($cookies);
        $this->initInstance();
    }
    protected function getAllCookies($refresh = false)
    {
        $this->closeInstance();
        $cookies = $this->__getAllCookies($refresh);
        $this->initInstance();
        return $cookies;
    }

    protected function clearAllCookies($refresh = false)
    {
        $this->closeInstance();
        $this->__clearAllCookies();
        if ($refresh) {
            $this->initInstance();
        }
    }
    protected function getCookie($name, $refresh = false)
    {
        $this->closeInstance();
        $cookie = $this->__getCookie($name, $refresh);
        $this->initInstance();
        return $cookie;
    }
    protected function getRequestInstance()
    {
        return $this->curl_instance;
    }
    protected function closeInstance()
    {
        if (is_resource($this->curl_instance)) {
            curl_close($this->curl_instance);
        }
    }
    protected function resetInstance()
    {
        $this->closeInstance();
        @unlink($this->cookie_file);
        $this->initInstance();
    }
    protected function requestExec($option)
    {
        curl_setopt_array($this->getRequestInstance(), $option);
        //if ($this->debug) {
        //    $result = curl_exec($this->getRequestInstance());
        //    Trace::write($result, $this->end_line, 'request output');
        //} else {
        return curl_exec($this->getRequestInstance());
        //}
    }
}
class QQVisitorRequest extends BaseRequest
{
    protected $user;
    protected $password;
    protected function __construct($user, $password, $cookie_file, $request_timeout, $debug, $end_line)
    {
        parent::__construct(dirname($cookie_file) . '/' . $user . '.' . basename($cookie_file), $request_timeout, $debug, $end_line);
        $this->user = $user;
        $this->password = $password;
    }
}

class ResultExtract
{
    public static function  getCoreJsInfo($content, $user)
    {
        $arr = array();
        preg_match('/cfg\s*=\s*\{(.*?)\s*\}\s*,\s*URL_PARAM_HASH/s', $content, $m);
        if (count($m) > 0) {
            $f = preg_replace('/\s*/', '', $m[1]);
            $f = preg_replace('/"\+g\_iLoginUin\+"/', $user, $f);
            $f = preg_replace('/\$j\.cookie.get\("hotfeeds_closed"\)==1\?""\:/', '', $f);
            $f = explode(",", $f);
            if (count($f) > 0) {
                foreach ($f as $t) {
                    $t = trim($t);
                    $p = strpos($t, ':');
                    $key = trim(substr($t, 0, $p), '"');
                    $value = trim(substr($t, $p + 1), '"');
                    if ($key) {
                        $arr[$key] = $value;
                    }
                }
                if (count($arr) > 0) {
                    $arr['visitor'] = $arr;
                }
            }
        }
        return $arr;
    }
    public static function  enterQzoneSuccess($content)
    {
        $arr = array();
        $arr2 = array();
        preg_match('/g_Data\s*=\s*{\s*feedsPart1\s*:\s*(.*?)\s*,\s*feedsPart2/s', $content, $m);
        if (count($m) > 0) {
            $f = preg_replace('/\s*/', '', $m[1]);
            $f = preg_replace('/([\{,])([^,]*?)(\:)/', '$1"$2"$3', $f);
            $f = preg_replace('/:\'(.*?)\'([,\}])/', ':"$1"$2', $f);
            $arr = json_decode($f, true);
            $arr = $arr['main'];
        }
        preg_match('/g_type.*?g_IZone_Flag/s', $content, $m);
        if (count($m) > 0) {
            $f = preg_replace('/\s*/', '', $m[0]);
            $f = explode(",", $f);
            foreach ($f as $t) {
                $t = trim($t);
                $p = strpos($t, '=');
                $key = trim(substr($t, 0, $p));
                $value = trim(substr($t, $p + 1), '"');
                if ($key) {
                    $arr2[$key] = $value;
                }
            }
        }
        return array_merge($arr, $arr2);
    }
    public static function getLoginJsInfo($content)
    {
        $s = preg_replace('/.*?pt\.plogin\s*=\s*\{(.*?)aqScanLink.*/s', '$1', $content);
        preg_match('/.*js_type\s*:\s*(\d+)\s*,.*/', $s, $m);
        if (count($m) > 1) {
            return array('js_type' => $m[1]);
        }
        return array();
    }
    public static function getLoginAddress($content)
    {
        preg_match('/.*?<\s*iframe\s*id\s*=\s*"login_frame"\s*name\s*=\s*"login_frame".*?src\s*=\s*"(.*?xui\.ptlogin2\.qq\.com.*?)".*?>\s*<\/iframe>.*?/', $content, $m);
        if (count($m) > 1) {
            return html_entity_decode($m[1]);
        }
        return null;
    }
    public static function checkLoginSuccess($content)
    {
        preg_match_all('/.*?\((.*)\).*?/', $content, $match);
        if ($match[1][0]) {
            $g = explode(',', $match[1][0]);
            if (count($g) > 1) {
                if (($g[count($g) - 2]) == "'登录成功!'") {
                    $url_parts = parse_url($g[2]);
                    parse_str($url_parts['query'], $arr);
                    if (array_key_exists('ptsig', $arr)) {
                        $ptsig = $arr['ptsig'];
                    } else {
                        $ptsig = null;
                    }
                    return array('status' => true, 'value' => array('url' => $g[2], 'ptsig' => $ptsig));
                }
            }
        }
        return array('status' => false);
    }

    public static function rightFrameVisitors($content)
    {
        $visitor_list = array();
        $f = preg_replace('/\s*/', '', $content);
        $f = preg_replace('/.*?_Callback\((\{.*?\})\).*?/', '$1', $f);
        $f = json_decode($f, true);
        if (is_array($f) && count($f) > 0 && array_key_exists('data', $f)
            && array_key_exists('module_3', $f['data'])
            && array_key_exists('data', $f['data']['module_3'])
            && array_key_exists('items', $f['data']['module_3']['data'])
        ) {
            $visitors = $f['data']['module_3']['data']['items'];
            foreach ($visitors as $visitor) {
                if (!array_key_exists('loc', $visitor)) {
                    $visitor_list [] = array(
                        'uin' => $visitor['uin'], 'name' => $visitor['name'], 'online' => $visitor['online'], 'time' => $visitor['time'],
                        'img' => $visitor['img'], 'yellow' => $visitor['yellow'], 'supervip' => $visitor['supervip'],
                    );
                }
            }
        }
        return $visitor_list;
    }
    public static function getVisitors($content)
    {
        $f = preg_replace('/\s*/', '', $content);
        preg_match('/^.*?(\{.*?\})\);\s*$/', $f, $m);
        $visitor_list = array();
        if (is_array($m) && count($m) > 1 && strlen($m[1]) > 0) {
            $visitors = json_decode(trim($m[1]), true);
            if (array_key_exists('data', $visitors) && array_key_exists('items', $visitors['data'])) {
                foreach ($visitors['data']['items'] as $visitor) {
                    if ($visitor['name']) {
                        $_ = array(
                            'uin' => $visitor['uin'], 'name' => $visitor['name'], 'time' => $visitor['time'],
                            'yellow' => $visitor['yellow'], 'supervip' => $visitor['supervip'],
                        );
                        if (array_key_exists('portraitlabel', $visitor)) {
                            $_['portraitlabel'] = $visitor['portraitlabel'];
                        }
                        $visitor_list[] = $_;
                        if (array_key_exists('uins', $visitor)) {
                            foreach ($visitor['uins'] as $uins) {
                                $_ = array(
                                    'uin' => $uins['uin'], 'name' => $uins['name'], 'time' => $uins['time'],
                                    'yellow' => $uins['yellow'], 'supervip' => $uins['supervip'],
                                );
                                if (array_key_exists('portraitlabel', $uins)) {
                                    $_['portraitlabel'] = $uins['portraitlabel'];
                                }
                                $visitor_list[] = $_;
                            }
                        }
                    }
                }
            }
        }
        return $visitor_list;
    }
    public static function  checkVC($content)
    {
        preg_match_all('/.*?\((.*)\).*?/', $content, $match);
        if (strlen($match[1][0]) > 1) {
            $m = str_replace("'", '', $match[1][0]);
            $g = explode(',', $m);
            if (count($g) == 3) {
                return array('saltUin' => $g[2], 'verifycode' => $g[1], 'RSAKey' => $g[2] ? false : true);
            }
        }
        return array();
    }
    public static function getLoginInfo($content)
    {
        $s = preg_replace('/.*?pt\.ptui\s*=\s*\{(.*?)\}\s*;.*/s', '$1', $content);
        $e = preg_split('/,\s*/', trim($s));
        $info = array();
        foreach ($e as $t) {
            $t = trim($t);
            $p = strpos($t, ':');
            $key = trim(substr($t, 0, $p));
            $value = trim(substr($t, $p + 1));
            if (preg_match('/encodeURIComponent/', $value)) {
                $value = preg_replace('/^encodeURIComponent\s*\(\s*"(.*)?"\s*\)\s*,?$/', '$1', $value);
            } else {
                $value = trim($value, '",');
            }
            if ($key) {
                $info[$key] = urldecode($value);
            }
        }
        return $info;
    }
}

class QQVisitorCapture extends QQVisitorRequest
{
    public function __construct($user, $password, $cookie_file, $request_timeout, $debug, $end_line)
    {
        parent:: __construct($user, $password, $cookie_file, $request_timeout, $debug, $end_line);
    }
    public function trace($content, $title)
    {
        if ($this->debug = true) {
            Trace:: write($content, $this->end_line, $title);
        }
    }
    public function error($message)
    {
        $this->trace($message, 'login error ');
        return false;
    }
    public function success()
    {
        return true;
    }
    public function getGTKEncryption()
    {
        return Utils ::getGTK($this->getCookie('skey', true));
    }
    public function getCookies($refresh = false)
    {
        return $this->getAllCookies($refresh);
    }
    public function clearCookies($refresh = false)
    {
        return $this->clearAllCookies($refresh);
    }
    public function login()
    {
        $login_submit_info_url = null;
        $login_submit_info_url = $this->visitQzone();
        $this->setCookies(array(
            'pgv_pvid' => array(
                'value' => Utils::getUTCMilliseconds(), 'path' => '/', 'domain' => '.qq.com', 'expires' => '0'
            ),
            'pgv_info' => array(
                'value' => 'ssid=s' . Utils::getUTCMilliseconds(), 'path' => '/', 'domain' => '.qq.com', 'expires' => '0'
            ),
            '_qz_referrer' => array(
                'value' => 'qzone.qq.com', 'path' => '/', 'domain' => '.qq.com', 'expires' => '0'
            ),
        ));
        //log
        $this->trace('', 'login begin');
        //log
        $this->trace($login_submit_info_url, '$login_submit_info_url===');
        $login_submit_info = $this->getLoginSubmitInfo($login_submit_info_url);
        //log
        $this->trace($login_submit_info, '$login_submit_info===');
        if (empty($login_submit_info)) {
            $this->error('err-001');
        }
        $this->report();
        //log
        $this->trace('', 'getLoginJs');
        $js_arr = $this->getLoginJs();
        //log
        $this->trace($js_arr, '$getLoginJs===');
        if (empty($js_arr)) {
            $this->error('err-002');
        }
        $u = $uin = $this->user;
        $r = Utils::jsRandom();
        $verifycode = null;
        $pt_rsa = null;
        $ptredirect = $login_submit_info['target'];
        $h = $t = $g = $from_ui = 1;
        $p = null;
        $regmaster = $login_submit_info['regmaster'];
        $u1 = Utils::decodeURIComponent($login_submit_info['s_url']);
        $ptlang = $login_submit_info['lang'];
        $action = strval(rand(5, 9)) . '-' . strval(strlen($this->user) + strlen($this->password) + rand(1, 5)) . '-' . Utils::loginJsTime();
        $js_ver = $login_submit_info['ptui_version'];
        $js_type = $js_arr['js_type'];
        $login_sig = $login_submit_info['login_sig'];
        $appid = $aid = $login_submit_info['appid'];
        $pt_qzone_sig = $login_submit_info['pt_qzone_sig'];
        $daid = $login_submit_info['daid'];
        //log
        $this->trace('', 'checkVC');
        $check_data = $this->checkVC($regmaster, $appid, $js_ver, $js_type, $login_sig, $u1, $r);
        if (count($check_data) !== 3) {
            $this->error('err-003');
        }
        //log
        $this->trace($check_data, '$check_data===');
        //log
        $this->trace(json_encode($check_data), '$check_data===');
        $verifycode = $check_data['verifycode'];
        if ($check_data['RSAKey']) {
            $this->error('err-004');
        } else {
            $p = Utils::getEncryption($this->password, $check_data['saltUin'], $verifycode);
            $pt_rsa = 0;
        }
        //log
        $this->trace('', 'submitLogin');
        $this->setCookies(array(
            'ptui_loginuin' => array(
                'value' => $this->user, 'path' => '/', 'domain' => '.qq.com', 'expires' => '0'
            ),
        ));
        $login_result = $this->submitLogin($verifycode, $p,
            $pt_rsa, $ptredirect, $u1,
            $h, $t, $g, $from_ui,
            $ptlang, $action, $js_ver, $js_type,
            $login_sig, $aid, $daid, $pt_qzone_sig);
        if ($login_result['status']) {
            $this->trace('登录成功', 'submitLogin');
            $this->trace($login_result, '$login_result====');
            $this->loginSuccessRedirect($login_result['value']['url']);
            $this->setCookies(array(
                'fnc' => array(
                    'value' => 1, 'path' => '/', 'domain' => '.qzone.qq.com', 'expires' => '0'
                ),
            ));
            $enterQzoneInfo = $this->enterQzone($login_result['value']['url'], $login_result['value']['ptsig']);
            //log
            $this->trace($enterQzoneInfo, '$enterQzoneInfo===');
            if ($enterQzoneInfo) {
                $this->trace('进入空间', 'enterQzone');
                //$referer = $login_result['value']['url'];
                //$scope = 0;
                //log
                $this->trace('', 'getCoreJs');
                $coreJsInfo = $this->getCoreJs();
                $this->trace($coreJsInfo, 'getCoreJs===');
                $this->setCookies(array(
                    'qzone_referer' => array(
                        'value' => $login_result['value']['url'], 'path' => '/', 'domain' => '.local.cckf123456789.com', 'expires' => '0'
                    ),
                    'qzone_visitor_param' => array(
                        'value' => implode('|', array_values($coreJsInfo['visitor'])), 'path' => '/', 'domain' => '.local.cckf123456789.com', 'expires' => '0'
                    ),
                ));
                //log
                //$this->trace('', 'rightFrameVisitor');
                //print_r($this->rightFrameVisitor($referer, implode('|', array_values($coreJsInfo['visitor']))));
                return $this->success();
            } else {
                $this->error('err-006');
            }
        } else {
            $this->error('err-005');
        }
    }
    protected function visitQzone()
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://qzone.qq.com',
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:qzone.qq.com',
                'Accept-Language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
                'Connection:keep-alive',)
        );
        return ResultExtract::getLoginAddress($this->requestExec($options));
    }
    protected function getLoginJs()
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://imgcache.qq.com/ptlogin/ver/10067/js/c_login_old.js',
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:imgcache.qq.com',
                'Connection:keep-alive',)
        );
        return ResultExtract::getLoginJsInfo($this->requestExec($options));
    }
    public function checkVC($regmaster, $appid, $js_ver, $js_type, $login_sig, $u1, $r)
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://check.ptlogin2.qq.com/check?' . http_build_query(array(
                'regmaster' => $regmaster,
                'uin' => $this->user,
                'appid' => $appid,
                'js_ver' => $js_ver,
                'js_type' => $js_type,
                'login_sig' => $login_sig,
                'u1' => $u1,
                'r' => $r,
            )),
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:check.ptlogin2.qq.com',
                'Accept-Language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::checkVC($this->requestExec($options));
    }
    protected function report()
    {
        $url = 'http://ui.ptlogin2.qq.com/cgi-bin/report?id=358342&t=' . Utils::jsRandom();
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $url,
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:ui.ptlogin2.qq.com',
                'Connection:keep-alive',)
        );
        $this->requestExec($options);
    }
    protected function getLoginSubmitInfo($url)
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $url,
            CURLOPT_HTTPHEADER => array(
                'Referer:http://qzone.qq.com/',
                'User-Agent:' . $this->user_agent,
                'Host:xui.ptlogin2.qq.com',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::getLoginInfo($this->requestExec($options));
    }
    protected function submitLogin($verifycode, $p,
                                   $pt_rsa, $ptredirect, $u1,
                                   $h, $t, $g, $from_ui,
                                   $ptlang, $action, $js_ver, $js_type,
                                   $login_sig, $aid, $daid, $pt_qzone_sig)
    {
        $url = 'http://ptlogin2.qq.com/login';
        $url .= '?' . http_build_query(array(
                'u' => $this->user,
                'verifycode' => $verifycode));
        $url .= '&p=' . $p; ###
        $url .= '&' . http_build_query(array(
                'pt_rsa' => $pt_rsa,
                'ptredirect' => $ptredirect,
                'u1' => $u1,
                'h' => $h,
                't' => $t,
                'g' => $g,
                'from_ui' => $from_ui,
                'ptlang' => $ptlang,
                'action' => $action,
                'js_ver' => $js_ver,
                'js_type' => $js_type,
            ));
        $url .= '&login_sig=' . $login_sig; ###
        $url .= '&' . http_build_query(array(
                'aid' => $aid,
                'daid' => $daid,
                'pt_qzone_sig' => $pt_qzone_sig));
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $url,
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:ptlogin2.qq.com',
                'Accept-Language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::checkLoginSuccess($this->requestExec($options));
    }
    public function loginSuccessRedirect($url)
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $url,
            CURLOPT_HTTPHEADER => array(
                'Referer:http://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=http%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&pt_qzone_sig=1&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=http%3A//qzs.qq.com/qzone/v5/loginsucc.html?para=izone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=http%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html',
                'User-Agent:' . $this->user_agent,
                'Host:qzs.qq.com',
                'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Connection:keep-alive',
                'DNT:1',
            )
        );
        $this->requestExec($options);
    }
    public function  enterQzone($referer, $ptsig)
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://user.qzone.qq.com/' . $this->user . '?ptsig=' . $ptsig,
            CURLOPT_HTTPHEADER => array(
                'Referer:' . $referer,
                'Host:user.qzone.qq.com',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::enterQzoneSuccess($this->requestExec($options));
    }
    public function getCoreJs()
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => "http://ctc.qzonestyle.gtimg.cn/c/=/qzone/v8/engine/cpu.js,/qzone/v8/ic/qm.js,/qzone/v8/ic/tab_menu.js,/qzone/v8/ic/feeds.js,/qzone/v8/ic/tab_friend_feed.js,/qzone/v8/toolbar/core.js",
        );
        return ResultExtract::getCoreJsInfo($this->requestExec($options), $this->user);
    }

    public function getVisitorInfo($mask = 7, $page = 1, $fupdate = 1, $clear = 1)
    {
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more?' . http_build_query(array(
                'uin' => $this->user,
                'mask' => $mask,
                'g_tk' => $this->getGTKEncryption(),
                'page' => $page,
                'fupdate' => $fupdate,
                'clear' => $clear,
                'sd' => Utils::jsRandom(),
            )),
            CURLOPT_HTTPHEADER => array(
                'Referer:http://ctc.qzs.qq.com/qzone/v6/friend_manage/visitors.html',
                'User-Agent:' . $this->user_agent,
                'Host:g.qzone.qq.com',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::getVisitors($this->requestExec($options));
    }
    public function  rightFrameVisitor()
    {
        $param = Utils ::getGTK($this->getCookie('qzone_visitor_param', true));
        $referver = Utils ::getGTK($this->getCookie('qzone_referer'));
        $options = array(
            CURLOPT_TIMEOUT => $this->request_timeout,
            CURLOPT_HEADER => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => 'http://r.qzone.qq.com/cgi-bin/right_frame.cgi?' . http_build_query(array(
                'uin' => $this->user,
                'param' => $param,
                'g_tk' => $this->getGTKEncryption(),
            )),
            CURLOPT_HTTPHEADER => array(
                'Referer:' . $referver,
                'User-Agent:' . $this->user_agent,
                'Host:r.qzone.qq.com',
                'Connection:keep-alive',
            )
        );
        return ResultExtract::rightFrameVisitors($this->requestExec($options));
    }
}
class CCKFServiceRequest extends BaseRequest
{
    protected $service_address;
    protected $service_id;
    protected $security_key;
    public function __construct($security_key, $service_id, $service_address, $cookie_file, $request_timeout, $debug, $end_line)
    {
        parent:: __construct($cookie_file, $request_timeout, $debug, $end_line);
        $this->service_address = $service_address;
        $this->service_id = $service_id;
        $this->security_key = $security_key;
    }
}
class CCKFService extends BaseRequest
{
    public function __construct($security_key, $service_id, $service_address, $cookie_file, $request_timeout, $debug, $end_line)
    {
        parent:: __construct($security_key, $service_id, $service_address, $cookie_file, $request_timeout, $debug, $end_line);
    }
    public function uploadData($data)
    {
        if (is_array($data) && !empty($data)) {
            $options = array(
                CURLOPT_TIMEOUT => $this->request_timeout,
                CURLOPT_HEADER => 1,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_URL => $this->service_address . '?' . http_build_query(array()),
            );
        }
    }
}
class BaseConfigFileUtils
{
    protected $file;
    public function __construct($file)
    {
        $this->file = $file;
    }
    public function extractFile()
    {
        $f_str = '';
        $fp = fopen($this->file, 'r');
        if (flock($fp, LOCK_SH)) {
            while (!feof($fp)) {
                $f_str .= fgets($fp);
            }
            flock($fp, LOCK_UN);
        }
        fclose($fp);
        $c = json_decode($f_str, true);
        return is_array($c) ? $c : array();
    }
}
class RunAtTimeConfig extends BaseConfigFileUtils
{
    protected $visitor_capture_interval;
    protected $config;
    public function __construct($file, $visitor_capture_interval)
    {
        parent::__construct($file);
        $this->config = $this->extractFile();
        $this->visitor_capture_interval = $visitor_capture_interval;
    }
    public function  updateConfig($arr)
    {
        $this->config = $this->extractFile();
        if ($this->isValidateRun()) {
            $fp = fopen($this->file, 'w');
            if (flock($fp, LOCK_EX)) {
                fwrite($fp, json_encode(array_merge($this->config, $arr)));
                flock($fp, LOCK_UN);
            }
            fclose($fp);
            return true;
        }
        return false;
    }
    public function  getConfig($item)
    {
        if (is_array($this->config) && array_key_exists($item, $this->config)) {
            return $this->config[$item];
        }
        return null;
    }
    public function isValidateRun()
    {
        $c_time = Utils::getMicroTime();
        $run_at_time = floatval($this->getConfig('run_at_time'));
        if ($c_time - $run_at_time >= $this->visitor_capture_interval) {
            return true;
        } else {
            return false;
        }
    }
}
class VisitorList extends BaseConfigFileUtils
{
    protected $visitor_list;
    /**$visitor_list [] = array(
    'uin' => $visitor['uin'], 'name' => $visitor['name'], 'online' => $visitor['online'], 'time' => $visitor['time'],
    'img' => $visitor['img'], 'yellow' => $visitor['yellow'], 'supervip' => $visitor['supervip'],
    );**/
    public function __construct($file)
    {
        parent::__construct($file);
        $this->visitor_list = $this->extractFile();
    }
    public function updateVisitor($visitor)
    {
        if (is_array($visitor) && !empty($visitor)) {
            foreach ($visitor as $one) {
                array_unshift($this->visitor_list, $one);
            }
        }
        $fp = fopen($this->file, 'w');
        if (flock($fp, LOCK_EX)) {
            fwrite($fp, json_encode($this->visitor_list));
            flock($fp, LOCK_UN);
        }
        fclose($fp);
    }
    public function addVisitor($visitor)
    {
        $list = array();
        if (is_array($visitor) && !empty($visitor)) {
            foreach ($visitor as $one) {
                if (!$this->isVisitorExist($one['name'])) {
                    $list[] = $one;
                }
            }
            $this->updateVisitor($list);
        }
        return $list;
    }
    public function isVisitorExist($name)
    {
        foreach ($this->visitor_list as $one) {
            if ($one['name'] == $name) {
                return true;
            }
        }
        return false;
    }
}
PHP 相关文章推荐
一个程序下载的管理程序(四)
Oct 09 PHP
PHP+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
Feb 15 PHP
一个简单的php实现的MySQL数据浏览器
Mar 11 PHP
php 读取文件乱码问题
Feb 20 PHP
php 上一篇,下一篇文章实现代码与原理说明
May 09 PHP
PHP 第二节 数据类型之数值型
Apr 28 PHP
CodeIgniter上传图片成功的全部过程分享
Aug 12 PHP
50个PHP程序性能优化的方法
Jun 02 PHP
thinkphp模板的包含与渲染实例分析
Nov 26 PHP
必须收藏的23个php实用代码片段
Feb 02 PHP
php简单随机字符串生成方法示例
Apr 19 PHP
Laravel如何创建服务器提供者实例代码
Apr 15 PHP
php命名空间学习详解
Feb 27 #PHP
php读取excel文件示例分享(更新修改excel)
Feb 27 #PHP
php中的strpos使用示例
Feb 27 #PHP
php判断字符串在另一个字符串位置的方法
Feb 27 #PHP
php汉字转拼音的示例
Feb 27 #PHP
PHP中session变量的销毁
Feb 27 #PHP
php处理restful请求的路由类分享
Feb 27 #PHP
You might like
DC最新动画电影:《战争之子》为何内容偏激,毁了一个不错的漫画
2020/04/09 欧美动漫
第十节--抽象方法和抽象类
2006/11/16 PHP
利用laravel+ajax实现文件上传功能方法示例
2017/08/13 PHP
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
js 获取radio按钮值的实例
2013/08/17 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
基于jquery实现可定制的web在线富文本编辑器附源码下载
2015/11/17 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
AngularJS服务service用法总结
2016/12/13 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
在js中做数字字符串补0(js补零)
2017/03/25 Javascript
详解关于html,css,js三者的加载顺序问题
2019/04/10 Javascript
记一次react前端项目打包优化的方法
2020/03/30 Javascript
小程序实现录音功能
2020/09/22 Javascript
通过vue.extend实现消息提示弹框的方法记录
2021/01/07 Vue.js
[47:42]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
深入讲解Java编程中类的生命周期
2016/02/05 Python
python之virtualenv的简单使用方法(必看篇)
2017/11/25 Python
Python模块的加载讲解
2019/01/15 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
Python requests上传文件实现步骤
2020/09/15 Python
基于html5实现的图片墙效果
2014/10/16 HTML / CSS
汽车技术服务与营销专业在籍生自荐信
2013/09/28 职场文书
秋季红领巾广播稿
2014/01/27 职场文书
贯彻学习两会心得体会范文
2014/03/17 职场文书
学习交流会主持词
2014/04/01 职场文书
党的群众路线教育实践活动督导组工作情况汇报
2014/10/28 职场文书
如何写贫困证明申请书
2014/10/29 职场文书
专业技术职务聘任证明
2015/03/02 职场文书
奖励申请报告范文
2015/05/15 职场文书
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
学会Python数据可视化必须尝试这7个库
2021/06/16 Python
Python中使用ipython的详细教程
2021/06/22 Python
使用 Apache 反向代理的设置技巧
2022/01/18 Servers
Python中的tkinter库简单案例详解
2022/01/22 Python
Windows Server 2008配置防火墙策略详解
2022/06/28 Servers