Python爬蟲之urllib庫—爬蟲的第一步

2021-02-20 Python數據科學

第一個爬蟲代碼的實現我想應該是從urllib開始吧,博主開始學習的時候就是使用urllib庫敲了幾行代碼就實現了簡單的爬數據功能,我想大多夥伴們也都是這麼過來的。當時的感覺就是:哇,好厲害,短短幾行竟然就可以搞定一個看似很複雜的任務,於是就在想這短短的幾行代碼到底是怎麼實現的呢,如何進行更高級複雜的爬取呢?帶著這個問題我也就開始了urllib庫的學習。

首先不得不提一下爬取數據的過程,弄清楚這到底是怎樣一個過程,學習urllib的時候會更方便理解。

  

其實,爬蟲的過程和瀏覽器瀏覽網頁的過程是一樣的。道理大家應該都明白,就是當我們在鍵盤上輸入網址點擊搜索之後,通過網絡首先會經過DNS伺服器,分析網址的域名,找到了真正的伺服器。然後我們通過HTTP協議對伺服器發出GET或POST請求,若請求成功,我們就得到了我們想看到的網頁,一般都是用HTML, CSS, JS等前端技術來構建的,若請求不成功,伺服器會返回給我們請求失敗的狀態碼,常見到的503,403等。

 

爬蟲的過程亦是如此,通過對伺服器發出請求得到HTML網頁,然後對下載的網頁進行解析,得到我們想要的內容。當然,這是一個爬蟲過程的一個概況,其中還有很多細節的東西需要我們處理的,這些在後續會繼續與大家分享。

 

了解了爬蟲的基本過程後,就可以開始我們真正的爬蟲之旅了。

 

 

Python有一個內置的urllib庫,可謂是爬蟲過程非常重要的一部分了。這個內置庫的使用就可以完成向伺服器發出請求並獲得網頁的功能,所以也是學習爬蟲的第一步了。

 

博主用的是Python3.x,urllib庫的結構相對於Python2.x有一些出入,Python2.x中使用的urllib2和urllib庫,而Python3.x中合併成一個唯一的urllib庫。

 

首先,我們來看看Python3.x的urllib庫都有什麼吧。

博主用的IDE是Pycharm,編輯調試非常方便,很贊。 

在控制臺下輸入如下代碼:

>>importurllib

>>dir(urllib)


結果:

['__builtins__','__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__','__path__', '__spec__', 'error', 'parse', 'request', 'response']

 

可以看到urllib除了以雙下劃線開頭結尾的內置屬性外,還有4個重要的屬性,分別是error,parse,request,response。

 

在Python的urllib庫中doc開頭是這樣簡短描述的:

Error:「Exception classesraised by urllib.」----就是由urllib舉出的exception類

Parse:「Parse (absolute andrelative) URLs.」----解析絕對和相對的URLs

Request:「An extensiblelibrary for opening URLs using a variety of protocols」

----用各種協議打開URLs的一個擴展庫

Response:「Response classesused by urllib.」----被urllib使用的response類

 

這4個屬性中最重要的當屬request了,它完成了爬蟲大部分的功能,我們先來看看request是怎麼用的。

request請求最簡單的操作是用urlopen方法,代碼如下

import urllib.request
response = urllib.request.urlopen('http://python.org/')
result = response.read()
print(result)

運行結果如下:

b'<!doctype html>\n<!--[if lt IE 7]>...</body>\n</html>\n'

發現得到的運行結果竟然是亂碼!!別著急,這是因為編碼的問題,我們只需要將請求的類文件讀取再解碼就可以了。

修改代碼如下:

import urllib.request
response = urllib.request.urlopen('http://python.org/')
result = response.read().decode('utf-8')
print(result)

運行結果:

<!doctype html>
<!--[if lt IE 7]>   <html class="no-js ie6 lt-ie7 lt-ie8>..
<!--[if IE 7]>      <html class="no-js ie7 lt-ie8 lt-ie9">..
<!--[if IE 8]>      <html class="no-js ie8 lt-ie9">                 <![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" lang="en" dir="ltr"

<head>
   <meta charset="utf-8">
...

得到的就是我們想要的html的網頁了,怎麼樣,簡單吧。

下面來介紹一下這個urlopen方法和其中應用的參數。

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TI
MEOUT,*, cafile=None, capath=None,
cadefault=False, context=None):

這個urlopen的功能是打開一個URL,可以是一串字符串(如上例子中一樣),也可以是Request對象(後面會提到)。它會返回一個類文件對象,並可以針對這個對象進行各種操作(如上例中的read操作,將html全部讀出來,後面會介紹其它的幾個操作)。

<1>url即是我們輸入的url網址(如:http://www.xxxx.com/);

<2>data:是我們要發給伺服器請求的額外信息(比如登錄網頁需要主動填寫的用戶信息)。如果需要添加data參數,那麼是POST請求,默認無data參數時,就是GET請求;

        <2.1>一般來講,data參數只有在http協議下請求才有意義

        <2.2>data參數被規定為byte object,也就是字節對象

        <2.3>data參數應該使用標準的結構,這個需要使用                        

         urllib.parse.urlencode()將data進行轉換,而一般我們把data設置成字典格               式再進行轉換即可;

         data在以後實戰中會介紹如何使用

<3>timeout:是選填的內容,定義超時時間,單位是秒,防止請求時間過長,不填就是默認的時間;

<4>cafile:是指向單獨文件的,包含了一系列的CA認證 (很少使用,默認即可);

<5>capath:是指向文檔目標,也是用於CA認證(很少使用,默認即可);

<5>cafile:可以忽略

<6>context:設置SSL加密傳輸(很少使用,默認即可);

對返回的類文件對象也可以進行其它操作:


geturl(): 返回URL,用於看是否有重定向。

result = response.geturl()

結果:

https://www.python.org/

info():返回元信息,例如HTTP的headers。

result = response.info()

結果:

x-xss-protection: 1; mode=block
X-Clacks-Overhead: GNU Terry Pratchett
...
Vary: Cookie
Strict-Transport-Security: max-age=63072000;includeSubDomains


getcode():返回回復的HTTP狀態碼,成功是200,失敗可能是503等,可以用來檢查代理IP的可使用性。

result = response.getcode()

結果:

200

class Request:
   def __init__(self, url, data=None, headers={},
origin_req_host=None, unverifiable=False,
method=None):

如上定義,Request是一個類,初始化中包括請求需要的各種參數:

<1>url,data和上面urlopen中的提到的一樣。

<2>headers是HTTP請求的報文信息,如User_Agent參數等,它可以讓爬蟲偽裝成瀏覽器而不被伺服器發現你正在使用爬蟲。

<3>origin_reg_host, unverifiable, method等不太常用

headers很有用,有些網站設有反爬蟲機制,檢查請求若沒有headers就會報錯,因此博主為保證爬蟲的穩定性,基本每次都會將headers信息加入進去,這是反爬的簡單策略之一。

那麼如何找到你所在瀏覽器的headers呢?

可以通過進入瀏覽器F12查看到

比如,博主用的Chrome瀏覽器,按F12->network就可以查看request的headers,可以把這個瀏覽器的headers信息複製下來使用。

下面來看看Request如何使用吧,代碼如下:

import urllib.request
headers = {'User_Agent': ''}
response = urllib.request.Request('http://python.org/', headers=headers)
html = urllib.request.urlopen(response)
result = html.read().decode('utf-8')
print(result)

結果和前面urlopen是一樣的,前面提到urlopen除了可以接受指定參數,也可以接受Request類的對象。

在需要headers的情況下,使用Request對象還是很有必要的。

' '裡面填寫自己瀏覽器的信息即可。

urllib庫的requset屬性裡面還有很多其它方法,代理、超時、認證、HTTP的POST模式下請求等內容將在下次進行分享,這次主要介紹基本功能。

下面來說說異常,urllib庫的error方法。

error屬性裡面主要包括了兩個重要的exception類,URLError類和HTTPError類。

def __init__(self, reason, filename=None):
   self.args = reason,
self.reason = reason
if filename is not None:
       self.filename = filename

URLError類是OSError的子類,繼承OSError,沒有自己的任何行為特點,但是將作為error裡面所有其它類型的基類使用。

URLError類初始化定義了reason參數,意味著當使用URLError類的對象時,可以查看錯誤的reason。

def __init__(self, url, code, msg, hdrs, fp):
   self.code = code
self.msg = msg
self.hdrs = hdrs
self.fp = fp
self.filename = url

HTTPError是URLError的子類,當HTTP發生錯誤將舉出HTTPError。

HTTPError也是HTTP有效回應的實例,因為HTTP協議錯誤是有效的回應,包括狀態碼,headers和body。所以看到在HTTPError初始化的時候定義了這些有效回應的參數。

當使用HTTPError類的對象時,可以查看狀態碼,headers等。

下面我們用一個例子來看一下如何使用這兩個exception類。

import urllib.request
import urllib.error
try:
   headers = {'User_Agent': 'Mozilla/5.0 (X11; Ubuntu;
               Linux x86_64; rv:57.0) Gecko/20100101
               Firefox/57.0'}
   response = urllib.request.Request('http://python.org/',
headers=headers)
   html = urllib.request.urlopen(response)
   result = html.read().decode('utf-8')
except urllib.error.URLError as e:
   if hasattr(e, 'reason'):
       print('錯誤原因是' + str(e.reason))
except urllib.error.HTTPError as e:
   if hasattr(e, 'code'):
       print('錯誤狀態碼是' + str(e.code))
else:
   print('請求成功通過。')

以上代碼使用了try..exception的結構,實現了簡單的網頁爬取,當有異常時,如URLError發生時,就會返回reason,或者HTTPError發生錯誤時就會返回code。異常的增加豐富了爬取的結構,使其更加健壯。

為什麼說更加健壯了呢?

不要小看了這些異常的錯誤,這些異常的錯誤非常好用,也非常關鍵。想想看,當你編寫一個需要不斷自動運行爬取並解析的代碼時,你是不希望程序中間被打斷而終止的。如果這些異常狀態沒有設置好,那麼就很有可能彈出錯誤而被終止,但如果設置好了完整的異常,則遇到錯誤時就會執行發生錯誤的代碼而不被打斷(比如向上面代碼一樣列印錯誤code等)。

這些打斷程序的錯誤可能是很多種,尤其當你使用代理ip池的時候,會發生很多不同錯誤,這時異常就起到作用了。

主要介紹了爬蟲的過程和urllib的使用和功能,針對爬蟲主要介紹了以下的使用方法:

request基本功能, urlopen, Request

error異常的使用

後續將會分享一些request的高級功能,如自定義opener使用代理ip、超時設置、認證等,以及如何POST請求主動發送信息等,也會利用這些內容做一次實戰爬取,希望大家能更加理解。

歡迎大家一起來討論學習,後面內容敬請期待!

相關焦點

  • python爬蟲之urllib庫
    urllib庫簡介urllib 庫是 Python 中一個最基本的網絡請求庫。可以模擬瀏覽器的行為,向指定的伺服器發 送一個請求,並可以保存伺服器返回的數據。urlopen函數在python3的urllib庫中,所有和網絡請求相關的方法,都被集成到urllib.request模塊下了,該函數的使用格式如下:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath
  • Python爬蟲常用庫之urllib詳解
    而當scheme協議加了,而前面的url也包含協議,一般會忽略後面的scheme參數既然後解析url,那當然也有反解析url,就是把元素串連成一個url1from urllib import parse2# 將列表元素拼接成url3url = ['http', 'www', 'baidu', 'com', 'dfdf', 'eddffa'] # 這裡至少需要
  • Python爬蟲 | 0x6 - 請求庫:urllib
    urlib庫是Python內置的一個HTTP請求庫,在Python2中由urllib和urllib2
  • python爬蟲常用庫之urllib詳解
    以下為個人在學習過程中做的筆記總結之爬蟲常用庫urlliburlib庫為python3的HTTP內置請求庫urilib的四個模塊:urllib.request:用於獲取網頁的響應內容urllib.error:異常處理模塊,用於處理異常的模塊urllib.parse:用於解析url
  • 【Python爬蟲】Urllib的使用(2)
    寫在前面這是第二篇介紹爬蟲基礎知識的文章,之前的文章【Python爬蟲】初識爬蟲(1)主要是讓大家了解爬蟲和爬蟲需要的基礎知識
  • python爬蟲基礎之urllib的使用
    這篇文章主要介紹了python爬蟲基礎之urllib的使用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下一
  • Python爬蟲之urllib庫—進階篇
    urllib庫除了一些基礎的用法外,還有很多高級的功能,可以更加靈活的適用在爬蟲應用中,比如,用HTTP的POST請求方法向伺服器提交數據實現用戶登錄
  • 小白學 Python 爬蟲(11):urllib 基礎使用(一)
    人生苦短,我用 Python前文傳送門:小白學 Python 爬蟲(1):開篇小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝小白學 Python
  • Python 爬蟲:urllib.request 模塊
    /usr/bin/env python32    #-*- coding: utf-8 -*-3    __author__ = 'hstking hst_king@hotmail.com'45    import urllib.request67    def clear():8     '''該函數用於清屏
  • 小白學 Python 爬蟲(13):urllib 基礎使用(三)
    爬蟲(2):前置準備(一)基本類庫的安裝小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門小白學 Python 爬蟲(5):前置準備(四)資料庫基礎小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝小白學 Python 爬蟲(7):HTTP
  • 10-python爬蟲之lxml庫
    lxml 是一種使用 Python 編寫的庫,可以迅速、靈活地處理 XML ,支持 XPath (XML Path Language)lxml
  • python爬蟲-學習urllib和requests使用,模擬請求
    urllib介紹Python內置的HTTP請求庫,安裝好Python就能用,它是最基本的請求庫,用於訪問網絡資源,程序發起請求,獲取響應數據,使用該庫實現。urllib的request模塊可以非常方便地抓取URL內容,也就是發送一個GET請求到指定的頁面,然後返回HTTP的響應:# 導入urllib.request 庫import urllib.request# 向指定的url發送請求,並返回伺服器響應的類文件對象response = urllib.request.urlopen("http
  • Python爬蟲常用庫之requests詳解
    作者:sergiojune      個人公眾號:日常學python作者好文:Python爬蟲常用庫之urllib
  • Python爬蟲實戰 | 只需 「4步」 入門網絡爬蟲(有福利哦)
    上面的網頁原始碼,在python語言中,我們只需要使用urllib、requests等庫實現即可,具體如下。這裡特別說明一些,requests比urllib更加方便、快捷。一旦學會requests庫,肯定會愛不釋手。
  • Python爬蟲:一些常用的爬蟲技巧總結
    也差不多一年多了,python應用最多的場景還是web快速開發、爬蟲、自動化運維:寫過簡單網站、寫過自動發帖腳本、寫過收發郵件腳本、寫過簡單驗證碼識別腳本。爬蟲在開發過程中也有很多復用的過程,這裡總結一下,以後也能省些事情。
  • Python 網絡爬蟲的常用庫匯總
    爬蟲的程式語言有不少,但 Python 絕對是其中的主流之一。今天就為大家介紹下 Python 在編寫網絡爬蟲常常用到的一些庫。
  • Python網絡爬蟲(二)- urllib爬蟲案例
    # -*- coding:utf-8 -*-#引入需要的模塊import urllib #用於進行中文編碼import urllib2  #用於進行爬蟲核心處理#定義一個函數,用於爬取對應的數據def load_url(url,file_name):    '''    作用:針對指定的
  • Python爬蟲的兩套解析方法和四種爬蟲實現
    對於大多數朋友而言,爬蟲絕對是學習python的最好的起手和入門方式。
  • python 安全之 urllib 模塊
    urllib 庫是
  • 什麼是Python網絡爬蟲?看這篇清晰多了!
    在py上面的網頁原始碼,在python語言中,我們只需要使用urllib、requests等庫實現即可,具體如下。這裡特別說明一些,requests比urllib更加方便、快捷。一旦學會requests庫,肯定會愛不釋手。