您的位置:首页 > 编程语言 > Python开发

python模拟登录新浪微博

2015-03-11 21:36 435 查看
Python 模拟登陆说明
一、基础知识

/article/7672628.html

用python爬虫抓站的一些技巧总结

http://www.open-open.com/lib/view/open1375945149312.html

1、浅谈HTTP中Get与Post的区别

(1)Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

特别的,GET用于信息获取,POST表示可能修改变服务器上的资源的请求。

(2)请求形式的差别

GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&
verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如%E4%BD%A0
%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。

POST把提交的数据则放置在是HTTP包的包体中。

(3)GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大
量的数据。
(4)POST的安全性要比GET的安全性高。

总结一下:Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!

以上内容来自一篇个人博客的提炼。博客地址:(http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html)

2、通过工具抓取客户端与服务器之间的数据报

我使用火狐浏览器中安装插件--抓包工具Firebug 2.0.6(http://getfirebug.com/),此插件可以获得浏览器与所发送的各种数据。如果使用的是谷歌浏览器,也可以通过审查元素中的Network获得数据,它对抓取的数据分类不是很好,看起来有点费劲。
简单介绍一下抓包工具的使用Firebug
a、打开目标网页,点击F12或者右键可以看到firebug的审查元素。
b、在firebug目录上切换到网络一栏,然后clear数据,刷新一下网页就可以看到他们之间的交互信息。
c、点保持功能,会把所有的请求保留下来,以便分析。

二、分析网页
1、查看网页源代码,找到网页的表单数据(form)和网页的input标签,查看用户登录数据的去处。
2、通过抓包工具,查看b/s之间的有哪些交互,并分析这些get和post请求涉及到哪些参数。参数是否加密,参数的来源那里等。
特别的,一些安全性好的网站,会对用户的用户数据进行加密与在post的表单中增加一些自定义的参数。
用户名或者密码的加密,通过产看数据的去处可以获得处理的方式
自定义的参数:1.服务器返回的2、存在请求的网页中存在,查看代码即可获得。

For example
新浪客户端
1、username 经过BASE64计算
2、password经过三次SHA1加密,且其中加入了 servertime 和 nonce 的值来干扰。即: 两次SHA1加密后,结果加上servertime和nonce的值,再SHA1算一次。在最新的rsa加密方法中,username还是以前一样的处理;
password加密方式和原来有所不同:
2.1 先创建一个rsa公钥,公钥的两个参数新浪微博都给了固定值,不过给的都是16进制的字符串,第一个是登录第一步中的pubkey,第二个是js加密文件中的‘10001'。
这两个值需要先从16进制转换成10进制,不过也可以写死在代码里。这里就把10001直接写死为65537。代码如下:
rsaPublickey = int(pubkey, 16)

key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥

message = str(servertime) + '\t' + str(nonce)+ '\n' + str(password) #拼接明文js加密文件中得到

passwd = rsa.encrypt(message, key) #加密

passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。

3、上面的消息是怎么知道的。
1、分析登录网页http://login.sina.com.cn/signup/signin.php?entry=sso的代码搜username和password的去处,发现在javascript代码中处理,在附近查找js文件,发现<script charset="utf-8"type="text/javascript"src="/js/sso/ssologin.js"></script>。进入到js文件中在搜username和password就可以看到相应的处理了。

三、登录一些情况

1、伪装成浏览器访问

某些网站反感爬虫的到访,于是对爬虫一律拒绝请求,我们需要伪装成浏览器,这可以通过修改http包中的header来实现。代码如下

1. headers = {

2. 'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
3. }

4. req = urllib2.Request(
5. url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/',

6. data = postdata,
7. headers = headers

8. )

2、cookie的处理

网站的都要对缓存进行处理,在提交时需要缓存的消息,避免多次认证。

1. style="font-size:18px;">import urllib2, cookielib

2. cookie_support= urllib2.HTTPCookieProcessor(cookielib.CookieJar())
3. opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)

4. urllib2.install_opener(opener)
5. content = urllib2.urlopen('http://XXXX').read()

这部分来自博客http://www.cnblogs.com/mfryf/p/3695844.html

四、具体的两个实例

A、登录新浪微博

1、先打开firebug clear,填写登录信息登录,可以看到交互的信息。

2、第一个get是获得post表单的数据"servertime" 和 "nonce" 的值, 是随机的。主要是新浪增加安全而设的,有的网站直接就是post,之前是不需要服务器返回数据的。

3、分析post方式的表单,看那些数据是不变或者是针对不同用户有改变的,多次登录抓包可以对比出来。

4、获得登录信息后,依次对响应的信息访问即可。

5、总结一下,此过程是需要带着缓存消息,我们需要保留每次的缓存,并带着缓存一起提交。

6、代码
#!/usr/bin/envpython
# -*-coding: utf-8 -*-
#@Date : 2014-11-20 12:35:39
#@Author : Your Name (you@example.org)
#@Link : http://example.org #@Version : $Id$

importos
importurllib
importurllib2
importcookielib
importbase64
importre
importhashlib
importjson
importrsa
importbinascii

cj=cookielib.LWPCookieJar()
cookie_support=urllib2.HTTPCookieProcessor(cj)
opener=urllib2.build_opener(cookie_support,urllib2.HTTPHandler)
urllib2.install_opener(opener)

postdata={
'cdult':'3',
'entry':'account',
'gateway':'1',
'from':'',
"savestate":'30',
'userticket':'0',
'pagerefer':'',
'geteway': '1',
'rsakv': '1330428213',
'prelt':'317',
'su': '',
'service': 'sso',
'servertime':'',
'nonce':'',
'pwencode':'rsa2',
'sp':'',
'encoding':'UTF-8',
'domain':'sina.com.cn',
'returntype':'TEXT',
'vsnf':'1'

}
#获取服务器的时间
defget_servertime():
url='http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)%lih211@sina.com'
data=urllib2.urlopen(url).read()
print data
p=re.compile('\((.*)\)')
try:
json_data=p.search(data).group(1)
data=json.loads(json_data)
servertime=str(data['servertime'])
nonce=str(data['nonce'])

returnservertime,nonce
except Exception, e:
print'get servertime error'
returnNone

#对密码加密

defget_pwsd(pwd,servertime,nonce):
# pwd1=hashlib.sha1(pwd).hexdigest()
# pwd2=hashlib.sha1(pwd1).hexdigest()
# pwd3_ =""+pwd2 + servertime +nonce
# pwd3=hashlib.sha1(pwd3_).hexdigest()
# return pwd3

pubkey='EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443'
rsaPublickey = int(pubkey, 16)
pub_key = rsa.PublicKey(rsaPublickey, int('10001', 16))
pwd = '%s\t%s\n%s' % (servertime, nonce,pwd)
pwd1= rsa.encrypt(pwd, pub_key) #jiami
pwd1=binascii.b2a_hex(pwd1)
return pwd1

defget_user(username):
username1=urllib.quote(username) #编码
username=base64.encodestring(username1)[:-1]
return username

deflogin():
username='lih211@sina.com'
pwd='ta3344521'
url='http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.18)'
try:
servertime,nonce=get_servertime()
#print servertime,nonce
except Exception, e:
return

global postdata
postdata['servertime']=servertime
postdata['nonce']=nonce
postdata['su']=get_user(username)
postdata['sp']=get_pwsd(pwd,servertime,nonce)

postdata=urllib.urlencode(postdata)

headers={'User-Agent':'Mozilla/5.0 (X11;Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0'}
req=urllib2.Request(
url=url,
data=postdata,
headers=headers
)

result=urllib2.urlopen(req)
text=result.read()
print text
dic=json.loads(text)
print dic['crossDomainUrlList'][0]
print dic['crossDomainUrlList'][1]

# p =re.compile('location\.replace\(\"(.*?)\"\)')
try:
#login_url=p.search(text).group(1)
login_url=dic['crossDomainUrlList'][0]
urll=urllib2.urlopen(login_url).read()
#for index, cookie in enumerate(cj):
# print '[',index, ']',cookie;
urll2=urllib2.urlopen(dic['crossDomainUrlList'][1]).read()
print'-------------------------------'
forindex, cookie in enumerate(cj):
print '[',index, ']',cookie;
print"登录成功!",urll
printurll2
printurllib2.urlopen('http://weibo.com/aj/mblog/fsearch?domain=3053595304&ajwvr=6&wvr=5&sudaref=www.baidu.com&pre_page=1&page=1&end_id=3779663979192652&pagebar=1&__rnd=1416626073104').read()
except:
print'Login error!'

login()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: