import urllib.request #構建一個HTTPHandler處理器對象,支持處理HTTP請求 http_handler=urllib.request.HTTPHandler() #構建一個HTTPHandler處理器對象,支持處理HTTPS請求 # http_handler=urllib.request.HTTPHandler() #調用urllib.request.build_opener()方法,建立支持處理HTTP請求的opener對象 opener=urllib.request.build_opener(http_handler) #構建Request請求 request=urllib.request.Request("http://www.baidu.com/") #調用自定義opener對象的open()方法,發送request請求 response=opener.open(request) print(response.read().decode('utf-8'))
使用代理IP,這是爬蟲/反爬蟲的第二大招,一般也是最好用的。python
不少網站會檢測某一段時間某個IP的訪問次數(經過流量統計,系統日誌等),若是訪問次數多的不像正常人,它會禁止這個IP的訪問。web
因此咱們能夠設置一些代理服務器,每隔一段時間換一個代理,就算IP被禁止,依然能夠換個IP繼續爬取。json
import urllib.request # 構建了兩個代理Handler,一個有代理IP,一個沒有代理IP httpproxy_handler = urllib.request.ProxyHandler({"http": "120.26.110.59:8080"}) nullproxy_handler = urllib.request.ProxyHandler({}) proxySwitch = True #定義一個代理開關 # 經過 urllib2.build_opener()方法使用這些代理Handler對象,建立自定義opener對象 # 根據代理開關是否打開,使用不一樣的代理模式 if proxySwitch: opener = urllib.request.build_opener(httpproxy_handler) else: opener = urllib.request.build_opener(nullproxy_handler) request = urllib.request.Request("http://www.baidu.com/") # 1. 若是這麼寫,只有使用opener.open()方法發送請求才使用自定義的代理,而urlopen()則不使用自定義代理。 response = opener.open(request) # 2. 若是這麼寫,就是將opener應用到全局,以後全部的,不論是opener.open()仍是urlopen() 發送請求,都將使用自定義代理。 # urllib2.install_opener(opener) # response = urlopen(request) print(response.read().decode('utf-8'))
若是代理IP足夠多,就能夠像隨機獲取User-Agent同樣,隨機選擇一個代理去訪問網站。瀏覽器
import urllib.request import random #代理列表 proxy_list = [ {"http" : "124.88.67.81:80"}, {"http": "120.26.110.59:8080"}, {"http" : "124.88.67.81:80"}, {"http" : "124.88.67.81:80"}, {"http" : "124.88.67.81:80"} ] # 隨機選擇一個代理 proxy = random.choice(proxy_list) # 使用選擇的代理構建代理處理器對象 httpproxy_handler = urllib.request.ProxyHandler(proxy) opener = urllib.request.build_opener(httpproxy_handler) request = urllib.request.Request("http://www.baidu.com/") response = opener.open(request) print(response.read().decode('utf-8'))
HTTPPasswordMgrWithDefaultRealm()
類將建立一個密碼管理對象,用來保存 HTTP 請求相關的用戶名和密碼,主要應用兩個場景:安全
ProxyBasicAuthHandler()
)HTTPBasicAuthHandler()
)若是咱們使用以前的代碼來使用私密代理,會報 HTTP 407 錯誤,表示代理沒有經過身份驗證服務器
import urllib.request #私密代理受權的帳戶 user="mr_mao_hacker" #私密代理受權的密碼 passwd="sffqry9r" #私密代理IP proxyserver="61.158.163.130:16816" #1.構建一個密碼管理對象,用來保存須要處理的用戶名和密碼 passwdmgr=urllib.request.HTTPPasswordMgrWithDefaultRealm() #2.添加帳戶信息,第一個參數realm是與遠程服務器相關的域信息 passwdmgr.add_password(None,proxyserver,user,passwd) #3.構建一個代理基礎用戶名/密碼驗證的ProxyBasicAuthHandler處理器對象,參數是建立的密碼管理對象 # 注意,這裏再也不使用普通ProxyHandler類了 proxyauth_handler=urllib.request.ProxyBasicAuthHandler(passwdmgr) #4.經過build_opener()方法使用這些代理Handler對象,建立自定義opener對象,參數包括構建的 proxy_handler 和 proxyauth_handler opener=urllib.request.build_opener(proxyauth_handler) #5.構造Request請求 request=urllib.request.Request("http://www.baidu.com/") #6.使用自定義opener發送請求 response=opener.open(request) #7.打印響應內容 print(response.read())
HTTP是無狀態的面向鏈接的協議, 爲了保持鏈接狀態, 引入了Cookie機制 Cookie是http消息頭中的一種屬性,包括:cookie
Cookie名字(Name) Cookie的值(Value) Cookie的過時時間(Expires/Max-Age) Cookie做用路徑(Path) Cookie所在域名(Domain), 使用Cookie進行安全鏈接(Secure)。 前兩個參數是Cookie應用的必要條件,另外,還包括Cookie大小(Size,不一樣瀏覽器對Cookie個數及大小限制是有差別的)。
Cookie由變量名和值組成,根據 Netscape公司的規定,Cookie格式以下:網絡
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
session
Cookies在爬蟲方面最典型的應用是斷定註冊用戶是否已經登陸網站,用戶可能會獲得提示,是否在下一次進入此網站時保留用戶信息以便簡化登陸手續。併發
import urllib import urllib2 import cookielib # 經過CookieJar()類構建一個cookieJar()對象,用來保存cookie的值 cookie = cookielib.CookieJar() # 經過HTTPCookieProcessor()處理器類構建一個處理器對象,用來處理cookie # 參數就是構建的CookieJar()對象 cookie_handler = urllib2.HTTPCookieProcessor(cookie) # 構建一個自定義的opener opener = urllib2.build_opener(cookie_handler) # 經過自定義opener的addheaders的參數,能夠添加HTTP報頭參數 opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36")] # renren網的登陸接口 url = "http://www.renren.com/PLogin.do" # 須要登陸的帳戶密碼 data = {"email":"mr_mao_hacker@163.com", "password":"alarmchime"} # 經過urlencode()編碼轉換 data = urllib.urlencode(data) # 第一次是post請求,發送登陸須要的參數,獲取cookie request = urllib2.Request(url, data = data) # 發送第一次的post請求,生成登陸後的cookie(若是登陸成功的話) response = opener.open(request) #print response.read() # 第二次能夠是get請求,這個請求將保存生成cookie一併發到web服務器,服務器會驗證cookie經過 response_deng = opener.open("http://www.renren.com/410043129/profile") # 獲取登陸後才能訪問的頁面信息 print response_deng.read()
import requests #根據協議類型,選擇不一樣的代理 proxies={ "http": "120.26.110.59:8080", "https": "http://12.34.56.79:9527", } response=requests.get("http://www.baidu.com",proxies=proxies) print(response.text)
雖然Python的標準庫中 urllib2 模塊已經包含了日常咱們使用的大多數功能,可是它的 API 使用起來讓人感受不太好,而 Requests 自稱 「HTTP for Humans」,說明使用更簡潔方便。
Requests 惟一的一個非轉基因的 Python HTTP 庫,人類能夠安全享用:)
Requests 繼承了urllib2的全部特性。Requests支持HTTP鏈接保持和鏈接池,支持使用cookie保持會話,支持文件上傳,支持自動肯定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。
#requests 的底層實現其實就是 urllib3 import requests response=requests.get("http://www.baidu.com/") print(response.text)
Requests的文檔很是完備,中文文檔也至關不錯。Requests能徹底知足當前網絡的需求,支持Python 2.6—3.5,並且能在PyPy下完美運行。
import requests response=requests.get("https://www.baidu.com/",verify=True) print(response.text)
requests模塊post請求
import requests import requests formdata = { "type":"AUTO", "i":"i love python", "doctype":"json", "xmlVersion":"1.8", "keyfrom":"fanyi.web", "ue":"UTF-8", "action":"FY_BY_ENTER", "typoResult":"true" } url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null" headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"} reponse=requests.post(url,data=formdata,headers=headers) print(reponse.text) #若是是json文件能夠直接顯示 print(reponse.json())
requests請求headers
import requests kw={'wd':'長城'} headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"} # params 接收一個字典或者字符串的查詢參數,字典類型自動轉換爲url編碼,不須要urlencode() response=requests.get("http://www.baidu.com/s?",params=kw,headers=headers) # 查看響應內容,response.text 返回的是Unicode格式的數據 print(response.text) # 查看響應內容,response.content返回的字節流數據 print(response.content) #查看完整url地址 print(response.url) #查看響應頭部字符編碼 print(response.encoding) #查看響應碼 print(response.status_code)
requests模塊私密代理
import requests # 若是代理須要使用HTTP Basic Auth,可使用下面這種格式: proxy={"http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816"} response=requests.get("http://www.baidu.com", proxies = proxy) print(response.text)
import requests auth=('test','123456') response=requests.get('http://192.168.199.107',auth=auth) print(response.text)
爬取https網站
import requests """ 若是SSL證書驗證不經過,或者不信任服務器的安全證書,則會報出SSLError, 聽說 12306 證書是本身作的 若是咱們想跳過 12306 的證書驗證,把 verify 設置爲 False 就能夠正常請求了 """ response = requests.get("https://www.12306.cn/mormhweb/",verify=False) print(response.text)