scrapy登錄界面的難點在於登錄時候的驗證碼,我們通過使用scrapy.FormRequest向目標網站提交數據(表單提交),同時將驗證碼顯示在本地,手動輸入,進而登錄。
驗證碼是類似於這種的,才可以通過此方式登錄,如網站是通過滑塊驗證登錄的話,此方法就不再適用
因為要找到這種驗證碼登錄的網站一時之間沒找到,本想用學校教務系統的登錄網站進行測試,但是測試后發現驗證碼是動態加載的,故放棄,找了一會,就用提交教育漏洞的edusrc網站作為練習登錄爬蟲的站點
登錄url是:https://src.sjtu.edu.cn/login/
我們先登錄一下,查看需要post哪些數據
可以看到,這里POST表單里面我們提交了username,password,captcha_1,captcha_0以及csrfmiddlewaretoken
username和password是我們的登錄郵箱和密碼,captcha_1是輸入的驗證碼,captcha_0我猜測是每次登錄的時候都會根據網站算法而更新的一個值,csrfmiddlewaretoken也是一個根據算法更新的值,從名字可以看出是防止csrf攻擊而生成的令牌值,告訴網站來到這個頁面的用戶的權限。
而提交的數據中,captcha_0和csrfmiddlewaretoken都是直接從頁面中獲取的,我們先用xpath從頁面中獲取這兩個值
使用xpath語法對這兩個值進行提取:
formdata={ 'username': '', 'password': '' } captcha_0=response.xpath('//input[@name="captcha_0"]/@value').get() formdata['captcha_0']=captcha_0 csrfmiddlewaretoken=response.xpath('//input[@name="csrfmiddlewaretoken"]/@value').get() formdata['csrfmiddlewaretoken']=csrfmiddlewaretoken
其中username和password需要自己輸入,這個時候就只剩下captcha_1即驗證碼沒有獲取了
查看源代碼 之后可知:
驗證碼存在一個url,這個url里面的驗證碼每次刷新之后都會改變,但是url也在不斷變化,使用xpath提取這個url,然后我們進一步進行處理
captcha_url = response.xpath('//img/@src').get() captcha_url = 'https://src.sjtu.edu.cn/' + captcha_url print captcha_url captcha = self.check_captcha(captcha_url)
check_captcha函數就是我們用來處理captcha_url即驗證碼url的
def check_captcha(self,image_url): urllib.urlretrieve(image_url,'captcha.jpg') image=Image.open('captcha.jpg') image.show() captcha=raw_input('please input captcha:') return captcha
我們使用了urlretrieve函數來下載遠程url的數據,這里就是將驗證碼圖片下載在了本地我們查看
python2和python3都可以使用urlretrieve函數,使用方法略有不同,我使用的是python2,參考這篇博客修改的:
https://blog.csdn.net/drdairen/article/details/61934598?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
獲取到的驗證碼圖片會保存在當前文件夾下,接着我們使用Image打開該圖片同時show,看到驗證碼圖片的我們關閉圖片后輸入驗證碼字符串並返回該字符串
formdata['captcha_1'] = captcha yield scrapy.FormRequest(url=self.login_url,formdata=formdata,callback=self.parse_after_login)
將captcha_1加入到formdata之后,我們向login_url提交formdata,同時為了檢測我們是否成功登錄,回調函數是parse_after_login
def parse_after_login(self,response): if response.url=="https://src.sjtu.edu.cn/":
yield scrapy.FormRequest(self.bug_url,callback=self.parse_bug)
print "login successful!"
else:
print "login failed!"
自己嘗試登錄之后,可以知道登錄了之后網站會自動將我們302重定向到https://src.sjtu.edu.cn/,所以我們只需要檢測response.url是否跟https://src.sjtu.edu.cn/相同即可
我們登錄了之后去bugurl即https://src.sjtu.edu.cn/list/?page=1頁面第一頁提取bug_list信息打印出來,證明可以做到登錄之后的操作即可,因為為了避免信息泄露,漏洞列表里登錄后和沒登錄看到的漏洞信息是不一樣的,側面可以反映我們是否登錄成功
def parse_bug(self,response): print response.url if response.url==self.bug_url: print "join bug_list successful!" bug_list=response.xpath('//td/a[contains(@href,"/post/")]/text()').getall() for bug in bug_list: print bug else: print "join bug_list failed!"
現在主要的部分就寫好了,填入username和password運行試試
運行之后跳出驗證碼圖片
輸入驗證碼之后輸出第一頁的漏洞列表:
可以看到跟登錄之后的漏洞信息顯示相同
如果沒登錄的話,顯示的信息是這樣的:
其實我感覺沒登錄的時候看到的信息要多一些:)
可以看出我們登錄成功了。
這個代碼主要是識別驗證碼和POST提交formdata數據比較重要
代碼放在github上面了:
https://github.com/Cl0udG0d/scrapy_demo
參考鏈接:
https://blog.csdn.net/drdairen/article/details/61934598?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task