Python模拟登陆163邮箱并获取通讯录
001 | #-*- coding:UTF-8 -*- |
002 | import urllib,urllib2,cookielib |
003 | import xml.etree.ElementTree as etree #xml解析类 |
004 |
005 | class Login163: |
006 | #伪装browser |
007 | header = { 'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6' } |
008 | username = '' |
009 | passwd = '' |
010 | cookie = None #cookie对象 |
011 | cookiefile = './cookies.dat' #cookie临时存放地 |
012 | user = '' |
013 | |
014 | def __init__( self ,username,passwd): |
015 | self .username = username |
016 | self .passwd = passwd |
017 | #cookie设置 |
018 | self .cookie = cookielib.LWPCookieJar() #自定义cookie存放 |
019 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor( self .cookie)) |
020 | urllib2.install_opener(opener) |
021 |
022 | #登陆 |
023 | def login( self ): |
024 |
025 | #请求参数设置 |
026 | postdata = { |
027 | 'username' : self .username, |
028 | 'password' : self .passwd, |
029 | 'type' : 1 |
030 | } |
031 | postdata = urllib.urlencode(postdata) |
032 |
033 | #发起请求 |
034 | req = urllib2.Request( |
036 | data = postdata, #请求数据 |
037 | headers = self .header #请求头 |
038 | ) |
039 |
040 | result = urllib2.urlopen(req).read() |
041 | result = str (result) |
042 | self .user = self .username.split( '@' )[ 0 ] |
043 |
044 | self .cookie.save( self .cookiefile) #保存cookie |
045 | |
046 | if '登录成功,正在跳转...' in result: |
047 | #print("%s 你已成功登陆163邮箱。---------n" %(user)) |
048 | flag = True |
049 | else : |
050 | flag = '%s 登陆163邮箱失败。' % ( self .user) |
051 | |
052 | return flag |
053 |
054 | #获取通讯录 |
055 | def address_list( self ): |
056 |
057 | #获取认证sid |
058 | auth = urllib2.Request( |
059 | url = 'http://entry.mail.163.com/coremail/fcg/ntesdoor2?username=' + self .user + '&lightweight=1&verifycookie=1&language=-1&style=1' , |
060 | headers = self .header |
061 | ) |
062 | auth = urllib2.urlopen(auth).read() |
063 | for i,sid in enumerate ( self .cookie): |
064 | sid = str (sid) |
065 | if 'sid' in sid: |
066 | sid = sid.split()[ 1 ].split( '=' )[ 1 ] |
067 | break |
068 | self .cookie.save( self .cookiefile) |
069 | |
070 | #请求地址 |
071 | url = 'http://twebmail.mail.163.com/js4/s?sid=' + sid + '&func=global:sequential&showAd=false&userType=browser&uid=' + self .username |
072 | #参数设定(var 变量是必需要的,不然就只能看到:<code>S_OK</code><messages>这类信息) |
073 | #这里参数也是在firebug下查看的。 |
074 | postdata = { |
075 | 'func' : 'global:sequential' , |
076 | 'showAd' : 'false' , |
077 | 'sid' : 'qACVwiwOfuumHPdcYqOOUTAjEXNbBeAr' , |
078 | 'uid' : self .username, |
079 | 'userType' : 'browser' , |
080 | 'var' : '<!--?xml version="1.0"?--><object><array name="items"><object><string name="func">pab:searchContacts</string><object name="var"><array name="order"><object><string name="field">FN</string><boolean name="desc">false</boolean><boolean name="ignoreCase">true</boolean></object></array></object></object><object><string name="func">pab:getAllGroups</string></object></array></object>' |
081 | } |
082 | postdata = urllib.urlencode(postdata) |
083 | |
084 | #组装请求 |
085 | req = urllib2.Request( |
086 | url = url, |
087 | data = postdata, |
088 | headers = self .header |
089 | ) |
090 | res = urllib2.urlopen(req).read() |
091 | |
092 | #解析XML,转换成json |
093 | #说明:由于这样请求后163给出的是xml格式的数据, |
094 | #为了返回的数据能方便使用最好是转为JSON |
095 | json = [] |
096 | tree = etree.fromstring(res) |
097 | obj = None |
098 | for child in tree: |
099 | if child.tag = = 'array' : |
100 | obj = child |
101 | break |
102 | #这里多参考一下,etree元素的方法属性等,包括attrib,text,tag,getchildren()等 |
103 | obj = obj[ 0 ].getchildren().pop() |
104 | for child in obj: |
105 | for x in child: |
106 | attr = x.attrib |
107 | if attr[ 'name' ] = = 'EMAIL;PREF' : |
108 | value = { 'email' :x.text} |
109 | json.append(value) |
110 | return json |
111 | |
112 | #Demo |
113 | print ( "Requesting......nn" ) |
114 | login = Login163( 'xxxx@163.com' , 'xxxxx' ) |
115 | flag = login.login() |
116 | if type (flag) is bool : |
117 | print ( "Successful landing,Resolved contacts......nn" ) |
118 | res = login.address_list() |
119 | for x in res: |
120 | print (x[ 'email' ]) |
121 | else : |
122 | print (flag) |
123 | < / messages> |