相信最開始接觸Python爬蟲學習的同窗最初大多使用的是urllib,urllib2。在那以後接觸到了第三方庫requests,requests徹底能知足各類http功能,真的是好用爆了 :Djavascript
他們是這樣說的:html
「Requests 惟一的一個非轉基因的 Python HTTP 庫,人類能夠安全享用。Requests 容許你發送純自然,植物飼養的 HTTP/1.1 請求,無需手工勞動。你不須要手動爲 URL 添加查詢字串,也不須要對 POST 數據進行表單編碼。Keep-alive 和 HTTP 鏈接池的功能是 100% 自動化的,一切動力都來自於根植在 Requests 內部的 urllib3。」java
-----來自官方文檔(http://cn.python-requests.org/zh_CN/latest/)python
敲入命令「Pip Install Requests」安裝便可享用(前提是已經安裝了pip)正則表達式
還等什麼呢?趕忙import requests加入豪華午飯吧瀏覽器
先看看幾個經常使用的方法和屬性:安全
1.requests.Session()這樣就能夠在會話中保留狀態,保持cookie等服務器
2.requests.get()獲取某個網頁,get時你可使用params參數發送一些數據過去cookie
d = {key1 : value1, key2 : value2 }
requests.get(‘URL’, params=d)
get時也可使用headers參數定製請求頭。網絡
h = {key1 : value1, key2 : value2 }
requests.get(‘URL’, headers=d)
3.requests.post()發送post請求,相似的,post時也能夠發送數據(使用data參數)和定製請求頭(使用headers參數)。
一些經常使用的屬性:
eg=requests.get() eg.text #能夠獲取響應的內容如抓回來的網頁 eg. encoding='utf-8' #有時回來的是亂碼,改變編碼以使其正常顯示根據實際狀況改變編碼utf-八、gb2312等 eg. content #能夠獲取二進制內容,如抓取登錄時的驗證碼等非字符資源 eg.cookies #能夠查看當前保存的cookie狀況 eg. status_code #能夠查看HTTP狀態碼(如200 OK、404 Not Found等) eg.url #能夠查看當前請求的網址
其餘詳細內容參見官方文檔(http://cn.python-requests.org/zh_CN/latest/)
好了,其實只要懂那麼一點點就能夠進行爬蟲之旅了。
一個有趣的現象:童鞋們在學習爬蟲時都會去爬一個叫作「教務處」的網站,哈哈。那這裏的小爬蟲也是以登錄本校(成都信息工程大學)的教務處做爲實例
首先使用瀏覽器打開教務處,按F12打開「開發人員工具」,進行一次正常的登錄,對登錄的數據進行分析。
1.教務處的登錄頁面爲http://210.41.224.117/Login/xLogin/Login.asp
2.在開發者工具中點擊網絡,經查看登錄的發送post數據的地址也是http://210.41.224.117/Login/xLogin/Login.asp
3.同時看到post的數據包括以下
參數列表
|
||
表單名 |
例 |
說明 |
WinW |
1366 |
屏幕分辨率-寬 |
WinH |
728 |
屏幕分辨率-高 |
txtId |
2013215042 |
學號 |
txtMM |
123456 |
密碼 |
verifycode |
123a |
驗證碼 |
codeKey |
597564 |
動態登錄碼,html文件中可見 |
Login |
Check |
登錄類型(固定) |
IbtnEnter.x |
10 |
登錄按鈕點擊位置 |
IbtnEnter.y |
10 |
登錄按鈕點擊位置 |
「開發者工具」中的登錄post表單數據:
4.其中codeKey在登錄頁載入時能夠在頁面中得到(使用正則表達式獲取)。
那麼思路來了:
1.get()載入登錄頁
2.在載入頁中獲取codeKey和驗證碼
3.使用post()將登錄學號、密碼、驗證碼等參數發送過去
4.登錄成功。
然而事實並非如此順利,經以上思路登錄以後會返回「LoginOK!」登錄成功的消息,原本是要經兩個302跳轉到教務處的學生主頁的,但並不能順利跳轉並且哪怕手動加載學生頁不行。
經再次分析發現從教務處首頁點擊登錄連接並非直接連接到登錄頁http://210.41.224.117/Login/xLogin/Login.asp,而是先訪問http://jxgl.cuit.edu.cn/JXGL/xs/MainMenu.asp試圖打開學生頁失敗,再經跳轉到一個http://210.41.224.117/Login/qqLogin.asp?Oid=jxgl.cuit.edu.cn&OSid=*********再經這裏跳轉纔到登錄頁,其中的OSid爲服務器下發分配的。實踐代表我須要模仿這個過程才能順利登錄成功。
好了,那麼思路再次來了:
要點:
思考完畢,接下來就是實現了,最後的登錄代碼以下:
#coding=utf-8 import requests import re import time import random from PIL import Image import cStringIO def login(username,password): headers = { #請求頭請求刷新驗證碼和發送post時須要使用 'Host': '210.41.224.117', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0', 'Accept': '*/*', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'http://210.41.224.117/Login/xLogin/Login.asp', 'Connection': 'keep-alive' } session = requests.Session() step1 = session.get('http://jxgl.cuit.edu.cn/JXGL/xs/MainMenu.asp') #連get兩次學生主頁以跳轉至登錄頁 step1 = session.get("http://jxgl.cuit.edu.cn/Jxgl/Xs/MainMenu.asp") get_osid_url = re.compile(r'content="0;URL=(.*?)">') #獲取含OSid的跳轉網址 osid_url = get_osid_url.findall(step1.text) step2 = session.get(osid_url[0]) #跳轉,上文要點1 get_codeKey = re.compile(r'var codeKey = \'(.*?)\';') #在登錄頁html中獲取codeKey(參數k) codeKey = get_codeKey.findall(step2.text) timeKey = str(time.time())[:10] + str(random.randint(100, 999)) #生成參數t的值(時間戳+三位隨機數) payload = {'k': codeKey[0], 't': timeKey} yzm_url='http://210.41.224.117/Login/xLogin/yzmDvCode.asp' yzmdata = session.get(yzm_url, params=payload, headers=headers) #刷新驗證碼,上文要點2 tempIm = cStringIO.StringIO(yzmdata.content) im = Image.open(tempIm) im.show() yzm = raw_input('please enter yzm: ') #人工識別驗證碼後輸入 post_data = { 'WinW': '1366', 'WinH': '728', 'txtId': username, 'txtMM': password, 'verifycode': yzm, 'codeKey': codeKey[0], 'Login': 'Check', 'IbtnEnter.x': 10, 'IbtnEnter.y': 10 } post_url='http://210.41.224.117/Login/xLogin/Login.asp' step3 = session.post(post_url, data=post_data, headers=headers) #post登錄數據 return session cuitJWC=login('username','password') con=cuitJWC.get('http://jxgl.cuit.edu.cn/JXGL/xs/MainMenu.asp') con.encoding='gb2312' print con.text