首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

[分享]模拟新浪微博自动登陆,该如何处理

2012-12-31 
[分享]模拟新浪微博自动登陆博客原文地址: http://blog.csdn.net/lgg201/article/details/8050606?php/**

[分享]模拟新浪微博自动登陆
博客原文地址: 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']);


[解决办法]
郁闷了,nodejs似乎没有 for win 的版本
[解决办法]
看来虚拟主机的环境用不了,必须得自己配置nodejs才行
[解决办法]
看来要看看nodejs才行呀!!
------解决方案--------------------


观望中
[解决办法]
倒是个好东西,回头注册一个新浪账号玩玩。
[解决办法]
体会体会、、、、、、、、
[解决办法]
其实很多的网站都可以用的到了,因为微博已经火了.
[解决办法]
有分享就有进步,楼主的分享精神值得赞美
有nodejs可能暂时用不上,先收着再说

[解决办法]
其实还是不明白为什么你们一定要搞模拟登录…………
别人好好的api+oauth2接口…………………………
[解决办法]

引用:
其实还是不明白为什么你们一定要搞模拟登录…………
别人好好的api+oauth2接口…………………………


比如, 新浪提供了获取全站最新微博的接口, 而我们有系统需要抓取这些信息, 那就需要模拟一个用户登陆, 然后使用这些接口...

换言之, 基于api/oauth开发一个新浪微博的应用, 需要让新浪的用户安装该应用, 然后使用...
而我们需要的是把新浪的某些东西可以用程序自动的拿过来, 供自己的系统使用.
[解决办法]
引用:
引用:

其实还是不明白为什么你们一定要搞模拟登录…………
别人好好的api+oauth2接口…………………………


比如, 新浪提供了获取全站最新微博的接口, 而我们有系统需要抓取这些信息, 那就需要模拟一个用户登陆, 然后使用这些接口...

换言之, 基于api/oauth开发一个新浪微博的应用, 需要让新浪的用户安装该应用, 然后使用...
而我们……

谁说的
敝公司的自动采集就是用的oauth新浪api
[解决办法]
除非是涉及用户身份操作的部分,新浪api是可以不登陆使用的。
[解决办法]
啊,莫非你看的是v2接口………………
我刚去看了文档,v2的确限制大了很多。

不过敝公司和新浪合作得比较好,所以v1是可以继续使用的……………………而v1的授权没那么麻烦………………
[解决办法]
引用:
啊,莫非你看的是v2接口………………
我刚去看了文档,v2的确限制大了很多。

不过敝公司和新浪合作得比较好,所以v1是可以继续使用的……………………而v1的授权没那么麻烦………………


当然说的就是一些必须得登陆的接口啊, 如果不需要登陆可以搞定, 当然不会去搞这些玩意儿啦.
[解决办法]
引用:
引用:

啊,莫非你看的是v2接口………………
我刚去看了文档,v2的确限制大了很多。

不过敝公司和新浪合作得比较好,所以v1是可以继续使用的……………………而v1的授权没那么麻烦………………


当然说的就是一些必须得登陆的接口啊, 如果不需要登陆可以搞定, 当然不会去搞这些玩意儿啦.


比如, 如果你的站点需要做一个和新浪微博的互通, 提供一种服务, 用户授权后, 将他在新浪发的feed在你的网站也发一份..
[解决办法]
引用:
引用:

引用:

啊,莫非你看的是v2接口………………
我刚去看了文档,v2的确限制大了很多。

不过敝公司和新浪合作得比较好,所以v1是可以继续使用的……………………而v1的授权没那么麻烦………………


当然说的就是一些必须得登陆的接口啊, 如果不需要登陆可以搞定, 当然不会去搞这些玩意儿啦.


比如, 如果你的站点需要做……

这个倒是真心不需要模拟登录,用oauth采集用户发的微博即可
另外,这个方式最大的问题是用户要把他的新浪密码提交给你。
如果是我,我不会放心的。就算是我本公司的应用,我也不会提交密码的
[解决办法]
没错, 所以这个方式可以做点内部的东西,
但是不能面向客户

引用:
另外,这个方式最大的问题是用户要把他的新浪密码提交给你。
如果是我,我不会放心的。就算是我本公司的应用,我也不会提交密码的
……

[解决办法]
其实API的东西会用就行了,没必要做深入的研究,就如同我的项目中所使用的google MAP的API和Facebook的API每次他们升级都要跟着修改,烦都快要烦死了.
[解决办法]
引用:
这个倒是真心不需要模拟登录,用oauth采集用户发的微博即可


另外,这个方式最大的问题是用户要把他的新浪密码提交给你。
如果是我,我不会放心的。就算是我本公司的应用,我也不会提交密码的



额....说反了...
我们这边的业务好像是在我们站发的东西需要往新浪微博发一份..
[解决办法]
引用:
引用:
这个倒是真心不需要模拟登录,用oauth采集用户发的微博即可
另外,这个方式最大的问题是用户要把他的新浪密码提交给你。
如果是我,我不会放心的。就算是我本公司的应用,我也不会提交密码的


额....说反了...
我们这边的业务好像是在我们站发的东西需要往新浪微博发一份..

敝站也有用户评论然后同步到微博的功能…………也是oauth搞定的…………
敝公司官微是一套单输入接口然后同步到新浪搜狐腾讯twitter的,也是oauth的……………………………………
[解决办法]
引用:
引用:

引用:
这个倒是真心不需要模拟登录,用oauth采集用户发的微博即可
另外,这个方式最大的问题是用户要把他的新浪密码提交给你。
如果是我,我不会放心的。就算是我本公司的应用,我也不会提交密码的


额....说反了...
我们这边的业务好像是在我们站发的东西需要往新浪微博发一份..

敝站也有用户评论然后同步到微博的功能…………


这个最普通的应用(和新浪没有合作关系), 不登陆能搞定哪些啊?
因为我这个模拟登陆是帮其他项目组做的, 所以不了解具体的接口....
上面我说的都是大概了解发散猜想的...
[解决办法]
引用:
这个最普通的应用(和新浪没有合作关系), 不登陆能搞定哪些啊?
因为我这个模拟登陆是帮其他项目组做的, 所以不了解具体的接口....
上面我说的都是大概了解发散猜想的...


这么说吧,你用新浪微博的api,能制作一个完整的新浪微博客户端。
也就是说,什么都能搞定。
[解决办法]
没有必要争论是否有必要自搞一套
虽然有现成的API有待深度发掘,但弄一个另类的也不失是个好主意
如果都套在一个框框里,那编程还有什么趣味?

[解决办法]
引用:
没有必要争论是否有必要自搞一套
虽然有现成的API有待深度发掘,但弄一个另类的也不失是个好主意
如果都套在一个框框里,那编程还有什么趣味?


唠叨此言差矣。

模拟登录,使用的是别人的内部接口,一旦这个接口有所改动,一不会反映在文档上,二根本没有文档,会给以后的维护带来无穷无尽的负担。使用google未开放api的开发者应该深有体会。上两个月,就有一批应用同时失灵,因为他们使用的api被关闭了;该api未开放,所以无预警。

在这个讨论中,我有两个观点:

1 不要重复发明轮子;
2 对方开放了前门,就不要复制后门的钥匙。
[解决办法]
参见:

http://www.google.com.hk/search?hl=en&q=google+api+%E5%85%B3%E9%97%AD
[解决办法]
1、楼主并没有去发明轮子,只是给轮子换了个材质。这在专利上称:实用新型
不要重复发明轮子,这个观点存在问题(当然这话也不是你发明的)。轮子自古就有,如果不对轮子进行创新。那现在满大街不都是木头轮子?
2、楼主发帖的意图就是告诉我们,不止前门可走。走走后门也是行的通的

[解决办法]
刚去找了下负责该项目的同事, 确认了该接口(获取某用户微博)需要登陆.

又到新浪微博开放平台看了下文档, 得到以下信息:
1. 自2012.10.15起,平台将禁止“累计使用人数小于10,000”的应用使用V1接口。请及时完成新版接口迁移以保证应用正常运行。迁移指南:http://t.cn/zWTaigK
2. http://open.weibo.com/wiki/2/statuses/user_timeline这个接口文档中明确提出了需要登陆

可能你们公司的应用授权级别高而不需要登陆吧....

也有可能我们没有互相理解对方的描述. 我再尝试描述一次这个模拟登陆的用途吧:
通过用户名和密码(通常这个用户名和密码不是用户提供的, 而是我们自己注册一个公司用的)换取access_token, 使得某些需要持续有效的access_token访问某些新浪微博要求登陆的接口的后台服务可以持续有效.
[解决办法]
引用:
也有可能我们没有互相理解对方的描述. 我再尝试描述一次这个模拟登陆的用途吧:
通过用户名和密码(通常这个用户名和密码不是用户提供的, 而是我们自己注册一个公司用的)换取access_token, 使得某些需要持续有效的access_token访问某些新浪微博要求登陆的接口的后台服务可以持续有效.

就这个描述来说,我还是倾向于使用oauth,因其可以完成这个描述的需求。

我之所以不建议使用模拟登录,是因为模拟登录使用的方法是非公开的,被改变时无预警无文档。

热点排行