天天看點

python學習之urllib使用小結

urllib庫是python做爬蟲中的基礎庫,也是許多初學者最先入手的地方,下面是我在學習和使用過程中的一些小結

import urllib.request as ur 用于打開網址

import urllib.error as ue 用于處理異常

import urllib.parse as up 用于構造請求

import http.cookiejar as hc 用于cookies的設定

一般網頁的爬取

1.data=ur.urlopen(url,timeout)

url為你想要打開時網址,timeout可以設定逾時時間

data有下列幾種方法:

data.info():可以檢視遠端伺服器回複的頭資訊

data.getcode():檢視http狀态碼(200成功,300重定向,400請求被拒絕或者沒有資源等,500伺服器内部出現了問題)

data.geturl():檢視請求的位址

下面的處理方式有兩種(注意此時的data是二進制的)

第一種:解碼并将其顯示或指派

str1=data.read().decode("utf-8","ignore")    #使用ignore參數來忽視少量的編碼錯誤,友善下面的操作進行
           

第二種:直接用二進制模式寫入檔案中 (.txt,.html均可)

with open(./1.txt) as fh:
    fh.write(data)
           

**

網頁資源的下載下傳

**

對于網絡上的一些資源(圖檔,文本,音頻,網頁本身等),可以通過urllib庫下載下傳下來

這裡我們使用

:ur.urlretrieve(url,filename=filename)

url即為資源的位址,filename為儲存的路徑,在儲存的時候,需要注意:

1.對于Windows系統,檔案路徑中會含有“\”,是以需要進行轉義,可以在每個斜杠前再加上一個“\”,也可以直接在路徑前加上“r”,如

filename=r"C:\User\TIAN\Desktop\檔案名"

2.有時候對儲存的路徑,python會沒有寫入的權限,需要自己在建立時修改檔案屬性

添加浏覽器辨別

對于擁有一些反扒機制的網站,其會檢查請求的User-Agent字段,如果不添加浏覽器辨別,就不能得到正确的網站資料

對于添加浏覽器辨別,我所知的方式有兩種

1.使用ur.Request

url = 'http://www.baidu.com'
header = {
   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'
}
req = ur.Request(url, headers=header)
ur.urlopen(req)
           

2構造opener

new_opener=ur.build_opener()
header=('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96Safari/537.36')
new_opener.addheaders=[header]
           

下面可以使用new_opener.open(url)來擷取資料了

如果想要使用ur.urlopen(url),還需要加上一行:

ur.install_opener(new_opener)

異常的處理

在爬取網站時,常常有很多url需要進行批量操作,如果不進行異常處理,若在某個地方發生了錯誤,爬蟲将會崩潰,後面的全部操作将無法完成

異常主要有兩種:URLError 和 HTTPError ,以及其他的一些小的錯誤,由于HTTPError是URLError的子類,我們隻用URLError即可,同時對于其他錯誤,統一用Exception來代替

代碼段:

try:
    data=ur.urlopen(url).read()
except (URLError,Exception) as e:
    if hasattr(e,"code") and hasattr(e,"reason"):    #針對URLError,輸出狀态碼以及錯誤原因
        print(e.code,e.reason)
    else:
        print(e)   #針對Exception,由于不知道錯誤類型,将直接輸出(當然如果不想這麼細化,可以直接輸出e也可以)
           

其他操作中的錯誤同理(大不了統一用Exception)

代理伺服器的設定

爬蟲都是存在風險的,在不知道對方反扒機制的情況下,直接通路可能會被封禁IP,這時我們就要用到代理伺服器為我們去爬

代碼段:

proxy=ur.ProxyHandler({'http':proxy_addr}) #proxy——addr即為代理伺服器的IP(帶端口)
new_opener=ur.build_opener(proxy,ur.HTTPHandler)  #ur.HTTPHandler為固定值
ur.install_opener(opener)  #使得urlopen自動帶有proxy
data=ur.urlopen(url).read().decode('utf8')
#大家可以注意到,這裡使用代理的方式與添加浏覽器辨別的代碼如出一轍,是以在實際操作中可以一并加上
           

資料的送出與cookie的使用

如果我們想要爬取某網站登陸後界面的資訊,就要把登陸的資訊和cookie一并送出

url='http://accounts.douban.com/login'
#設定送出的資料,注意資料的字段名要到網頁源代碼中找
data={
    'form_email':'***********',
    'form_password':'***********',
    'redir':'http://www.douban.com/people/********/'     #設定送出後要登陸的頁面
}
#将資料編碼(因為純字元的形式不能被伺服器識别)
postdata=up.urlencode(data).encode('utf8')
header={
    'User-Agent':'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
#使用ur.Request方法構造請求并加上url,postdata,headers
req=ur.Request(url,postdata,headers=header)
#使用hc.CookieJar()建立CookieJar對象
cjar=hc.CookieJar()
#使用HTTPCookieProcessor建立cookie處理器
cookie=ur.HTTPCookieProcessor(cjar)
opener=ur.build_opener(cookie)
ur.install_opener(opener)
data=ur.urlopen(req)
           

打開HTTPS的網址

ur.urlopen()不能直接打開https://的網址,因為要驗證一次證書進而導緻URLError,可以在開頭加上

import ssl

ssl._create_default_https_context = ssl._create_unverified_context
           

總結:在構造請求時要明确幾個不同的概念及他們的構造方式

1.目标網址——————>直接由url指定

2.模拟浏覽器——————>通過ur.request(url,postdata,headers)中headers添加

3.post送出表單資料——————>通過ur.request(url,postdata,headers)中postdata添加,注意要用ur.urlencode().encode(“utf-8”)進行處理

4.代理設定——————>使用ur.ProxyHandler({‘http’:proxy_addr})構造并添加到ur.build_opener()

5.cookie設定——————>cjar=hc.CookieJar()———>cookie=ur.HTTPCookieProcessor(cjar)——————>opener=ur.build_opener(cookie)

最後注意構造的opener要使用ur.install_opener(opener)才能在ur.urlopen(req)中發揮作用