[分享]模拟新浪微博自动登陆
博客原文地址: http://blog.csdn.net/lgg201/article/details/8050606
<?php
/**
* 功能: 模拟新浪微博登陆
* 用途: 模拟用户登陆, 以便进行后续操作, 比如自动化的控制自己的新浪app刷新某些数据
* 注意事项:
* 1. 需要安装nodejs
* 2. 需要下载新浪的加密js文件, 请到新浪登陆页查看网络请求自己下载最新版本(我当时用的: http://js.t.sinajs.cn/t35/miniblog/static/js/sso.js?version=e482ef2bbdaa8bc2)
* 3. 对新浪加密js文件进行修改, 以便让nodejs可以运行它
*1) 在文件前面增加下面内容
varwindow= {
location: {
hash: '',
host: 'weibo.com',
hostname: 'weibo.com',
href: 'http://weibo.com/',
pathname: '/',
port: '',
protocol: 'http:',
search: ''
},
navigator: {
appCodeName: 'Mozilla',
appName: 'Netscape',
appVersion: '5.0 (Macintosh)',
buildID: '20120713134347',
cookieEnabled: true,
doNotTrack: 'unspecified',
language: 'en-US'
}
};
varlocation= window.location;
varnavigator= window.navigator;
*2) 在文件后面增加下面内容
varargv= process.argv.splice(2);
varpubkey= argv[0],
servertime= argv[1],
nonce= argv[2],
password= argv[3];
var RSAKey = new sinaSSOEncoder.RSAKey();
RSAKey.setPublic(pubkey, '10001');
password = RSAKey.encrypt([servertime, nonce].join("\t") + "\n" + password);
console.log(password);
process.exit();
*4. 修改encode_password函数中的nodejs程序路径和修改后的新浪js文件路径
* 5. 修改用户名密码
* author: selfimpr
* blog: http://blog.csdn.net/lgg201
* mail: lgg860911@yahoo.com.cn
*/
define('REQUEST_METHOD_GET','GET');
define('REQUEST_METHOD_POST','POST');
define('REQUEST_METHOD_HEAD','HEAD');
define('COOKIE_FILE','/tmp/sina.login.cookie');
function curl_switch_method($curl, $method) {
switch ( $method) {
case REQUEST_METHOD_POST:
curl_setopt($curl, CURLOPT_POST, TRUE);
break;
case REQUEST_METHOD_HEAD:
curl_setopt($curl, CURLOPT_NOBODY, TRUE);
break;
case REQUEST_METHOD_GET:
default:
curl_setopt($curl, CURLOPT_HTTPGET, TRUE);
break;
}
}
function curl_set_headers($curl, $headers) {
if ( empty($headers) ) return ;
if ( is_string($headers) )
$headers= explode("\r\n", $headers);
#类型修复
foreach ( $headers as &$header )
if ( is_array($header) )
$header= sprintf('%s: %s', $header[0], $header[1]);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
function curl_set_datas($curl, $datas) {
if ( empty($datas) ) return ;
curl_setopt($curl, CURLOPT_POSTFIELDS, $datas);
}
function curl_request($url, $method = REQUEST_METHOD_GET, $datas = NULL, $headers = NULL) {
static$curl;
if ( !$curl )
$curl= curl_init();
curl_switch_method($curl, $method);
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION,TRUE);
curl_setopt($curl, CURLOPT_AUTOREFERER,TRUE);
curl_setopt($curl, CURLOPT_COOKIEJAR,COOKIE_FILE);
curl_setopt($curl, CURLOPT_COOKIESESSION,TRUE);
if ( $datas )
curl_set_datas($curl, $datas);
if ( $headers)
curl_set_headers($curl, $headers);
$response= curl_exec($curl);
if ( $errno = curl_errno($curl) ) {
error_log(sprintf("%10d\t%s\n", $errno, curl_error($curl)), 3, 'php://stderr');
return FALSE;
}
return $response;
}
function get_js_timestamp() {
return time() * 1000 + rand(0, 999);
}
function http_build_query_no_encode($datas) {
$r= array();
foreach ( $datas as $k => $v )
$r[]= $k . '=' . $v;
return implode('&', $r);
}
function makeUrl($url, $info, $encode = TRUE) {
if ( !is_array($info) || empty($info) ) return $url;
$components= parse_url($url);
if ( array_key_exists('query', $components) )
$query= parse_str($components['query']);
else
$query= array();
if ( is_string($info) ) $info = parse_str($info);
$query= array_merge($query, $info);
$query= $encode
? http_build_query($query)
: http_build_query_no_encode($query);
$components['scheme']= array_key_exists('scheme', $components)
? $components['scheme'] . '://'
: '';
$components['user']= array_key_exists('user', $components)
? $components['user'] . ':' . $components[HTTP_URL_PASS] . '@'
: '';
$components['host']= array_key_exists('host', $components)
? $components['host']
: '';
$components['port']= array_key_exists('port', $components)
? ':' . $components['port']
: '';
$components['path']= array_key_exists('path', $components)
? '/' . ltrim($components['path'], '/')
: '';
$components['query']= $query
? '?' . $query
: '';
$components['fragment']= array_key_exists('fragment', $components)
? '#' . $components['fragment']
: '';
return sprintf('%s%s%s%s%s%s%s', $components['scheme'], $components['user'], $components['host'],
$components['port'], $components['path'],
$components['query'], $components['fragment']);
}
function encode_username($username) {
return base64_encode(urlencode($username));
}
function encode_password($pub_key, $password, $servertime, $nonce) {
#这里是要用nodejs执行新浪的js文件
$response= `/usr/local/node.js-0.8.8/bin/node sina.js "$pub_key" "$servertime" "$nonce" "$password"`;
return substr($response, 0, strlen($response) - 1);
}
function main_page() {
return curl_request('weibo.com');
}
function prepare_login_info() {
$time= get_js_timestamp();
$url= makeUrl('http://login.sina.com.cn/sso/prelogin.php', array(
'entry'=> 'sso',
'callback'=> 'sinaSSOController.preloginCallBack',
'su'=> encode_username('undefined'),
'rsakt'=> 'mod',
'client'=> 'ssologin.js(v1.4.2)',
'_'=> $time,
), FALSE);
$response= curl_request($url);
$length= strlen($response);
$left= 0;
$right= $length - 1;
while ( $left < $length )
if ( $response[$left] == '{' ) break;
else $left ++;
while ( $right > 0 )
if ( $response[$right] == '}' ) break;
else $right --;
$response= substr($response, $left, $right - $left + 1);
return array_merge(json_decode($response, TRUE), array(
'preloginTime'=> max(get_js_timestamp() - $time, 100),
));
}
function login($info, $username, $password) {
$feedbackurl= makeUrl('http://weibo.com/ajaxlogin.php', array(
'framelogin'=> 1,
'callback'=> 'parent.sinaSSOController.feedBackUrlCallBack',
));
$datas= array(
'encoding'=> 'UTF-8',
'entry'=> 'weibo',
'from'=> '',
'gateway'=> 1,
'nonce'=> $info['nonce'],
'prelt'=> $info['preloginTime'],
'pwencode'=> 'rsa2',
'returntype'=> 'META',
'rsakv'=> $info['rsakv'],
'savestate'=> 7,
'servertime'=> $info['servertime'],
'service'=> 'miniblog',
'sp'=> encode_password($info['pubkey'], $password, $info['servertime'], $info['nonce']),
'ssosimplelogin'=> 1,
'su'=> encode_username($username),
'url'=> $feedbackurl,
'useticket'=> 1,
'vsnf'=> 1,
);
$url= makeUrl('http://login.sina.com.cn/sso/login.php', array(
'client'=> 'ssologin.js(v1.4.2)',
), FALSE);
$response= curl_request($url, REQUEST_METHOD_POST, $datas);
$sign= 'location.replace(\'';
$response= substr($response, strpos($response, $sign) + strlen($sign));
$location= substr($response, 0, strpos($response, '\''));
$response= curl_request($location);
$length= strlen($response);
$left= 0;
$right= $length - 1;
while ( $left < $length )
if ( $response[$left] == '{' ) break;
else $left ++;
while ( $right > 0 )
if ( $response[$right] == '}' ) break;
else $right --;
$response= substr($response, $left, $right - $left + 1);
return json_decode($response, true);
}
$info= prepare_login_info();
$info= login($info, '用户名', '密码');
echo curl_request('http://weibo.com/u/' . $info['userinfo']['uniqueid'] . $info['userinfo']['userdomain']);