Python 爬蟲入門(requests)

相信最開始接觸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爲服務器下發分配的。實踐代表我須要模仿這個過程才能順利登錄成功。

好了,那麼思路再次來了:

  1. get(‘http://jxgl.cuit.edu.cn/JXGL/xs/MainMenu.asp’)這裏要get兩次才能跳轉到登錄頁
  2. 在載入的登錄頁中獲取codeKey和驗證碼
  3. 使用post()將登錄學號、密碼、驗證碼等參數發送過去
  4. 登錄成功,加載學生主頁

要點:

  1. 兩次get()以後獲得一個跳轉頁面由瀏覽器執行javascript自動跳轉,但在爬蟲裏須要在這個頁面中找出跳轉的地址手動跳轉過去。使用正則表達式在javascript代碼中獲取須要跳轉的網址,再get該網址便可。
  2. 獲取驗證碼,驗證碼是隨機生成的,獲得驗證碼刷新地址http://210.41.224.117/Login/xLogin/yzmDvCode.asp?k=597564&t=1471855009329其中參數k爲codeKey,t爲時間戳加上三位隨機數。那就使用前邊提到eg. content能夠獲取二進制內容將圖片保存下來再打開人工識別後輸入驗證碼。

 

思考完畢,接下來就是實現了,最後的登錄代碼以下:

 

#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

 

 

轉載請註明出處:http://www.cnblogs.com/lucky-pin/p/5806394.html 

相關文章
相關標籤/搜索