日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python网络爬虫--urllib

發布時間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python网络爬虫--urllib 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇隨便記錄學習崔慶才老師編著的《Python3 網絡爬蟲開發實戰》以及urllib標準庫使用

urllib庫是Python內置的HTTP請求庫,包含四個模塊:

  • request:最基本的HTTP請求模塊,可以用來模擬發送請求。
  • error:異常處理模塊,包含request模塊HTTP請求過程拋出的異常
  • parse:一個工具模塊,提供了許多URL處理的方法,比如拆、解析、合并等
  • robotparser:主要用來識別網站的robot.txt文件,然后判斷網站哪些部分可以爬取

發送請求

urllib.request.urlopen()  

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
  • url:請求的網址,必選參數
  • data:可選參數,如果設定,則該請求為POST請求方法。data必須為字節流數據(可用內置函數bytes()方法轉換為字節流),數據內容如果是字典,可以通過parse模塊的urlencode()方法將其轉換為url格式的字符串
  • timeout:可選參數,設置請求超時時間,單位為秒
  • cafile:可選參數,CA證書文件
  • capath:CA證書路徑
  • cadefault:python3中已經棄用
  • context:可選參數,指定SSL設置,必須為ssl.SSLContext類型
import urllib.request
import urllib.parsename = bytes(urllib.parse.urlencode({"name":"Jane"}),encoding = "utf-8")
response = urllib.request.urlopen("https://www.python.org",data = name,timeout = 1)

urllib.request.Request()

urllib.request.open()方法可以實現最基本的請求,但是該方法中只有幾個參數,有時候不能滿足我們的要求。因此我們可以通過urllib.request.Request()構建一個請求

Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  • url:必選參數,請求的網址
  • data:可選參數,如果設定,則該請求為POST請求方法。data必須為字節流數據(可用內置函數bytes()方法轉換為字節流),數據內容如果是字典,可以通過parse模塊的urlencode()方法將其轉換為url格式的字符串
  • headers:可選參數,請求頭
  • origin_req_host:客戶端主機名稱或者IP地址
  • unverifiable:用戶沒有足夠的權限接收這個請求的結果,默認為False,即我們有權限接收
  • method:請求方法
from urllib import request,parseheaders = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36","accept-encoding":"gzip","Cookie":"_ga=GA1.2.1498502246.1545274514"}
data = bytes(parse.urlencode({"Language":"Python"}),encoding = "utf-8")
my_request = request.Request("https://www.python.org",headers = headers,data = data,method = "POST")
response = request.urlopen(my_request)

handler和opener

常用的handler:

  • HTTPDefaultErrorHandler:用于處理HTTP響應錯誤,錯誤都會拋出HTTPError類型的異常
  • HTTPRedirectHandler:用于處理重定向
  • HTTPCookieProcessor:用于處理Cookies
  • ProxyHandler:用于設置代理,默認代理為空
  • HTTPPasswordMgr:用于管理密碼,維護用戶名與密碼的表單
  • HTTPBasicAuthHandler:用于管理認證,如果打開一個連接需要認真,那么可以用它來解決認證的問題
  • HTTPHandler:用來用處URL

opener:

  • urllib.request.build_opener([handler,?...]):實例化一個opener,使用各種功能的處理器
  • urllib.request.install_opener(opener)?:設定一個全局opener,即程序里所有的請求都調用該opener

自定義的一般步驟:

  1. 使用相關功能的Handle處理器,來創建特定功能的處理器對象
  2. 然后通過如request.build_opener()方法,來使用這些處理器對象,創建自定義opener對象
  3. 使用自定義的opener對象,調用其open()方法向服務器發送請求
from urllib import request
http_handler = request.HTTPHandler() # 實例化一個具有處理url功能的處理器
my_opener = request.build_opener(http_handler) # 創建一個能使用該處理器的opener,此時該opener就具備了處理url功能
response = my_opener.open("https://www.python.org")  
# 設置代理
from urllib import request
my_proxy = {"http":"120.76.55.49:8088"}
proxy_handler = request.ProxyHandler(my_proxy)
proxy_opener = request.build_opener(proxy_handler)
response = proxy_opener.open("https://www.python.org")#如果有多個代理
from urllib import request
import random
my_proxies = [{"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(my_proxies)
proxy_handler = request.ProxyHandler(proxy)
proxy_opener = request.build_opener(proxy_handler)
response = proxy_opener.open("https://www.python.org")

平時我們設置Cookies都是在輸入賬戶、密碼登錄之后,然后在瀏覽器保存這些信息(Cookies),然后再去查看源碼找到這個Cookies(抓包),然后將它加入到請求頭,根據源碼再構建的請求。

而用handler的話,對于python2來說可以用cookielib模塊和urllib.request.HTTPCookieProcessor來處理,對于cookielib模塊有四個對象。在python3中,替換為http.cookiejar庫,四個子類,同python2四個對象相同:

  • CookieJar:管理HTTP cookie值、存儲HTTP請求生成的cookie、向傳出的HTTP請求添加cookie的對象。整個cookie都存儲在內存中,對CookieJar實例進行垃圾回收后cookie也將丟失。
  • FileCookieJar:FileCookieJar(filename,delayload=None,policy=None):從CookieJar派生而來,用來創建FileCookieJar實例,檢索cookie信息并將cookie存儲到文件中。filename是存儲cookie的文件名。delayload為True時支持延遲訪問文件,即只有在需要時才讀取文件或在文件中存儲數據。
  • MozillaCookieJar:MozillaCookieJar(filename, delayload=None, policy=None):從FileCookieJar派生而來,創建與Mozilla瀏覽器 cookies.txt兼容的FileCookieJar實例
  • LWPCookieJar:LWPCookieJar(filename, delay=None, policy=None):從FileCookieJar派生而來,創建與libwww-perl標準的Set-Cookie3文件格式兼容的FileCookieJar實例。

python2中基本用法:

from urllib import request
import cookielib
cookiejar = cookielib.CookieJar() # 創建一個Cookiejar對象來保存cookie
cookie_handler = request.HTTPCookieProcessor(cookiejar) # 創建一個cookie處理器對象
my_opener = request.build_opener(cookie_handler) # 創建一個opener來使用這個處理器
response = my_opener.open("https://www.baidu.com")

python3中基本用法(CookieJar()):

from urllib import request
from http import cookiejarmy_cookiejar = cookiejar.CookieJar() # CookieJar()可以管理,儲存HTTP請求生成的cookie,我們把這個保存的cookie實例化
my_cookiehandler = request.HTTPCookieProcessor(my_cookiejar) # 創建一個處理cookiejar的處理器,也就是處理器處理這個cookie
opener = request.build_opener(my_cookiehandler) # 創建一個opener,此時這個opener就包含了這個cookie
response = opener.open("https://www.baidu.com")

大多數情況我們使用CookieJar(),但是如果需要同本地文件進行交互(也就是從本地讀取,或者在本地創建),那么可以使用MozillaCookieJar()和LWPCookieJar(),兩者用法一樣,只需要將MozillaCookieJar和LWPCookieJar名稱互換

from urllib import request
from http import cookiejar
my_cookiejar = cookiejar.MozillaCookieJar(file) # 創建一個符合Mozilla瀏覽器標準的cookiejar對象,叫做my_cookiejar,此時它是一個對象,一個MozillaCookieJar實例化對象。file,即我們要創建的cookie文件的文件名字
my_cookiehandler = request.HTTPCookieProsessor(my_cookiejar) # 創建一個處理這個cookiejar實例的處理器對象
openr = request.build_opener(my_cookiehandler) # 創建一個opener,來使用這個處理器對象 
response = opener.open("https://www.baidu.com")
# sava()將這個實例化對象my_cookiejar包含的cookies信息,保存成本地文件,文件名之前已經確定了。另外,還可以通過load()方法從一個文件導入cookies
# save()方法中兩個參數,ignore_discard:保存需要被丟棄的cookies;ignore_expires:保存過期的cookies
# 通過下面代碼可以發現本地電腦中創建了一個名為cookie的文本文件
my_cookiejar.save(ignore_discard = True,ignore_expires = True)

對于某些網站需要輸入賬戶、密碼才能訪問,此處我們可以用HTTPPasswordMgrWithDefaultReadlm(管理賬戶、密碼)、HTTPBasicAuthHandler

from urllib import request
username = "Maria"
password = "123456"
np = request.HTTPPasswordMgrWithDefaultReadlm() # 創建一個賬戶密碼管理器對象
np.add_password(username,password) # 賬戶密碼管理器中加入賬戶密碼
auth_handler = request.HTTPBasicAuthHandler(np) # 創建一個驗證該賬戶密碼的處理器對象
opener = request.build_opener(auth_handler)
response = opener.open("https://www.baidu.com")

異常

異常:urrlib庫的error模塊定義了由request模塊產生的異常,如果request模塊應用過程出現了問題,request模塊便會拋出error模塊定義的異常。即,error模塊能捕獲request模塊使用過程中出現的問題,error模塊主要有三類:

  • ContentTooShortError
  • HTTPError
  • URLError

urllib.error.URLError

當各種處理器(handler)運行出現問題的時候,一般是沒有網絡連接或者是無法連接服務器處理器會拋出異常。它是OSError的子類,它具有一個屬性:reason

reason:這個錯誤的原因,它可以是一個字符信息或者是一個異常實

urllib.error.HTTPError

它是URLError的子類,這一種異常通常是連接服務器后,服務器響應出現問題,如返回錯誤信息或者重定向錯誤,網頁驗證錯誤等等。雖然它是一個異常,但是它也可以像非異常文件樣的函數方法一樣返回(像urlopen()方法返回值一樣),這在處理外部HTTPError非常有用,比如 說驗證請求錯誤。這個類包含三個屬性:code、reason、headers

  code:HTTP狀態碼

  reason:通常是一個字符串信息,解釋這個錯誤的原因

  headers:導致HTTPError的HTTP請求后服務器返回的HTTP響應的頭部信息。

urllib.error.ContentTooShort

當urlretrieve()函數檢測到下載的數據量小于預期(這個預期在頭部信息,Content-Length給定)時,拋出該異常。其中,content屬性儲存著下載的(或刪減過后的)數據

from urllib import request
from urllib import error
try:response = request.urlopen("https://www.sdkfjla.com")
except error.URLError as ue:print(ue.reson)print(ue)
except error.HTTPError as he:print(he.code)print(he.reason)print(he.headers)print(he)
except Exception as e:print(e)

?解析鏈接

urlparse()

將一個URL鏈接解析為6部分:<協議>://<域名>/<路徑>;<訪問參數>?<查詢條件>#<錨點>。結果返回包含6個元素的元組。

urlparse(url, scheme='', allow_fragments=True)Parse a URL into 6 components:
<scheme>://<netloc>/<path>;<params>?<query>#<gragment>   
Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
Note that we don't break the components up in smaller bits
(e.g. netloc is a single string) and we don't expand % escape.
  • url:必選參數,即帶解析的URL
  • scheme:默認的協議,如果待解析的URL不含協議信息,則會將該參數作為默認的協議
  • allow_fragment:即是否忽略fragment。如果設置為False,則fragment則會被忽略,而原本該解析為fragment的這一部分會被解析為path、parameters或者query的一部分,fragment則顯示為空
from urllib import parse
result = parse.urlparse("https://i.cnblogs.com/EditPosts.aspx?postid=10813489&update=1")
print(type(result),result)
result1 = parse.urlparse("http://www .baidu .com/index .html;user?id=5#commen",allow_fragment = False)
print(result1)

運行結果:

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', params='', query='postid=10813489&update=1', fragment='')
ParseResult(scheme='http', netloc='www,baidu.com', path='/index.html', params='user', query='5#commen', fragment='')

?urlunparse()

與urlparse()正好相反,構造一個URL鏈接,其接收的參數是一個可迭代對象,但是它的長度必須為6,否則會拋出參數數量不足或者過多的問題。

urlunparse(components)
Put a parsed URL back together again.  This may result in a slightly different, but equivalent URL, 
if the URL that was parsed originally had redundant delimiters,
e.g. a ? with an empty query (the draft states that these are equivalent).

如:

from urllib import parsecomponents = ["http","www.baidu.com","index.html","user","id=5","comment"]
URL = parse.urlunparse(components)
print(URL)

運行結果為:

"http://www.baidu.com/index.html;user?id=5#comment"

urlsplit()

這個方法和urlparse()非常相似,只不過它不再單獨解析params這部分,只返回5個結果。

from urllib import parse
result = parse.urlsplit("http://www .baidu .com/index .html;user?id=5#commen")
print(result)

運行結果:

SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='comment')

urlunsplit()

該方法與urlunparse()非常相似,正好與urlsplit()相反。將鏈接各組分組合成一個完整的鏈接,傳入的參數是一個可迭代對象,但是長度必須為5

from urllib import parse
components = ("http","www.baidu.com","/index.html;name=Jane","id=5","comment")
URL = parse.urlunsplit(components)
print(URL)

運行結果:

http://www.baidu.com/index.html;name=Jane?id=5#comment

urljoin()

urljoin(base, url, allow_fragments=True)Join a base URL and a possibly relative URL to form an absolute interpretation of the latter.
  • base:基礎鏈接
  • url:待構建的一個鏈接
  • allow_fragment:是否包含錨點

首先提供一個基礎鏈接作為第一個參數,將一個新鏈接作為第二個參數,該方法會分析基礎鏈接的scheme、netloc、path這三個部分內容,然后根據這三個組分對新鏈接中的缺失部分進行補充,讓后者形成一個完整的鏈接

from urllib import parse
URL = parse.urljoin("https://www.baidu.com","/index.html;name=Jane?id=2#comment")
print(URL)

運行結果:

https://www.baidu.com/index.html;name=Jane?id=2#comment

urlencode()

常用來構建GET請求參數,即標準鏈接中的params組分。為了方便我們常會現用字典表示參數,然后用該方法將它構建為URL中的params組分。

from urllib import parse
infomation = {"Maria":15,"Jane":16,"Mecheal":16}
base_url = "https://www.baidu.com?"
new_url = base_url+parse.urlencode(infomation)
print(new_url)

運行結果:

https://www.baidu.com?Maria=15&Jane=16&Mecheal=16

parse_qs()

反序列化,假如我們有一串GET請求參數,利用parse_qs()方法,我們可以將這些參數轉回為字典

from urllib import parse
params = "Maria=15&Jane=16&Mecheal=16"
print(parse.parse_qs(params))

運行結果:

{'Maria': ['15'], 'Jane': ['16'], 'Mecheal': ['16']}

parse_qsl()

同parse_qs()方法相似,只是parse_qsl()方法是將請求參數轉化為元組組成的列表

from urllib import parse
params = "Maria=15&Jane=16&Mecheal=16"
print(parse.parse_qsl(params))

運行結果:

[('Maria', '15'), ('Jane', '16'), ('Mecheal', '16')]

quote()

該方法可以將內容轉化為URL編碼,如URL中帶有中文參數時,可能會出現亂碼問題,我們可以用該方法將中文字符轉換為URL編碼

from urllib import parse
keyword = "馮寶寶"
url = "https://www.baidu.com/seach?wd="+parse.quote(keyword)
print(url)

運行結果:

https://www.baidu.com/seach?wd=%E5%86%AF%E5%AE%9D%E5%AE%9D

unquote()

與quote()方法相反,unquote()方法可以將URL中的中文編碼解析還原為中文

from urllib import parse
url = "https://www.baidu.com/seach?wd=%E5%86%AF%E5%AE%9D%E5%AE%9D"
print(parse.unquote(url))

運行結果:

https://www.baidu.com/seach?wd=馮寶寶

解析Robots協議

Robots協議,全稱為網絡爬蟲排除標準(Robots Exclusion Protocol),用來告訴爬蟲或者搜索引擎哪些頁面可以抓取,哪些頁面不可以抓取。通常是一個Robots.txt文件,一般放在網站的根目錄下

robotparser.RobotFileParser類

該類提供了很多方法:

  • can_fetch(self, useragent, url):返回的內容是該搜索引擎是否可以抓取這個 URL ,返回結果是 True 或 False
  • modified(self):將當前時間設置為上次抓取和分析robot.text文件的時間
  • mtime(self):返回的是上次抓取和分析robot.text文件的時間
  • parse(self, lines):用來解析 robots. txt 文件,傳人的參數是 robots .txt某些行的內,它會按照 robots . txt的語法規則來分析這些內容?
  • read(self):讀取 robots . txt 文件并進行分注意,這個方法執行一個讀取和分析操作,如果不調用這個方法 接下來的判斷都會為 False ,所以一定記得調用這個方法 這個方法不會返回任何內容,但是執行了讀取操作?
from urllib.robotparser import RobotFileParser
rp = RobotFileParser() # 對RobotFileParser類實例化
rp.set_url("https://www.taobao.com/robots.text") # 設置robot.txt文件鏈接
rp.read() #讀取該robot.txt文件并分析
# 分析我們是否能抓取該網站的某個頁面
print(rp.can_fetch("*","https://www.taobao.com/markets/3c/tbdc?spm=a21bo.2017.201867-main.12.5af911d9DPQkf4"))

運行結果:

False

?

轉載于:https://www.cnblogs.com/sakura-d/p/10813489.html

總結

以上是生活随笔為你收集整理的Python网络爬虫--urllib的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。