天天看點

《python爬蟲實戰》:模拟登陸

前面幾篇博文基本上都是在不需要進行登陸的網頁上面的進行内容的抓取。如果有的網頁時需要我們先登陸後才能看到的,那麼如果要爬取這些上面的網頁的内容,就需要先模拟登陸,然後進行資料的抓取。這篇博文是自己學習的如何進行模拟登陸,将其記錄下來。

本博文将其知乎網:http://www.zhihu.com為例。

第一步:擷取知乎網首頁的html源碼

用簡單的get方法來擷取知乎網首頁的html源碼,實作代碼如下:

#encoding=utf-8
#模拟登陸,以知乎網為例
import urllib2
import urllib
import re
class SimuLogin:
    def __init__(self,url):
        self.url=url
    #爬取知乎首頁的html源碼
    def getPageHtml(self):
        user_agent="Mozilla /5.0 (Windows NT (6.1))"
        headers={"User-Agent":user_agent}
        request=urllib2.Request(self.url,headers=headers)
        html=urllib2.urlopen(request)
        print html.read() #測試輸出
        return html.read()

#測試
url=raw_input("input a url:")
sLogin=SimuLogin(url)
sLogin.getPageHtml()
           

上面的代碼與前幾篇博文的代碼一模一樣,但是在我們爬取知乎網首頁的html源碼時,報錯。報錯如下:

《python爬蟲實戰》:模拟登陸

網上查資料,說是有可能是那個網站阻止了這類的通路,隻要在請求中加上僞裝成浏覽器的header就可以了,但是以上的代碼确實已經加上了請求頭,居然報錯,開始檢查代碼,看是否有自己寫錯的地方,發現沒有,自己就寫了自己寫的第一個爬百度的html的代碼,如下:

#encoding=utf-8
import urllib2
#response=urllib2.urlopen("http://www.xingjiakmite.com")
response=urllib2.urlopen("http://www.baidu.com")
print response.read()
           

居然還是報相同的錯,現在我都開始懷疑是我的環境有問題,實在是郁悶,找了半天的原因,最後的原因居然是:我把Fiddler 這個軟體打開了,這個軟體切斷了我的所有爬蟲的請求。

今天花了點時間,重新折騰了下關于這個模拟登陸,需要下面4個參數,但是隻有_xsrf是需要我們在登陸首頁擷取的,是以,步驟如下:

《python爬蟲實戰》:模拟登陸

1、首先擷取要登陸頁面的“_xsrf”的值

實作代碼如下:

def getXSRF(data):
    #<input type="hidden" name="_xsrf" value="e9d826c0fa34d68b3320d10c60df8588">
    pattern= re.compile(r'<input type="hidden" name="_xsrf" value="(.*?)"',re.S)
    strlist = re.findall(pattern,data)
    print u"xsrf:"+strlist[] #測試輸出
    return strlist[]
url="http://www.zhihu.com/"
response=urllib2.urlopen(url)
#print response.read().decode("utf-8")
data=response.read()
_xsrf=getXSRF(data)  #得到_xsrf,之後就可以模拟登陸了
           

2、模拟浏覽器并通過post來傳送參數資料

實作代碼如下:

header = {
    'Connection': 'Keep-Alive',
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Accept-Encoding': 'gzip, deflate',
    'Host': 'www.zhihu.com',
    'Dnt': '1'
}
#擷取opener

def getopener(head):#接收一個head參數
    #第一步:得到一個cookie執行個體對象來儲存Cookie内容
    cookie=cookielib.CookieJar()
    #第二步:利用urllib2庫中的HTTPCookieProcessor得到一個cookie的處理器
    pro=urllib2.HTTPCookieProcessor(cookie)
    #第三步:得到opener
    opener=urllib2.build_opener(pro)
    header=[]
    for key,value in head.items():
        elem=(key,value)
        header.append(elem)
    opener.addheaders=header
    return opener
#模拟浏覽器
opener=getopener(header)
url+="login/email"
id="[email protected]"
password="123456"
postDict={"_xsrf":_xsrf,
        "email":id,
        "password":password,
        "rememberme":"true"
        }
postData=urllib.urlencode(postDict).encode()
html=opener.open(url,postData)
print html.read()#
print html.info().get("Content-Encoding")
           

到這裡原以為就能夠登陸成功,但是,還差一步,知乎現在有驗證碼,是以,還需要破解驗證碼之後才能登陸成功,下次來研究下怎麼來擷取驗證碼。

完整代碼如下:

#encoding=utf-8
import urllib2
import urllib
import cookielib
import re
import gzip
#解壓gzip包
def ungzip(data):
    try:     #嘗試解壓
        print(u"解壓中...")
        data=gzip.decompress(data)
        print(u"解壓完成")
    except:
        print(u"未經壓縮,無需解壓")
    return data
header = {
    'Connection': 'Keep-Alive',
    'Accept': 'text/html, application/xhtml+xml, */*',
    'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Accept-Encoding': 'gzip, deflate',
    'Host': 'www.zhihu.com',
    'Dnt': '1'
}
#擷取opener

def getopener(head):#接收一個head參數
    #第一步:得到一個cookie執行個體對象來儲存Cookie内容
    cookie=cookielib.CookieJar()
    #第二步:利用urllib2庫中的HTTPCookieProcessor得到一個cookie的處理器
    pro=urllib2.HTTPCookieProcessor(cookie)
    #第三步:得到opener
    opener=urllib2.build_opener(pro)
    header=[]
    for key,value in head.items():
        elem=(key,value)
        header.append(elem)
    opener.addheaders=header
    return opener
def getXSRF(data):
    #<input type="hidden" name="_xsrf" value="e9d826c0fa34d68b3320d10c60df8588">
    pattern= re.compile(r'<input type="hidden" name="_xsrf" value="(.*?)"',re.S)
    strlist = re.findall(pattern,data)
    print u"xsrf:"+strlist[] #測試輸出
    return strlist[]
# response=urllib2.urlopen("http://www.xingjiakmite.com")
url="http://www.zhihu.com/"
response=urllib2.urlopen(url)
#print response.read().decode("utf-8")
data=response.read()
_xsrf=getXSRF(data)  #得到_xsrf,之後就可以模拟登陸了
#模拟浏覽器
opener=getopener(header)
url+="login/email"
id="[email protected]"
password="123456"
postDict={"_xsrf":_xsrf,
        "email":id,
        "password":password,
        "rememberme":"true"
        }
postData=urllib.urlencode(postDict).encode()
html=opener.open(url,postData)
print html.read()#到這裡原以為就能夠登陸成功,但是,還差一步,知乎現在有驗證碼,是以,還需要破解驗證碼之後才能登陸成功
print html.info().get("Content-Encoding")
#對資料進行解壓
data=ungzip(html.read().decode())
print data
           

小結

原以為用python進行模拟登陸會比較簡單,經過自己嘗試,發現還是有點不簡單呀,到目前為止,還沒有成功登陸,還有驗證碼這個問題沒有解決,嗚嗚。最近由于新項目的啟動,很忙,沒有時間做這塊了,嗚嗚。