方法一:直接使用已知的cookie訪問python
方法二:模擬登陸後再攜帶獲得的cookie訪問web
方法三:模擬登陸後用session保持登陸狀態windows
方法四:使用無頭瀏覽器訪問瀏覽器
簡單,但須要先在瀏覽器登陸服務器
簡單地說,cookie保存在發起請求的客戶端中,服務器利用cookie來區分不一樣的客戶端。由於http是一種無狀態的鏈接,當服務器一會兒收到好幾個請求時,是沒法判斷出哪些請求是同一個客戶端發起的。而「訪問登陸後才能看到的頁面」這一行爲,偏偏須要客戶端向服務器證實:「我是剛纔登陸過的那個客戶端」。因而就須要cookie來標識客戶端的身份,以存儲它的信息(如登陸狀態)。cookie
固然,這也意味着,只要獲得了別的客戶端的cookie,咱們就能夠假冒成它來和服務器對話。這給咱們的程序帶來了可乘之機。session
咱們先用瀏覽器登陸,而後使用開發者工具查看cookie。接着在程序中攜帶該cookie向網站發送請求,就能讓你的程序假扮成剛纔登陸的那個瀏覽器,獲得只有登陸後才能看到的頁面。app
1.用瀏覽器登陸,獲取瀏覽器裏的cookie字符串工具
先使用瀏覽器登陸。再打開開發者工具,轉到network選項卡。在左邊的Name一欄找到當前的網址,選擇右邊的Headers選項卡,查看Request Headers,這裏包含了該網站頒發給瀏覽器的cookie。對,就是後面的字符串。把它複製下來,一下子代碼裏要用到。post
注意,最好是在運行你的程序前再登陸。若是太早登陸,或是把瀏覽器關了,極可能複製的那個cookie就過時無效了。
2.寫代碼
urllib庫的版本:
import sys import io from urllib import request sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改變標準輸出的默認編碼 #登陸後才能訪問的網站 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' #瀏覽器登陸後獲得的cookie,也就是剛纔複製的字符串 cookie_str = r'JSESSIONID=xxxxxxxxxxxxxxxxxxxxxx; iPlanetDirectoryPro=xxxxxxxxxxxxxxxxxx' #登陸後才能訪問的網頁 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' req = request.Request(url) #設置cookie req.add_header('cookie', raw_cookies) #設置請求頭 req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36') resp = request.urlopen(req) print(resp.read().decode('utf-8'))
requests庫的版本:
import requests import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改變標準輸出的默認編碼 #登陸後才能訪問的網頁 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' #瀏覽器登陸後獲得的cookie,也就是剛纔複製的字符串 cookie_str = r'JSESSIONID=xxxxxxxxxxxxxxxxxxxxxx; iPlanetDirectoryPro=xxxxxxxxxxxxxxxxxx' #把cookie字符串處理成字典,以便接下來使用 cookies = {} for line in cookie_str.split(';'): key, value = line.split('=', 1) cookies[key] = value
咱們先在程序中向網站發出登陸請求,也就是提交包含登陸信息的表單(用戶名、密碼等)。從響應中獲得cookie,從此在訪問其餘頁面時也帶上這個cookie,就能獲得只有登陸後才能看到的頁面。
1.找出表單提交到的頁面
仍是要利用瀏覽器的開發者工具。轉到network選項卡,並勾選Preserve Log(重要!)。在瀏覽器裏登陸網站。而後在左邊的Name一欄找到表單提交到的頁面。怎麼找呢?看看右側,轉到Headers選項卡。首先,在General那段,Request Method應當是POST。其次最下方應該要有一段叫作Form Data的,裏面能夠看到你剛纔輸入的用戶名和密碼等。也能夠看看左邊的Name,若是含有login這個詞,有可能就是提交表單的頁面(不必定!)。
這裏要強調一點,「表單提交到的頁面」一般並非你填寫用戶名和密碼的頁面!因此要利用工具來找到它。
2.找出要提交的數據
雖然你在瀏覽器裏登錄時只填了用戶名和密碼,但表單裏包含的數據可不僅這些。從Form Data裏就能夠看到須要提交的全部數據。
3.寫代碼
urllib庫的版本:
import sys import io import urllib.request import http.cookiejar sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改變標準輸出的默認編碼 #登陸時須要POST的數據 data = {'Login.Token1':'學號', 'Login.Token2':'密碼', 'goto:http':'//ssfw.xmu.edu.cn/cmstar/loginSuccess.portal', 'gotoOnFail:http':'//ssfw.xmu.edu.cn/cmstar/loginFailure.portal'} post_data = urllib.parse.urlencode(data).encode('utf-8') #設置請求頭 headers = {'User-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'} #登陸時表單提交到的地址(用開發者工具能夠看到) login_url = ' http://ssfw.xmu.edu.cn/cmstar/userPasswordValidate.portal #構造登陸請求 req = urllib.request.Request(login_url, headers = headers, data = post_data) #構造cookie cookie = http.cookiejar.CookieJar() #由cookie構造opener opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie)) #發送登陸請求,此後這個opener就攜帶了cookie,以證實本身登陸過 resp = opener.open(req) #登陸後才能訪問的網頁 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' #構造訪問請求 req = urllib.request.Request(url, headers = headers) resp = opener.open(req) print(resp.read().decode('utf-8'))
requests庫的版本:
import requests import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改變標準輸出的默認編碼 #登陸後才能訪問的網頁 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' #瀏覽器登陸後獲得的cookie,也就是剛纔複製的字符串 cookie_str = r'JSESSIONID=xxxxxxxxxxxxxxxxxxxxxx; iPlanetDirectoryPro=xxxxxxxxxxxxxxxxxx' #把cookie字符串處理成字典,以便接下來使用 cookies = {} for line in cookie_str.split(';'): key, value = line.split('=', 1) cookies[key] = value #設置請求頭 headers = {'User-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'} #在發送get請求時帶上請求頭和cookies resp = requests.get(url, headers = headers, cookies = cookies) print(resp.content.decode('utf-8'))
明顯感受requests庫用着更方便啊~~~
session是會話的意思。和cookie的類似之處在於,它也可讓服務器「認得」客戶端。簡單理解就是,把每個客戶端和服務器的互動看成一個「會話」。既然在同一個「會話」裏,服務器天然就能知道這個客戶端是否登陸過。
1.找出表單提交到的頁面
2.找出要提交的數據
這兩步和方法二的前兩步是同樣的
3.寫代碼
requests庫的版本
import requests import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') #改變標準輸出的默認編碼 #登陸時須要POST的數據 data = {'Login.Token1':'學號', 'Login.Token2':'密碼', 'goto:http':'//ssfw.xmu.edu.cn/cmstar/loginSuccess.portal', 'gotoOnFail:http':'//ssfw.xmu.edu.cn/cmstar/loginFailure.portal'} #設置請求頭 headers = {'User-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'} #登陸時表單提交到的地址(用開發者工具能夠看到) login_url = 'http://ssfw.xmu.edu.cn/cmstar/userPasswordValidate.portal' #構造Session session = requests.Session() #在session中發送登陸請求,此後這個session裏就存儲了cookie #能夠用print(session.cookies.get_dict())查看 resp = session.post(login_url, data) #登陸後才能訪問的網頁 url = 'http://ssfw.xmu.edu.cn/cmstar/index.portal' #發送訪問請求 resp = session.get(url) print(resp.content.decode('utf-8'))
功能強大,幾乎能夠對付任何網頁,但會致使代碼效率低
若是能在程序裏調用一個瀏覽器來訪問網站,那麼像登陸這樣的操做就垂手可得了。在Python中可使用Selenium庫來調用瀏覽器,寫在代碼裏的操做(打開網頁、點擊……)會變成瀏覽器忠實地執行。這個被控制的瀏覽器能夠是Firefox,Chrome等,但最經常使用的仍是PhantomJS這個無頭(沒有界面)瀏覽器。也就是說,只要把填寫用戶名密碼、點擊「登陸」按鈕、打開另外一個網頁等操做寫到程序中,PhamtomJS就能確確實實地讓你登陸上去,並把響應返回給你。
1.安裝selenium庫、PhantomJS瀏覽器
2.在源代碼中找到登陸時的輸入文本框、按鈕這些元素
由於要在無頭瀏覽器中進行操做,因此就要先找到輸入框,才能輸入信息。找到登陸按鈕,才能點擊它。
在瀏覽器中打開填寫用戶名密碼的頁面,將光標移動到輸入用戶名的文本框,右鍵,選擇「審查元素」,就能夠在右邊的網頁源代碼中看到文本框是哪一個元素。同理,能夠在源代碼中找到輸入密碼的文本框、登陸按鈕。
3.考慮如何在程序中找到上述元素
Selenium庫提供了find_element(s)_by_xxx的方法來找到網頁中的輸入框、按鈕等元素。其中xxx能夠是id、name、tag_name(標籤名)、class_name(class),也能夠是xpath(xpath表達式)等等。固然仍是要具體分析網頁源代碼。
4.寫代碼
import requests import sys import io from selenium import webdriver sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8') #改變標準輸出的默認編碼 #創建Phantomjs瀏覽器對象,括號裏是phantomjs.exe在你的電腦上的路徑 browser = webdriver.PhantomJS('d:/tool/07-net/phantomjs-windows/phantomjs-2.1.1-windows/bin/phantomjs.exe') #登陸頁面 url = r'http://ssfw.xmu.edu.cn/cmstar/index.portal' # 訪問登陸頁面 browser.get(url) # 等待必定時間,讓js腳本加載完畢 browser.implicitly_wait(3) #輸入用戶名 username = browser.find_element_by_name('user') username.send_keys('學號') #輸入密碼 password = browser.find_element_by_name('pwd') password.send_keys('密碼') #選擇「學生」單選按鈕 student = browser.find_element_by_xpath('//input[@value="student"]') student.click() #點擊「登陸」按鈕 login_button = browser.find_element_by_name('btn') login_button.submit() #網頁截圖 browser.save_screenshot('picture1.png') #打印網頁源代碼 print(browser.page_source.encode('utf-8').decode()) browser.quit()