天天看點

python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

python網絡爬蟲

靜态網頁爬取概述

靜态網頁介紹

  • 在網站設計中,純粹HTML(标準通用标記語言下的一個應用)格式的網頁通常被稱為“靜态網頁”,靜态網頁是标準的HTML檔案,它的檔案擴充名是.htm、.html,可以包含文本、圖像、聲音、FLASH動畫、用戶端腳本和ActiveX控件及JAVA小程式等。(無法實作互動功能)
  • 靜态網頁是網站建設的基礎,早期的網站一般都是由靜态網頁制作的。靜态網頁是相對于動态網頁而言,是指沒有背景資料庫、不含程式和不可互動的網頁。動态網頁有資料傳遞的過程,實時更新。靜态網頁相對于動态網頁加載速度更快。

簡單靜态網頁爬取

  1. 爬蟲進本流程

    (1) 發起請求:通過HTTP庫向目标站點發起請求,即發送一個Request,請求可以包含額外的headers等資訊,等待伺服器響應。

    (2) 擷取響應内容:如果伺服器能正常響應,會得到一個Response,Response的内容便是所要擷取的頁面内容,類型可能有HTML,Json字元串,二進制資料(如圖檔視訊)等類型。

    (3) 解析内容:得到的内容可能是HTML,可以用正規表達式、網頁解析庫進行解析。可能是Json,可以直接轉為Json對象解析,可能是二進制資料,可以做儲存或者進一步的處理。

    (4) 儲存資料:儲存形式多樣,可以存為文本,也可以儲存至資料庫,或者儲存特定格式的檔案。

實作HTTP請求

1.使用urllib3庫實作

許多Python的原生系統已經開始使用urllib3庫,其提供了很多python标準庫裡所沒有的重要特性。

連接配接特性 連接配接特性
線程安全 管理連接配接池
用戶端SSL∕TLS驗證 使用分部編碼上傳檔案
協助處理重複請求和HTTP重定位 支援壓縮編碼
支援HTTP和SOCKS代理 測試覆寫率達到100%

(1)生成請求

通過request方法即可建立一個請求,該方法傳回一個HTTP響應對象。Reques文法格式如下。

參數 說明
method 接收string。表示請求的類型,如“GET”、“HEAD”、“DELETE”等。無預設值
url 接收string。表示字元串形式的網址。無預設值
field 接收dict。表示請求類型所帶的參數。預設為None
headers 接收dict。表示請求頭所帶參數。預設為None
**urlopen_kw 接收dict或其他Python中的類型的資料。依據具體需要及請求的類型可添加的參數,通常參數指派為字典類型或為具體資料。無預設值
import urllib3
http = urllib3.PoolManager()#urllib3必須生成一個執行個體才能進行request請求
request = http.request('GET',
                       url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501')
           

(2)請求頭處理

在request方法中,如果需要傳入headers參數,可通過定義一個字典類型實作。定義一個包含User-Agent資訊的字典,使用浏覽器為火狐和chrome浏覽器,作業系統為“Windows NT 6.1; Win64; x64”,向網站添加連結描述發送帶headers參數的GET請求,hearders參數為定義的User-Agent字典。

import urllib3
http = urllib3.PoolManager()#urllib3必須生成一個執行個體才能進行request請求
head = {'User-Agent':'Windows NT 6.1: Win64: x64'}
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             headers=head)
           

(3)Timeout設定

為防止因為網絡不穩定、伺服器不穩定等問題造成連接配接不穩定時的丢包,可以在請求中增加timeout參數設定,通常為浮點數。依據不同需求,timeout參數提供多種設定方法,可直接在URL後設定該次請求的全部timeout參數,也可分别設定該次請求的連接配接與讀取timeout參數,在PoolManager執行個體中設定timeout參數可應用至該執行個體的全部請求中。
重定向(Redirect)就是通過各種方法将各種網絡請求重新定個方向轉到其它位置(如:網頁重定向、域名的重定向、路由選擇的變化也是對資料封包經由路徑的一種重定向)。
  • 方法一直接在url網址後添加
import urllib3
http = urllib3.PoolManager()#urllib3必須生成一個執行個體才能進行request請求
head = {'User-Agent':'Windows NT 6.1: Win64: x64'}
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             timeout=3.0,
             headers=head)#逾時超過三秒就終止
           
  • 方法二 使用urllib3内置函數分别設定連接配接和讀取參數
import urllib3
http = urllib3.PoolManager()#urllib3必須生成一個執行個體才能進行request請求
head = {'User-Agent':'Windows NT 6.1: Win64: x64'}
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             timeout=urllib3.Timeout(connect=1.0,read=2.0),
             headers=head)#連接配接超過一秒或讀取超過兩秒就終止
           
  • 方法三在設定好的PoolManager執行個體裡進行設定
import urllib3
http = urllib3.PoolManager(timeout=4.0)
head = {'User-Agent':'Windows NT 6.1: Win64: x64'}
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             headers=head)
           

(4)請求重試設定

urllib3庫可以通過設定retries參數對重試進行控制(逾時重試)。預設進行3次請求重試,并進行3次重定向。自定義重試次數通過指派一個整型給retries參數實作,可通過定義retries執行個體來定制請求重試次數及重定向次數。若需要同時關閉請求重試及重定向則可以将retries參數指派為False,僅關閉重定向則将redirect參數指派為False。與Timeout設定類似,可以在PoolManager執行個體中設定retries參數控制全部該執行個體下的請求重試政策。
  • 方法一從執行個體的内置函數進行設定
import urllib3
http = urllib3.PoolManager(timeout=4.0,retries=10)#重試十次
head = {'User-Agent':'Windows NT 6.1: Win64: x64'}
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             headers=head)
           
  • 方法二在request函數設定參數
http.request('GET',
             url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501', 
             headers=head,
             retries=10)
           

(5)生成完整HTTP請求

使用urllib3庫實作生成一個完整的請求,該請求應當包含連結、請求頭、逾時時間和重試次數設定。

User-Agent參數設定可在網頁開發者工具(F12)進行查找。

按F12打開開發者工具,從Network中重新整理檢視參數
import urllib3
#發送請求頭的執行個體
http = urllib3.PoolManager()

#網址
url = 'https://blog.csdn.net/m0_51877411/article/details/116208871?spm=1001.2014.3001.5501'

#請求頭
head = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46'}

#逾時時間的設定
time = urllib3.Timeout(connect=1.0,read=3.0)

#重試次數和重定向次數設定
request = http.request('GET', url=url ,headers=head, timeout=time, retries=5, redirect=4)
           

此時就可以生成完整的HTTP請求

接下來可以列印一下伺服器響應碼和響應實體

print('伺服器響應碼:', request.status)
print('響應實體:', request.data)
           

可以發現中文全部變成\x的編碼方式

python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

可以轉換編碼方式decode()

print('伺服器響應碼:', request.status)
print('響應實體:', request.data.decode('utf-8'))
           

此時中文可正常顯示

python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

可從網站源代碼meta标簽下檢視編碼方式

python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

2.使用requests庫實作HTTP請求

requests庫是一個原生的HTTP庫,比urllib3庫更為容易使用。requests庫發送原生的HTTP 1.1請求,無需手動為URL添加查詢字串,也不需要對POST資料進行表單編碼。相對于urllib3庫,requests庫擁有完全自動化Keep-alive和HTTP連接配接池的功能(是以不需要去手動給url進行查詢字數的添加以及post資料進行表達編碼,可以直接通過get方法擷取響應實體)。requests庫包含的特性如下。

連接配接特性 連接配接特性 連接配接特性
Keep-Alive&連接配接池 基本∕摘要式的身份認證 檔案分塊上傳
國際化域名和URL 優雅的key∕value Cookie 流下載下傳
帶持久Cookie的會話 自動解壓 連接配接逾時
浏覽器式的SSL認證 Unicode響應體 分塊請求
自動内容解碼 HTTP(S)代理支援 支援.netrc
  • 使用requests庫實作
  1. 生成請求

    requests庫生成請求的代碼非常便利,其使用的request方法的文法格式如下。

request方法常用的參數及其說明如下。

參數 說明
method 接收string。表示請求的類型,如“GET”、“HEAD”、“DELETE”等。無預設值
url 接收string。表示字元串形式的網址。無預設值
**kwargs 接收dict或其他Python中的類型的資料。依據具體需要及請求的類型可添加的參數,通常參數指派為字典類型或為具體資料
import requests
url =  'https://edu.tipdm.org/course/1749/task/42885/show'
rqq = requests.get(url)
print('響應碼:',rqq.status_code)
print('編碼方式:',rqq.encoding)
print('請求頭:',rqq.headers)
print('響應實體:',rqq.content)
print('響應實體:',rqq.text)
           
python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

此時可以發現中文編碼以\x方式出現

content()和text()比較

print('響應實體:',rqq.content[:40])
print('響應實體:',rqq.text[:40])#列印前四十行
           
python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

最後傳回的字元串類型有所不同

2. 檢視狀态碼與編碼

  • 需要注意的是,當requests庫猜測錯時,需要手動指定encoding編碼,避免傳回的網頁内容解析出現亂碼。
  • chardet庫使用detect方法檢測給定字元串的編碼,detect方法常用的參數及其說明如下。
參數 說明
byte_str 接收string。表示需要檢測編碼的字元串。無預設值
import requests
url =  'https://edu.tipdm.org/course/1749/task/42885/show'
rqq = requests.get(url)
rqq.encoding = 'utf-8'
print('響應實體:',rqq.text)
           
python網絡爬蟲 : 靜态網頁爬取python網絡爬蟲

此時編碼方式轉換成中文編碼正常顯示

但content()仍以亂碼形式出現

修改content()中文亂碼方式

  • 手動指定的方法并不靈活,無法自适應對應爬取過程中不同網頁的編碼,而使用chardet庫比較簡便靈活,chardet庫是一個非常優秀的字元串∕檔案編碼檢測子產品。
import chardet
chardet.detect(rqq.content)#需要輸入為位元組型資料的content,如果輸入text會報錯
>>>import chardet
chardet.detect(rqq.content)#需要輸入為位元組型資料的content,如果輸入text會報錯
import chardet
chardet.detect(rqq.content)#需要輸入為位元組型資料的content,如果輸入text會報錯
>>>{'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}
           
  1. 請求頭與響應頭處理

    requests庫中對請求頭的處理與urllib3庫類似,也使用headers參數在GET請求中上傳參數,參數形式為字典。使用headers屬性即可檢視伺服器傳回的響應頭,通常響應頭傳回的結果會與上傳的請求參數對應。

import requests
url =  'https://edu.tipdm.org/course/1749/task/42885/show'
head = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51'}
rqq = requests.get(url, headers=head)
rqq.headers
           
  1. Timeout設定

    為避免因等待伺服器響應造成程式永久失去響應,通常需要給程式設定一個時間作為限制,超過該時間後程式将會自動停止等待。在requests庫中通過設定timeout這個參數實作,超過該參數設定的秒數後,程式會停止等待。

import requests
url =  'https://edu.tipdm.org/course/1749/task/42885/show'
head = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51'}
rqq = requests.get(url, headers=head,timeout=2.0)
rqq.headers
           
  1. 生成完整HTTP請求

    使用requests庫的request方法向網站“http://www.tipdm.com/tipdm/index.html”發送一個完整的GET請求,該請求包含連結、請求頭、響應頭、逾時時間和狀态碼,并且編碼應正确設定。