7.代理handler

簡單的自定義opener()

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'))

 

ProxyHandler處理器(代理設置)

使用代理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()

HTTPPasswordMgrWithDefaultRealm()類將建立一個密碼管理對象,用來保存 HTTP 請求相關的用戶名和密碼,主要應用兩個場景:安全

  1. 驗證代理受權的用戶名和密碼 (ProxyBasicAuthHandler())
  2. 驗證Web客戶端的的用戶名和密碼 (HTTPBasicAuthHandler())

ProxyBasicAuthHandler(代理受權驗證)

若是咱們使用以前的代碼來使用私密代理,會報 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())

 

Cookie原理

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;SECUREsession

Cookie應用

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()

 

代理ip

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)

 

 

Requests: 讓 HTTP 服務人類

雖然Python的標準庫中 urllib2 模塊已經包含了日常咱們使用的大多數功能,可是它的 API 使用起來讓人感受不太好,而 Requests 自稱 「HTTP for Humans」,說明使用更簡潔方便。

Requests 惟一的一個非轉基因的 Python HTTP 庫,人類能夠安全享用:)

Requests 繼承了urllib2的全部特性。Requests支持HTTP鏈接保持和鏈接池,支持使用cookie保持會話,支持文件上傳,支持自動肯定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。

requests 的底層實現其實就是 urllib3

#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)
相關文章
相關標籤/搜索