在認識爬蟲中我給自己設(shè)定一個目標(biāo)就是學(xué)習(xí)模擬登錄篡殷。但是目前的知乎瞬内、豆瓣都要輸入驗證碼,本以為可愛的簡書是不會的载矿,結(jié)果他居然要滑動圖塊解鎖垄潮。但是學(xué)技術(shù)總要先會一點簡單的呀,于是我就拿我自己的個人網(wǎng)站xuzhougent.top開刀了闷盔。由于阿里云服務(wù)器6-17號到期了魂挂,一時半會我也沒有續(xù)期的打算,所以估計你們看的時候馁筐,這個域名已經(jīng)打不開了。
背景知識
這個部分其實打算放在最后作為補充閱讀的坠非,但是作為一個懶人深知大家會直接翻到后面看重點敏沉,但是我覺得這一部分對于理解代碼更加重要,所以我就自作主張?zhí)崆傲恕?/p>
1. Request objects
Scrapy使用Request和Response對象爬取網(wǎng)站。通常而言盟迟,Request從spiders從產(chǎn)生秋泳,到Downloader時執(zhí)行request返回Reponse對象。Response返回到發(fā)出request的爬蟲里攒菠。先看下源碼中Request類:
簡單解釋下里面的各個參數(shù):
- url: 請求的地址
- callback:指定用來解析當(dāng)前request產(chǎn)生的reponse的parse
- method: http方法迫皱,默認是'GET'
- meta:一個Python字典(dict),用于初始Request.meta值辖众。起始為空卓起,由不同的Scrapy組件進行填充注:HTTP.meta包含本次HTTP請求的Header信息,比如用戶的IP地址和用戶Agent
- body: 請求主體凹炸,不太懂戏阅,并且只能通過replace方法進行修改。待編輯
- headers:本次請求的headers啤它,一般是瀏覽器信息
- cookies: 請求的cookies奕筐。模擬登陸的重要成員。
- encoding(string):編碼方式变骡,默認為'utf-8'离赫。如果解析得到的item是亂碼的,說明這個網(wǎng)站可能是其他編碼方式塌碌,似乎京東是gbk的渊胸。
- priority(int): 請求的優(yōu)先度,目前用不到
- dont_filter(boolean):因為scrapy會默認過濾掉重復(fù)的request誊爹,如果你需要對一個網(wǎng)站發(fā)起多次request蹬刷,那么請設(shè)為False
- errback: scrapy會無視掉一些404等錯誤返回,如果你需要對這些錯誤返回進行爬绕登稹(比如說騰訊的公益404頁面)办成,你可以指定一個parse。
Cookie是http消息頭中的一種屬性搂漠,簡單說明下迂卢,大致有以下內(nèi)容:
- Cookie名字(Name)Cookie的值(Value)
- Cookie的過期時間(Expires/Max-Age)
- Cookie作用路徑(Path)
- Cookie所在域名(Domain),使用Cookie進行安全連接(Secure)桐汤。
前兩個參數(shù)是Cookie應(yīng)用的必要條件而克,另外,還包括Cookie大姓(Size员萍,不同瀏覽器對Cookie個數(shù)及大小限制是有差異的)。
用法如下:
2.模擬登陸的重點scrapy.http.FormRequest(url[, formdata, ...])
前面講的基礎(chǔ)的Request拣度,scrapy還在此基礎(chǔ)上定義了一個FormRequest用于向表格發(fā)起request碎绎,除了Request基本功能外螃壤,還定義了一個非常重要的類方法 from_response(response[,formname=None,formnumber=0,formdata=None,formxpath=None,formcss=None,clickdata=None, dont_click=False, ...])。老規(guī)矩筋帖,先解釋一下各個參數(shù):
- response: 用于在responses找到填寫的web登錄表單
- formname: 非必須奸晴,要填寫web登錄表單的名稱
- formxpath和formcss:非必須,都是用來在responses定位web登錄表單
- formnumbe:非必須日麸,假如web登錄表單有多個寄啼,用int指定其中一個。0表示第一個
- clickdata(dict): 查找控制點擊的屬性如(<input type="submit">)代箭。默認使用web表單第一個可以點擊元素墩划。
- dont_click(boolean):假如這個web表單使用js控制,輸入完自動提交梢卸,不需要點擊走诞,那么設(shè)置為false。
實戰(zhàn)使用
沒想到模擬登陸的背景知識寫了那么多蛤高,如果你沒看背景知識直接跳到這里蚣旱,沒有關(guān)系,那么下面代碼有任何不懂的都可以在上面找到解釋戴陡。
步驟一:
通過開發(fā)者工具找到要request的URL以及要填寫的表單內(nèi)容塞绿。我的網(wǎng)站比較好找就定義了一個login,填寫的數(shù)據(jù)有4個恤批。以前看到一個方法就是輸入錯誤的登錄賬號密碼進行查找异吻,而且打開Preserver log以免登陸成功后login被覆蓋掉。其中csrf_token是防止跨站工具的信息喜庞,需要在獲取網(wǎng)頁后查找
得到诀浪。
步驟二:思路整理
所謂爬蟲就是模擬人去查看網(wǎng)頁,所有寫任何代碼前延都,我們都先要想自己是如何做的雷猪,然后在編寫代碼讓爬蟲也模仿我們。
- 打開登錄頁面
- 輸入賬號密碼
- 頁面重定向到目標(biāo)頁面
步驟三:寫代碼
由于前面的背景知識鋪墊很多晰房,所以接下來就直接上代碼了:
# -- coding: utf-8 --
import scrapy
from scrapy.http import Request, FormRequest
class LoginSpider(scrapy.Spider):
name = "login"
allowed_domains = ["xuzhougeng.top"]
#向登錄頁發(fā)起請求求摇,得到下一步需要的response
def start_requests(self):
return [Request('http://xuzhougeng.top/auth/login', callback=self.post_login)]
## 首先查看一下自己的狀態(tài),需要sign in殊者。所以填寫好表單与境,用FormRequest.from_response提交,這時候網(wǎng)頁會返回一個重定向的response給我們猖吴,我們用after_login處理
def post_login(self, response):
sign_in = response.xpath('//*[@id="navbar-collapse-01"]/ul[2]/li/a/text()').extract()[0]
print(sign_in)
csrf = response.css('div > input::attr(value)').extract_first()
return FormRequest.from_response(response,formdata=
{'csrf_token':csrf,
'email':'admin@admin.com',
'password':'password',
'remember_me':'y',
'submit:':'Log In'
},callback=self.after_login)
### 檢查登錄狀態(tài)
def after_login(self, response):
sign_out = response.css('#signin_icon > a::text').extract()
print sign_out
下面是cmd的運行結(jié)果摔刁。
這篇主要是初步學(xué)習(xí)模擬登陸,所以很多的基礎(chǔ)知識海蔽,下面我想去試試登陸豆瓣和知乎簸搞,以及簡書了扁位,估計又要學(xué)很多東西〕每。可能要學(xué)習(xí)一下Linux的網(wǎng)絡(luò)編程去。