Python爬蟲基礎(三)urllib2庫的高級使用

Handler處理器 和 自定義Opener

    opener是 urllib2.OpenerDirector 的實例,其中urlopen是模塊默認構建的opener。 可是基本的urlopen()方法不支持代理、cookie等其餘的HTTP/HTTPS高級功能。若是要支持這些功能,能夠使用相關的 Handler處理器來建立特定功能的處理器對象,而後經過 urllib2.build_opener()方法使用這些處理器對象,建立自定義opener對象,最後 使用自定義的opener對象,調用open()方法發送請求。     html

自定義一個簡單的opener()web

 -*- coding: utf-8 -*-
import urllib2

# 構建一個HTTPHandler 處理器對象,支持處理HTTP請求
http_handler = urllib2.HTTPHandler()

# 構建一個HTTPHandler 處理器對象,支持處理HTTPS請求
# http_handler = urllib2.HTTPSHandler()

# 調用urllib2.build_opener()方法,建立支持處理HTTP請求的opener對象
opener = urllib2.build_opener(http_handler)

# 構建 Request請求
request = urllib2.Request("http://www.baidu.com/")

# 調用自定義opener對象的open()方法,發送request請求
response = opener.open(request)

# 獲取服務器響應內容
print response.read()


# 開啓Debug Log程序在執行的時候,會把收包和發包的報頭在屏幕上自動打印出來
# 構建一個HTTPHandler 處理器對象,支持處理HTTP請求,同時開啓Debug Log,debuglevel 值默認 0
# http_handler = urllib2.HTTPHandler(debuglevel=1)

# 構建一個HTTPHSandler 處理器對象,支持處理HTTPS請求,同時開啓Debug Log,debuglevel 值默認 0
# https_handler = urllib2.HTTPSHandler(debuglevel=1)

使用ProxyHandler處理器設置代理

        使用代理IP,這也是爬蟲/反爬蟲的有效方式,不少網站會檢測某一段時間某個IP的訪問次數,若是訪問頻率太高,就有可能被禁止訪問。這時能夠設置一些代理服務器,每隔一段時間換一個代理,就算IP被禁止,依然能夠換個IP繼續爬取。瀏覽器

在urllib2中能夠經過ProxyHandler來設置使用代理服務器:服務器

# -*- coding: utf-8 -*-
import urllib2

# 構建了兩個代理Handler,一個有代理IP,一個沒有代理IP
httpproxy_handler = urllib2.ProxyHandler({"http" : "124.88.67.81:80"})
nullproxy_handler = urllib2.ProxyHandler({})

proxySwitch = True #定義一個代理開關

# 經過 urllib2.build_opener()方法使用這些代理Handler對象,建立自定義opener對象
# 根據代理開關是否打開,使用不一樣的代理模式
if proxySwitch:  
    opener = urllib2.build_opener(httpproxy_handler)
else:
    opener = urllib2.build_opener(nullproxy_handler)

request = urllib2.Request("http://www.baidu.com/")

#  只有使用opener.open()方法發送請求才使用自定義的代理,而urlopen()則不使用自定義代理。
response = opener.open(request)

# 將opener應用到全局,以後不論是opener.open()仍是urlopen() 發送請求,都將使用自定義代理。
# urllib2.install_opener(opener)
# response = urlopen(request)

print response.read()

免費的開放代理很容易獲取,有很多這樣的網站,能夠多收集一些代理IP,這樣能夠像隨機獲取User-Agent同樣,隨機選擇一個代理去訪問網站:cookie

# -*- coding: utf-8 -*-
import urllib2
import random

proxy_list = [
    {"http" : "124.88.67.81:80"},
    {"http" : "124.88.67.81:80"},
    {"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 = urllib2.ProxyHandler(proxy)

opener = urllib2.build_opener(httpproxy_handler)

request = urllib2.Request("http://www.baidu.com/")
response = opener.open(request)
print response.read()

免費代理不穩定,若是要求高就購買私密代理,購買私密代理後會獲得一個帳戶和密碼做爲認證,具體使用以下:網絡

# -*- coding:utf-8 -*-
import urllib2

# 私密代理受權的帳戶
user = "xxxx"
# 私密代理受權的密碼
passwd = "****"

# 受權的代理帳戶密碼拼接
authproxy_handler = urllib2.ProxyHandler({"http" : user+":"+passwd+"@114.215.104.49:16816"})

# 構建一個自定義的opener
opener = urllib2.build_opener(authproxy_handler)

# 構建請求
request = urllib2.Request("http://www.baidu.com/")

# 獲取響應
response = opener.open(request)

# 打印內容
print response.read()

爲避免帳戶密碼泄露能夠將其寫入環境變量中。app

HTTPBasicAuthHandler處理器(Web客戶端受權驗證)

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import urllib
import urllib2

# 用戶名
user = "xxxx"
# 密碼
passwd = "****"
# Web服務器 IP
webserver = "http://192.168.12.33"

# 構建一個密碼管理對象,用來保存須要處理的用戶名和密碼
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

# 添加帳戶信息,第一個參數realm是與遠程服務器相關的域信息,通常沒人管它都是寫None,後面三個參數分別是 Web服務器、用戶名、密碼
passwdmgr.add_password(None, webserver, user, passwd)

# 構建一個HTTP基礎用戶名/密碼驗證的HTTPBasicAuthHandler處理器對象,參數是建立的密碼管理對象
httpauth_handler = urllib2.HTTPBasicAuthHandler(passwdmgr)

# 經過 build_opener()方法使用這些代理Handler對象,建立自定義opener對象,參數包括構建的 proxy_handler
opener = urllib2.build_opener(httpauth_handler)

# 能夠選擇經過install_opener()方法定義opener爲全局opener
urllib2.install_opener(opener)

# 構建 Request對象
request = urllib2.Request("http://192.168.199.107")

# 定義opener爲全局opener後,可直接使用urlopen()發送請求
response = urllib2.urlopen(request)

# 打印響應內容
print response.read()

這種網站比較少,遇到時咱們可使用requests庫來爬取會方便不少,這種方法過於繁瑣。dom

Cookie 是指某些網站服務器爲了辨別用戶身份和進行Session跟蹤,而儲存在用戶瀏覽器上的文本文件,Cookie能夠保持登陸信息到用戶下次與服務器的會話。網站

Cookies在爬蟲方面最典型的應用是斷定註冊用戶是否已經登陸網站,用戶可能會獲得提示,是否在下一次進入此網站時保留用戶信息以便簡化登陸手續。ui

經過抓包獲取一個有登陸信息的Cookie來模擬登錄:

# -*- coding: utf-8 -*-
import urllib2

# 構建一個已經登陸過的用戶的headers信息
headers = {
    "Host":"www.renren.com",
    "Connection":"keep-alive",
    "Upgrade-Insecure-Requests":"1",
    "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",
    "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language":"zh-CN,zh;q=0.8,en;q=0.6",
    # 這個Cookie是保存了密碼無需重複登陸的用戶的Cookie,經過抓包獲取(這裏只是一部分)
    "Cookie": "anonymid=efrna3fysufnwv; depovince=GW; _r01_=1; "
}

# 經過headers裏的報頭信息(主要是Cookie信息),構建Request對象
urllib2.Request("http://www.renren.com/", headers = headers)

# 直接訪問renren主頁,服務器會根據headers報頭信息(主要是Cookie信息),判斷這是一個已經登陸的用戶,並返回相應的頁面
response = urllib2.urlopen(request)

# 打印響應內容
print response.read()

cookielib庫 和 HTTPCookieProcessor處理器

一、獲取Cookie,並保存到CookieJar()對象中
# -*- coding: utf-8 -*-
import urllib2
import cookielib

# 構建一個CookieJar對象實例來保存cookie
cookiejar = cookielib.CookieJar()

# 使用HTTPCookieProcessor()來建立cookie處理器對象,參數爲CookieJar()對象
handler=urllib2.HTTPCookieProcessor(cookiejar)

# 經過 build_opener() 來構建opener
opener = urllib2.build_opener(handler)

# 4. 以get方法訪問頁面,訪問以後會自動保存cookie到cookiejar中
opener.open("http://www.baidu.com")
2. 訪問網站得到cookie,並把得到的cookie保存在cookie文件中
# -*- coding: utf-8 -*-
import cookielib
import urllib2

# 保存cookie的本地磁盤文件名
filename = 'cookie.txt'

# 聲明一個MozillaCookieJar(有save實現)對象實例來保存cookie,以後寫入文件
cookiejar = cookielib.MozillaCookieJar(filename)

# 使用HTTPCookieProcessor()來建立cookie處理器對象,參數爲CookieJar()對象
handler = urllib2.HTTPCookieProcessor(cookiejar)

# 經過 build_opener() 來構建opener
opener = urllib2.build_opener(handler)

# 建立一個請求,原理同urllib2的urlopen
response = opener.open("http://www.baidu.com")

# 保存cookie到本地文件
cookiejar.save()
3. 從文件中獲取cookies,作爲請求的一部分去訪問
# -*- coding: utf-8 -*-
import cookielib
import urllib2

# 建立MozillaCookieJar(有load實現)實例對象
cookiejar = cookielib.MozillaCookieJar()

# 從文件中讀取cookie內容到變量
cookie.load('cookie.txt')

# 使用HTTPCookieProcessor()來建立cookie處理器對象,參數爲CookieJar()對象
handler = urllib2.HTTPCookieProcessor(cookiejar)

# 經過 build_opener() 來構建opener
opener = urllib2.build_opener(handler)

response = opener.open("http://www.baidu.com")

 

urllib2 的異常錯誤處理

在咱們用urlopen或opener.open方法發出一個請求時,若是urlopen或opener.open不能處理這個response,就產生錯誤。主要有URLError和HTTPError。
URLError 產生的緣由主要有:沒有網絡鏈接、服務器鏈接失敗、找不到指定的服務器。
HTTPError是URLError的子類,咱們發出一個請求時,服務器上都會對應一個response應答對象,其中它包含一個數字"響應狀態碼"。若是urlopen或opener.open不能處理的,會產生一個HTTPError,對應相應的狀態碼,HTTP狀態碼錶示HTTP協議所返回的響應的狀態。

異常處理程序:

# -*- coding: utf-8 -*-

# 一、URLError
import urllib2
# 訪問一個不存在的域名
requset = urllib2.Request('http://www.ajkfhafwjqh.com')
try:
    urllib2.urlopen(request, timeout=5)
except urllib2.URLError, err:
    print err


# 二、HTTPError
import urllib2
requset = urllib2.Request('http://blog.baidu.com/zhihu')
try:
    urllib2.urlopen(requset)
except urllib2.HTTPError, err:
    # 打印狀態碼
    print err.code
    print err


#三、因爲HTTPError的父類是URLError,因此父類的異常應當寫到子類異常的後面,因此上述的代碼能夠這麼改寫:

import urllib2

requset = urllib2.Request('http://blog.baidu.com/zhihu')

try:
    urllib2.urlopen(requset)

except urllib2.HTTPError, err:
    print err.code

except urllib2.URLError, err:
    print err

else:
    print "OK"
相關文章
相關標籤/搜索