Python自动下载人人所有好友的相册


写的自动抓取自己人人相册的python代码,用途貌似只有备份一下自己的相册。于是今天修改了专门针对人人网的爬虫,增加了自动抓取所有好友的功能,然后去他们的空间,把他(她)们的相册都下载回来(比较适合较多美女朋友的同学们..)...

昨天发的文章有很多标签结果太长了,于是很悲剧地,修改的时候腾讯居然不给提交,XXXXX(省略一万字...)

人人网是个很类似facebook的东东....为什么会很类似,因为中国特色....

转入正题,因为怕以后忘了,所以写下来记录一下...

好,第一点是名词解释。

爬虫是神马?

根据百度百科有: “网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。.......传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。”

偶针对人人做了一些特化(换句话说拿到其他网站就没用了),人人网要访问首先得有个帐号,也就是说要先登录,然后服务器就可以根据session或cookie来判断你在其他页面的登录情况,而对人人cookie就好了。当然,我们在一个浏览器登录,在另一个浏览器也可能还得要再登录一下,因为一般情况下他们不共享cookie,除非专门去读某个浏览器的cookie。于是爬虫要爬人人,首先要登录.....然后保存cookie。

浏览器与服务器之间通讯主要都是Http协议,方法主要有GET和POST,(据《深入理解计算机系统》说,GET方法占了99%的HTTP请求。),GET方法主要向服务器发送比较短的数据,主要将参数写到URL里面,而POST方法则可以发送比较长的数据,例如发这篇文章的话,则是用了POST。想我们可以用"Telnet www.google.com 80",然后键入"Get /"就可以可以收到和我们在浏览器打上"http://www.google.com/"同样的东西。爬虫也一样,就是不断地GET,POST……

要抓取所有好友的所有可见的相册有两种方法,一种是人工一个好友一个好友一个相册一个相册地下,另一种就是就给计算机让它自己去爬....因为我比较懒,所以选择第二种方法。

又到了“要怎么怎么样,首先怎么怎么样”的句式了~

要获取所有好友,可以在登录的情况下访问http://friend.renren.com/myfriendlistx.do,如果有用浏览器登录的话,好友会被javascript分成很多页显示。在网页的某段javascript中有个变量叫friends,保存所有好友的信息,里面都是{"id":254905709,"vip":false,"selected":true,"mo":true,"name":"\u5b89\u8feaAndy","head":"http:\/\/hdn.xnimg.cn\/photos\/hdn321\/20110612\/1600\/h_tiny_zFLc_715e000281932f76.jpg","groups":["\u534e\u5357\u7406\u5de5\u5927\u5b66"]}这种元组,从这里,我们可以获取所有好友的id。

要获取某个人的所有相册,可以访问http://www.renren.com/profile.do?id=(某人的id)&v=photo_ajax&undefined,这个是怎么找出来的呢?我们登录一个人的主页时,然后点击相册,这个页面并没有刷新,只是由AJAX替换了页面的一部分,它就是去Get那个路径,就返回了网页的一部分代码过来,替换掉现在的。所以我们也可以去Get那个路径,就可以获得包含所有相册id的页面。

要获取一个相册里面的所有照片,这个要靠人人的一个Bug了,很无意发现的,你可以打开别人相册的排序照片的页面。在排序的页面,一个相册所有的照片都列出来了,通过正则表达式,我们就可以拿到每张照片的id。排序的页面为http://photo.renren.com/photo/(某人的id)/album-(相册id)/reorder。

经过了三句“要怎么怎么样,首先怎么怎么样”,我们拿到了所有好友的id,所有好友的所有相册的id,和所有好友的所有相册的所有照片的id。为什么都是id呢?这个个人觉得用一个整数作为数据库元组的主码,性能会高些,而且对于一个32位整数,只占4字节,就可以标识4294967296个东西了。加上在客户与服务器之间传送id也方便。

拥有这些id我们可以做什么,目前什么都做不了,我们访问http://photo.renren.com/photo/(某人的id)/photo-(相片id)就可以在网页中代码中发现AJAX返回的一段代码代码中有一句"largeurl":"http:\/\/fmn.rrimg.com\/fmn049\/20110621\/1520\/p_large_S5jA_37eb000165dc5c3f.jpg",这就是一张照片的真正地址了,然后我们把里面的"\"给删掉就可以下载了。

相关文件下载:

免费下载地址在 http://linux.bkjia.com/

用户名与密码都是www.bkjia.com

具体下载目录在 /pub/2011/08/25/Python自动下载人人所有好友的相册/

好,于是我们就可以这样写出一个残缺不全的爬虫了..........对于人人的新鲜事,可以把一个页面的url抓出来筛选后放到一个优先队列里,再从优先队列里选一个最优的进入,重复上一步,直到队列为空或者其他情况....呃,传说中的中文伪代码....

程序在Ubuntu 11.04下测试正常,在Windows下可能会有乱码....

  1. # -*-coding:utf-8-*-   
  2. # Filename:main.py   
  3. # 作者:华亮   
  4. #   
  5.   
  6. from Renren import SuperRenren  
  7. import time  
  8.   
  9. def main():  
  10.     renren = SuperRenren()  
  11.     if renren.Create('人人帐号''人人密码'):  
  12.         #renren.PostMsg(time.asctime())   
  13.         #renren.PostGroupMsg('387635422', '%s' % time.asctime())   
  14.         #renren.DownloadAlbum('333982368', 'sss')   
  15.         renren.DownloadAllFriendsAlbums()  
  16.       
  17. if __name__ == '__main__':  
  18.     main()  
  19.       

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

  1. <pre name="code" class="python"># -*- coding:utf-8 -*-   
  2. # Filename:Renren.py   
  3. # 作者:华亮   
  4. #   
  5.   
  6. from HTMLParser import HTMLParser  
  7. from Queue import Empty  
  8. from Queue import Queue  
  9. from re import match  
  10. from sys import exit  
  11. from urllib import urlencode  
  12. import os  
  13. import re  
  14. import socket  
  15. import threading  
  16. import time  
  17. import urllib  
  18. import urllib2  
  19. import shelve  
  20.   
  21.   
  22. # 提供给输出的互斥对象   
  23. GlobalPrintMutex = threading.Lock()  
  24. # 提供输出config.cfg的互斥对象   
  25. GlobalWriteConfigMutex = threading.Lock()  
  26. # 提供保存用户最后更新的互斥对象   
  27. GlobalShelveMutex = threading.Lock()  
  28.   
  29.   
  30. # 根据平台不同选择不同的路径分割符   
  31. Delimiter = '/' if os.name == 'posix' else '\\'  
  32.   
  33. ConfigFilename = 'config.cfg'           # 每个相册的已经下载的图片id   
  34. LastUpdatedFileName = 'lastupdated.cfg' # 所有人的最后更新时间   
  35. UpdateThreashold = 10 * 60                 # 更新时间   
  36.   
  37. # 多核情况下的输出   
  38. def MutexPrint(content):  
  39.     GlobalPrintMutex.acquire()  
  40.     print content  
  41.     GlobalPrintMutex.release()  
  42.       
  43. def MutexWriteFile(file, content):  
  44.     GlobalWriteConfigMutex.acquire()  
  45.     file.write(content)  
  46.     file.flush()  
  47.     GlobalWriteConfigMutex.release()          
  48.       
  49.       
  50. # 字符串形式的unicode转成真正的字符   
  51. def Str2Uni(str):  
  52.     import re  
  53.     pat = re.compile(r'\\u(\w{4})')  
  54.     lst = pat.findall(str)          
  55.     lst.insert(0'')  
  56.     return reduce(lambda x,y: x + unichr(int(y, 16)), lst)      
  57.   
  58. #------------------------------------------------------------------------------    
  59. # 下载文件的下载者   
  60. class Downloader(threading.Thread):  
  61.     def __init__(self, urlQueue, failedQueue, file=None):  
  62.         threading.Thread.__init__(self)  
  63.         self.queue = urlQueue  
  64.         self.failedQueue = failedQueue  
  65.         self.file = file    
  66.                   
  67.     def run(self):  
  68.         try:  
  69.             while not self.queue.empty():  
  70.                 pid, url, filename = self.queue.get()  
  71.                 isfile = os.path.isfile(filename)                  
  72.                 MutexPrint(("\tDownloading %s" if not isfile else "\tExists %s") % filename.decode('utf-8'))                              
  73.                 if not isfile: urllib.urlretrieve(url, filename.decode('utf-8'))  
  74.                 MutexWriteFile(self.file, pid + '\n')  
  75.         except Empty:  
  76.             pass  
  77.         except Exception, e:  
  78.             self.failedQueue.put(pid)  
  79.             MutexPrint('\tError occured when downloading photo which id = %s' % pid)  
  80.             MutexPrint(e)  
  81.           
  82.              
  83.               
  84.       
  85. #------------------------------------------------------------------------------    
  86. # 人人相册的解析   
  87. class RenrenAlbums(HTMLParser):  
  88.     in_key_div = False  
  89.     in_ul = False  
  90.     in_li = False  
  91.     in_a = False  
  92.     albumsUrl = []      
  93.       
  94.     def handle_starttag(self, tag, attrs):  
  95.         attrs = dict(attrs)  
  96.         if tag == 'div' and 'class' in attrs and attrs['class'] == 'big-album album-list clearfix':  
  97.             self.in_key_div = True  
  98.         elif self.in_key_div:   
  99.             if tag == 'ul':  
  100.                 self.in_ul = True  
  101.             elif self.in_ul and tag == 'li':  
  102.                 self.in_li = True  
  103.             if self.in_li and tag == 'a' and 'href' in attrs:  
  104.                 self.in_a = True  
  105.                 self.albumsUrl.append(attrs['href'])      
  106.                   
  107.     def handle_data(self, data):  
  108.         pass      
  109.       
  110.     def handle_endtag(self, tag):  
  111.         if self.in_key_div and tag == 'div':  
  112.             self.in_key_div = False  
  113.         elif self.in_ul and tag == 'ul':  
  114.             self.in_ul = False  
  115.         elif self.in_li and tag == 'li':  
  116.             self.in_li = False  
  117.         elif self.in_a and tag == 'a':  
  118.             self.in_a = False  
  119.       
  120.       
  121. class RenrenRequester:  
  122.     ''''' 
  123.     人人访问器 
  124.     '''  
  125.     LoginUrl = 'http://www.renren.com/PLogin.do'  
  126.     # 输入用户和密码的元组   
  127.     def Create(self, username, password):  
  128.         loginData = {'email':username,  
  129.                 'password':password,  
  130.                 'origURL':'',  
  131.                 'formName':'',  
  132.                 'method':'',  
  133.                 'isplogin':'true',  
  134.                 'submit':'登录'}  
  135.         postData = urlencode(loginData)  
  136.         cookieFile = urllib2.HTTPCookieProcessor()  
  137.         self.opener = urllib2.build_opener(cookieFile)  
  138.         req = urllib2.Request(self.LoginUrl, postData)  
  139.         result = self.opener.open(req)  
  140.         if not (result.geturl() == 'http://www.renren.com/home' or 'http://guide.renren.com/guide'):  
  141.             return False    
  142.           
  143.         rawHtml = result.read()          
  144.         # 获取用户id   
  145.         useridPattern = re.compile(r'user : {"id" : (\d+?)}')  
  146.         self.userid = useridPattern.search(rawHtml).group(1)                
  147.           
  148.         # 查找requestToken           
  149.         pos = rawHtml.find("get_check:'")  
  150.         if pos == -1return False          
  151.         rawHtml = rawHtml[pos + 11:]  
  152.         token = match('-\d+', rawHtml)  
  153.         if token is None:  
  154.             token = match('\d+', rawHtml)  
  155.             if token is Nonereturn False  
  156.         self.requestToken = token.group()    
  157.         self.__isLogin = True        
  158.         return self.__isLogin  
  159.       
  160.     def GetRequestToken(self):  
  161.         return self.requestToken  
  162.       
  163.     def GetUserId(self):  
  164.         return self.userid  
  165.       
  166.     def Request(self, url, data = None):  
  167.         if self.__isLogin:  
  168.             if data:  
  169.                 encodeData = urlencode(data)  
  170.                 request = urllib2.Request(url, encodeData)  
  171.             else:  
  172.                 request = urllib2.Request(url)  
  173.             result = self.opener.open(request)  
  174.             return result  
  175.         else:  
  176.             return None  
  177.           
  178.           
  179. class RenrenPostMsg:  
  180.     ''''' 
  181.     RenrenPostMsg 
  182.         发布人人状态 
  183.     '''  
  184.     newStatusUrl = 'http://status.renren.com/doing/updateNew.do'  
  185.       
  186.     def Handle(self, requester, param):  
  187.         requestToken, msg = param  
  188.   
  189.         statusData = {'content':msg,  
  190.                     'isAtHome':'1',  
  191.                     'requestToken':requestToken}  
  192.         postStatusData = urlencode(statusData)  
  193.           
  194.         requester.Request(self.newStatusUrl, statusData)  
  195.           
  196.         return True  
  197.   
  198.           
  199. class RenrenPostGroupMsg:  
  200.     ''''' 
  201.     RenrenPostGroupMsg 
  202.         发布人人小组状态 
  203.     '''          
  204.     newGroupStatusUrl = 'http://qun.renren.com/qun/ugc/create/status'  
  205.       
  206.     def Handle(self, requester, param):  
  207.         requestToken, groupId, msg = param  
  208.         statusData = {'minigroupId':groupId,  
  209.                     'content':msg,  
  210.                     'requestToken':requestToken}  
  211.         requester.Request(self.newGroupStatusUrl, statusData)  
  212.   
  213.   
  214. class RenrenFriendList:  
  215.     ''''' 
  216.     RenrenFriendList 
  217.         人人好友列表 
  218.     '''  
  219.     def Handler(self, requester, param):       
  220.         friendUrl = 'http://friend.renren.com/myfriendlistx.do'  
  221.         rawHtml = requester.Request(friendUrl).read()     
  222.            
  223.         friendInfoPack = re.search(r'var friends=\[(.*?)\];', rawHtml).group(1)          
  224.         friendIdPattern = re.compile(r'"id":(\d+).*?"name":"(.*?)"')  
  225.         friendIdList = []  
  226.         for id, name in friendIdPattern.findall(friendInfoPack):  
  227.             friendIdList.append((id, Str2Uni(name)))  
  228.           
  229.         return friendIdList          
  230.       
  231.       
  232. class RenrenAlbumDownloader:  
  233.     ''''' 
  234.     AlbumDownloader 
  235.         相册下载者,记录已经下载的照片id到config.cfg,不会重新下载 
  236.     '''  
  237.     threadNumber = 10    # 下载线程数   
  238.       
  239.     def Handler(self, requester, param):  
  240.         self.requester = requester      
  241.         userid, path = param  
  242.         self.__DownloadOneAlbum(userid, path)  
  243.           
  244.   
  245.     # 解析html获取人名   
  246.     def __GetPeopleNameFromHtml(self, rawHtml):  
  247.         peopleNamePattern = re.compile(r'<h2>(.*?)<span>')  
  248.         # 取得人名   
  249.         peopleName = peopleNamePattern.search(rawHtml).group(1).strip()  
  250.         return peopleName  
  251.       
  252.     def __GetAlbumsNameFromHtml(self, rawHtml):  
  253.         albumUrlPattern = re.compile(r'<a href="(.*?)" stats="album_album"><img.*?/>(.*?)</a>')  
  254.         albums = []  
  255.         # 把相册路径定向到排序页面,就可以在那个页面获得该相册下所有的相片的id   
  256.         for album_url, album_name in albumUrlPattern.findall(rawHtml):  
  257.             albums.append((album_name.strip(), album_url + '/reorder'))  
  258.         return albums  
  259.       
  260.     def __GetAlbumPhotos(self, userid, albumUrl):  
  261.         # 匹配的正则表达式   
  262.         # 照片id   
  263.         pidPattern = re.compile(r'<li pid="(\d+)".*?>.*?</li>', re.S)          
  264.         # 访问所有包含所有相册的页面   
  265.         result = self.requester.Request(albumUrl)  
  266.         rawHtml = result.read()  
  267.         photohtmlurl = []   # 每张照片的页面   
  268.         for pid in pidPattern.findall(rawHtml):  
  269.             photohtmlurl.append((pid, 'http://photo.renren.com/photo/%s/photo-%s' % (userid, pid)))      
  270.               
  271.         return photohtmlurl                   
  272.           
  273.       
  274.     def __GetRealPhotoUrls(self, photohtmlurl):  
  275.         # 访问每个相册,获取所有照片,并修正相片的url   
  276.         # 照片地址   
  277.         imgPattern = re.compile(r'"largeurl":"(.*?)"')  
  278.         imgUrl = [] # id与真实照片的url   
  279.         for pid, url in photohtmlurl:  
  280.             result = self.requester.Request(url)  
  281.             rawHtml = result.read()  
  282.             for img in imgPattern.findall(rawHtml):    
  283.                 imgUrl.append((pid, img.replace('\\', '')))      
  284.                   
  285.         return imgUrl  
  286.       
  287.     def __DownloadAlbum(self, savepath, album_name, imgUrl, file):                
  288.         # 下载相册所有图片    
  289.         # 将下载文件压入队列         
  290.         queue = Queue()      
  291.         failedQueue = Queue()    
  292.         for pid, url in imgUrl:  
  293.             imgname = url.split('/')[-1]  
  294.             queue.put((pid, url, savepath + Delimiter + imgname))                        
  295.         # 启动多线程下载       
  296.         threads = []  
  297.         for i in range(self.threadNumber):  
  298.             downloader = Downloader(queue, failedQueue, file)  
  299.             threads.append(downloader)  
  300.             downloader.start()  
  301.         # 等待所有线程完成   
  302.         for t in threads:  
  303.             t.join()   
  304.         # 返回相片队列         
  305.         return failedQueue  
  306.               
  307.               
  308.     # 下载某人的相册               
  309.     def __DownloadOneAlbum(self, userid, path='albums'):  
  310.         #if not self.__isLogin: return   
  311.         if os.path.exists(path.decode('utf-8')) == False: os.mkdir(path.decode('utf-8'))          
  312.           
  313.         albumsUrl = 'http://www.renren.com/profile.do?id=%s&v=photo_ajax&undefined' % userid                     
  314.           
  315.         try:          
  316.             # 取出相册和路径               
  317.             result = self.requester.Request(albumsUrl)              
  318.             rawHtml = result.read()  
  319.             # 取得人名   
  320.             peopleName = self.__GetPeopleNameFromHtml(rawHtml).strip()  
  321.             albums = self.__GetAlbumsNameFromHtml(rawHtml)  
  322.               
  323.             # 根据人名建文件夹   
  324.             path += Delimiter + peopleName  
  325.             if os.path.exists(path.decode('utf-8')) == False: os.mkdir(path.decode('utf-8'))            
  326.               
  327.             # 开始进入相册下载               
  328.             MutexPrint('Enter %s' % peopleName.decode('utf-8'))              
  329.             for album_name, albumUrl in albums:      
  330.                 MutexPrint('Downloading Album: %s' % album_name.decode('utf-8'))  
  331.                 # 获取该相册下照片id和照片地址的表   
  332.                 photohtmlurl = self.__GetAlbumPhotos(userid, albumUrl)      
  333.                   
  334.                 # 按相册名建文件夹           
  335.                 album_name = album_name.replace('\\', '')      
  336.                 album_name = album_name.replace('/''')  
  337.                 savepath = path + Delimiter + album_name                
  338.                 if os.path.exists(savepath.decode('utf-8')) == False: os.mkdir(savepath.decode('utf-8'))    
  339.                   
  340.                 #   
  341.                 newDownloadIdSet = set()  
  342.                 finishedIdSet = set()  
  343.                 totalIdSet = set()  
  344.                 for pid, url in photohtmlurl:  
  345.                     totalIdSet.add(pid)  
  346.                   
  347.                 configFile = savepath + Delimiter + ConfigFilename  
  348.                 if os.path.isfile(configFile):    
  349.                     # 读取已经完成的照片以免重复访问获取大图地址的页面                                 
  350.                     file = open(configFile.decode('utf-8'), 'r')                      
  351.                     photoIdMap = []  
  352.                     for line in file.readlines():  
  353.                         line = line.strip()  
  354.                         pid = line  
  355.                         photoIdMap.append(pid)                          
  356.                     file.close()                      
  357.                     finishedIdSet = set(photoIdMap)                      
  358.                   
  359.                 newDownloadIdSet = totalIdSet - finishedIdSet  
  360.                   
  361.                 newDownloadPhotoHtmlUrl = ((pid, url) for pid, url in photohtmlurl if pid in newDownloadIdSet)  
  362.                   
  363.                 imgUrl = self.__GetRealPhotoUrls(newDownloadPhotoHtmlUrl)                                   
  364.                   
  365.                           
  366.                 # 下载照片                   
  367.                 try:   
  368.                     file = open(configFile.decode('utf-8'), 'w')  
  369.                     for id in finishedIdSet:  
  370.                         file.write(id + '\n')  
  371.                     file.flush()      
  372.                       
  373.                     failedQueue = self.__DownloadAlbum(savepath, album_name, imgUrl, file)       
  374.                                      
  375.                 except Exception, e:  
  376.                     print 'Error when downloading.', e        
  377.                 finally:  
  378.                     # 取出下载失败的的照片的id   
  379.                     while not failedQueue.empty():  
  380.                         totalIdSet.remove(failedQueue.get())    
  381.                     file.close()                                              
  382.         except AttributeError, e:  
  383.             raise     
  384.         except Exception, e:              
  385.             print 'Error! Please contact QQ: 414112390'  
  386.             print e  
  387.   
  388.       
  389. class AutoRenrenDownloader:  
  390.     ''''' 
  391.     AutoRenrenDownloader 
  392.         自动下载所有好友相册,具有断点续传功能,一次下载为完成,第二次会接着下 
  393.     '''  
  394.     def handler(self, requester, param):  
  395.         self.requester = requester  
  396.         path, threadnumber = param  
  397.         self.__DownloadFriendsAlbums(path, threadnumber)  
  398.           
  399.           
  400.     #------------------------------------------------------------------------------    
  401.     # 好友相册下载者           
  402.     class FriendDownloader(threading.Thread):  
  403.         def __init__(self, requester, queue, file):  
  404.             threading.Thread.__init__(self)  
  405.             self.file = file  
  406.             self.requester = requester  
  407.             self.queue = queue  
  408.           
  409.         def run(self):  
  410.             try:                               
  411.                 while not self.queue.empty():  
  412.                     id, path = self.queue.get()  
  413.                     downloader = RenrenAlbumDownloader()     
  414.                     downloader.Handler(self.requester, (id, path))  
  415.                     GlobalShelveMutex.acquire()  
  416.                     self.file['TaskList'].remove(id)  
  417.                     GlobalShelveMutex.release()  
  418.             except Empty:  
  419.                 pass  
  420.             except AttributeError, e:  
  421.                 print '有可能已经被人人网认为访问了100个好友,请访问人人网的任意好友的主页输入验证码'  
  422.                 #print e   
  423.             except ValueError, e:  
  424.                 print id  
  425.                 print e  
  426.                   
  427.                
  428.           
  429.     def __DownloadFriendsAlbums(self, path='albums', threadnumber=10):       
  430.         if not os.path.exists(path.decode('utf-8')): os.mkdir(path.decode('utf-8'))  
  431.           
  432.         friendsList = RenrenFriendList().Handler(self.requester, None)  
  433.           
  434.         db = shelve.open(LastUpdatedFileName, writeback = True)  
  435.         if not db.has_key('TaskList'): db['TaskList'] = []  
  436.         if len(db['TaskList']) == 0:  
  437.             db['TaskList'] = [id for id, realName in friendsList]  
  438.               
  439.         updateList = db['TaskList']      
  440.            
  441.         i = 1  
  442.         print "此次需要更新如下:"  
  443.         # 获取好友列表   
  444.         queue = Queue()  
  445.         for id in updateList:  
  446.             print "%s:\t%s\t" % (i, id),  
  447.             print '' if os.name == 'nt' else dict(friendsList)[id]  
  448.             i += 1  
  449.             queue.put((id, path))  
  450.               
  451.         # 下载好友      
  452.         DownloadersList = []      
  453.         failedQueue = Queue()  
  454.         try:  
  455.             for i in range(threadnumber):  
  456.                 friendDownloader = self.FriendDownloader(self.requester, queue, db)  
  457.                 friendDownloader.start()  
  458.                 DownloadersList.append(friendDownloader)          
  459.             for downloader in DownloadersList:  
  460.                 downloader.join()  
  461.         except Exception, e:  
  462.             print '-' * 100 + "\nPlease Goto Renren.com\n" + '-' * 100   
  463.             print e  
  464.         finally:  
  465.             db.close()  
  466.           
  467.                      
  468.       
  469.           
  470. class SuperRenren:  
  471.     ''''' 
  472.     SuperRenren 
  473.         人人控制器 
  474.     '''  
  475.     # 创建   
  476.     def Create(self, username, password):  
  477.         self.requester = RenrenRequester()  
  478.         if self.requester.Create(username, password):  
  479.             self.userid = self.requester.userid  
  480.             self.requestToken = self.requester.requestToken  
  481.             return True  
  482.         return False  
  483.     # 发送个人状态   
  484.     def PostMsg(self, msg):  
  485.         poster = RenrenPostMsg()  
  486.         poster.Handle(self.requester, (self.requestToken, msg))  
  487.     # 发送小组状态           
  488.     def PostGroupMsg(self, groupId, msg):  
  489.         poster = RenrenPostGroupMsg()  
  490.         poster.Handle(self.requester, (self.requestToken, groupId, msg))  
  491.     # 下载相册   
  492.     def DownloadAlbum(self, userId, path = 'albums'):         
  493.         downloader = RenrenAlbumDownloader()  
  494.         downloader.Handler(self.requester, (userId, path))  
  495.     # 自动下载所有好友相册   
  496.     def DownloadAllFriendsAlbums(self, path = 'albums', threadnumber = 10):  
  497.         downloader = AutoRenrenDownloader()  
  498.         downloader.handler(self.requester, (path, threadnumber))  
  499.                

相关内容