1. 程式人生 > >用python的cookielib模擬登入虎撲下載相簿圖片

用python的cookielib模擬登入虎撲下載相簿圖片

    虎撲裡有個大神叫科比ni很帥,他的虎撲相簿裡有很多科比的精美gif,其質量之高,內容之廣,虎撲中無出其右。無奈圖片數量太大,如果一張一張右鍵儲存工作量相當可觀。之前我也寫過抓取虎撲帖子上圖片的程式。奈何虎撲相簿需要登入才能檢視,於是我利用週末的時間學習了一下python的模擬登入,寫了個小程式。由於初學,程式可能比較渣,有大神路過希望能給與指導,如果也有初學者路過,歡迎一同探討。

    首先要登入肯定要Post一些資訊給伺服器,登入虎撲還比較簡單,每次登入都會把你帶到登入頁面:http://passport.hupu.com/login。然後我們就用Firebug這個外掛在Firefox上看看我們到底傳送了什麼資料。

    被我塗抹掉的部分是我的密碼。我們要傳送的資料已經就是用紅圈圈起來的Source下邊的內容。其實如果不利用cookielib,直接向虎撲傳送這些資料就能實現登入,但是這樣的話,我們只能獲得登入成功介面,這是沒什麼用的。我們要帶著登入資訊在網頁上瀏覽才能看到人家的相簿。

    我們建立一個CookieJar的物件,用於收集cookie,然後建立一個能夠處理cookie的opener,這樣就完成了主要部分,剩下的就是解析獲得的HTML檔案,用HTMLParser還是正則表示式就隨意了,我一般是網頁中稀少的東西用正則表示式提取,如果網頁中比較多就用HTMLParser。下邊把程式碼貼上來吧。

import urllib2
import cookielib
import re
import os
from HTMLParser import HTMLParser

class Photo(HTMLParser):

    header={\
            'User-Agent' : 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0'\
            }

    def __init__(self):
        HTMLParser.__init__(self)
        self.opener=None
        self.getOpener()
        self.start=False
        self.image_list=[]

    def handle_starttag(self,tag,attrs):
        if(tag=='div'):
            if([('class','albumlist_list')] == attrs):
                self.start=True
        elif(self.start and tag=='a'):
            if(len(attrs)==1 and 'href' in attrs[0]):
                self.image_list.append(attrs[0][1])
        else:
            pass

    def handle_endtag(self,tag):
        if(self.start and tag=='div'):
            self.start=False

    def getOpener(self):
        data='mobile=&code=&authCode=&usernameMobile=&username=shuoyin&password=*****&charset=utf-8&jumpurl=http%3A%2F%2Fnba.hupu.com%2F&captcha%5Bclient_public_key%5D=&captcha%5Bclient_token%5D=&isNewSeccode=&mode=email'
        request=urllib2.Request('http://passport.hupu.com/login',data,Photo.header)#'*' represents for my password
        cookie=cookielib.CookieJar()
        handle=urllib2.HTTPCookieProcessor(cookie)
        self.opener=urllib2.build_opener((handle))
        self.opener.open(request)

    def getimagelinks(self,url):
        pattern='<a href="(\\S*?)" class="next">'
        pattern=re.compile(pattern)
        while url:
            request=urllib2.Request(url,headers=Photo.header)
            html=self.opener.open(request).read()
            self.feed(html)
            x=pattern.search(html)
            url=(x!=None and 'http://my.hupu.com'+x.groups()[0] or None)
        
    def download(self,url,save_path):
        try:
            os.makedirs(save_path)
        except:
            pass
        self.image_list=[]
        self.getimagelinks(url)
        print self.image_list
        alt=open(os.path.join(save_path,'alt.txt'),'w')
        pattern=re.compile('<img id="bigpic" alt="(.*?)" src="(\\S*?)"')
        for num,link in enumerate(self.image_list):
            fullurl='http://my.hupu.com'+link
            request=urllib2.Request(fullurl,headers=Photo.header)
            html=self.opener.open(request).read()
            x=pattern.findall(html)
            alt.write('%d: '%num)
            alt.write(x[0][0])
            alt.write('\n')
            try:
                img=urllib2.urlopen(x[0][1]).read()
            except urllib2.URLError,e:
                print '%d Failed, reason: '%num,e
                continue
            imgname='%d.'%num+x[0][1][-3:]
            saveimg=open(os.path.join(save_path,imgname),'w+b')
            saveimg.write(img)
            saveimg.close()


if __name__=="__main__":
    m=Photo()
    url=raw_input('Please enter the url of the album:\n')
    path=raw_input('please enter the path you want to keep them:\n')
    m.download(url,path)

樣例輸入:

http://my.hupu.com/4636142/photo/a143789.html

/home/yinshuo/kobe/clutch

由於程式寫的不是很健壯,所以只能接受完整的URL和完整的路徑。並且受制於我的可憐的網路知識,只能是相簿第一頁(也就是一個相簿的根目錄)

另外,每個相簿開啟之後都會有一個圖片處於選中狀態,造成這個圖片無法被我的程式識別出來,我不想為了這一個圖片而加入一個特例,又沒有想出一個好的方法。所以現在這個程式有個bug,誰有好的方法希望能教教我。下邊是下載完成之後的效果。