程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python urllib

編輯:Python

Python urllib 庫用於操作網頁 URL,並對網頁的內容進行抓取處理。

本文主要介紹 Python3 的 urllib。

urllib 包 包含以下幾個模塊:

  • urllib.request - 打開和讀取 URL。
  • urllib.error - 包含 urllib.request 拋出的異常。
  • urllib.parse - 解析 URL。
  • urllib.robotparser - 解析 robots.txt 文件。

 


urllib.request

urllib.request 定義了一些打開 URL 的函數和類,包含授權驗證、重定向、浏覽器 cookies等。

urllib.request 可以模擬浏覽器的一個請求發起過程。

我們可以使用 urllib.request 的 urlopen 方法來打開一個 URL,語法格式如下:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
  • url:url 地址。
  • data:發送到服務器的其他數據對象,默認為 None。
  • timeout:設置訪問超時時間。
  • cafile 和 capath:cafile 為 CA 證書, capath 為 CA 證書的路徑,使用 HTTPS 需要用到。
  • cadefault:已經被棄用。
  • context:ssl.SSLContext類型,用來指定 SSL 設置。

實例如下:

實例

from urllib.request import urlopen
myURL = urlopen("https://www.runoob.com/")
print(myURL.read())

以上代碼使用 urlopen 打開一個 URL,然後使用 read() 函數獲取網頁的 HTML 實體代碼。

read() 是讀取整個網頁內容,我們可以指定讀取的長度:

實例

from urllib.request import urlopen
myURL = urlopen("https://www.runoob.com/")
print(myURL.read(300))

除了 read() 函數外,還包含以下兩個讀取網頁內容的函數:

  • readline() - 讀取文件的一行內容

    from urllib.request import urlopen
    myURL = urlopen("https://www.runoob.com/")
    print(myURL.readline()) #讀取一行內容
  • readlines() - 讀取文件的全部內容,它會把讀取的內容賦值給一個列表變量。

    from urllib.request import urlopen
    myURL = urlopen("https://www.runoob.com/")
    lines = myURL.readlines()
    for line in lines:
    print(line) 

我們在對網頁進行抓取時,經常需要判斷網頁是否可以正常訪問,這裡我們就可以使用 getcode() 函數獲取網頁狀態碼,返回 200 說明網頁正常,返回 404 說明網頁不存在:

實例

import urllib.request
myURL1 = urllib.request.urlopen("https://www.runoob.com/")
print(myURL1.getcode())   # 200
try:
    myURL2 = urllib.request.urlopen("https://www.runoob.com/no.html")
except urllib.error.HTTPError as e:
    if e.code == 404:
        print(404)   # 404

如果要將抓取的網頁保存到本地,可以使用 Python3 File write() 方法 函數:

實例

from urllib.request import urlopen
myURL = urlopen("https://www.runoob.com/")
f = open("runoob_urllib_test.html", "wb")
content = myURL.read()  # 讀取網頁內容
f.write(content)
f.close()

執行以上代碼,在本地就會生成一個 runoob_urllib_test.html 文件,裡面包含了 https://www.runoob.com/ 網頁的內容。

URL 的編碼與解碼可以使用 urllib.request.quote() 與 urllib.request.unquote() 方法:

實例

import urllib.request
encode_url = urllib.request.quote("https://www.runoob.com/")  # 編碼
print(encode_url)
unencode_url = urllib.request.unquote(encode_url)    # 解碼
print(unencode_url)
輸出結果為:
https%3A//www.runoob.com/
https://www.runoob.com/

模擬頭部信息

我們抓取網頁一般需要對 headers(網頁頭信息)進行模擬,這時候需要使用到 urllib.request.Request 類:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  • url:url 地址。
  • data:發送到服務器的其他數據對象,默認為 None。
  • headers:HTTP 請求的頭部信息,字典格式。
  • origin_req_host:請求的主機地址,IP 或域名。
  • unverifiable:很少用整個參數,用於設置網頁是否需要驗證,默認是False。。
  • method:請求方法, 如 GET、POST、DELETE、PUT等。

實例 - py3_urllib_test.php 文件代碼

import urllib.request
import urllib.parse
url = 'https://www.runoob.com/?s='  # 菜鳥教程搜索頁面
keyword = 'Python 教程'
key_code = urllib.request.quote(keyword)  # 對請求進行編碼
url_all = url+key_code
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'
}   #頭部信息
request = urllib.request.Request(url_all,headers=header)
reponse = urllib.request.urlopen(request).read()
fh = open("./urllib_test_runoob_search.html","wb")    # 將文件寫入到當前目錄中
fh.write(reponse)
fh.close()

打開 urllib_test_runoob_search.html 文件(可以使用浏覽器打開),內容如下:

表單 POST 傳遞數據,我們先創建一個表單,代碼如下,我這裡使用了 PHP 代碼來獲取表單的數據:

實例

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com) urllib POST  測試</title>
</head>
<body>
<form action="" method="post" name="myForm">
    Name: <input type="text" name="name"><br>
    Tag: <input type="text" name="tag"><br>
    <input type="submit" value="提交">
</form>
<hr>
<?php
// 使用 PHP 來獲取表單提交的數據,你可以換成其他的
if(isset($_POST['name']) && $_POST['tag'] ) {
   echo $_POST["name"] . ', ' . $_POST['tag'];
}
?>
</body>
</html>

實例

import urllib.request
import urllib.parse
url = 'https://www.runoob.com/try/py3/py3_urllib_test.php'  # 提交到表單頁面
data = {'name':'RUNOOB', 'tag' : '菜鳥教程'}   # 提交數據
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'
}   #頭部信息
data = urllib.parse.urlencode(data).encode('utf8')  # 對參數進行編碼,解碼使用 urllib.parse.urldecode
request=urllib.request.Request(url, data, header)   # 請求處理
reponse=urllib.request.urlopen(request).read()      # 讀取結果
fh = open("./urllib_test_post_runoob.html","wb")    # 將文件寫入到當前目錄中
fh.write(reponse)
fh.close()

打開 urllib_test_post_runoob.html 文件(可以使用浏覽器打開),顯示結果如下:


urllib.error

urllib.error 模塊為 urllib.request 所引發的異常定義了異常類,基礎異常類是 URLError。

urllib.error 包含了兩個方法,URLError 和 HTTPError。

URLError 是 OSError 的一個子類,用於處理程序在遇到問題時會引發此異常(或其派生的異常),包含的屬性 reason 為引發異常的原因。

HTTPError 是 URLError 的一個子類,用於處理特殊 HTTP 錯誤例如作為認證請求的時候,包含的屬性 code 為 HTTP 的狀態碼, reason 為引發異常的原因,headers 為導致 HTTPError 的特定 HTTP 請求的 HTTP 響應頭。

對不存在的網頁抓取並處理異常:

實例

import urllib.request
import urllib.error
myURL1 = urllib.request.urlopen("https://www.runoob.com/")
print(myURL1.getcode())   # 200
try:
    myURL2 = urllib.request.urlopen("https://www.runoob.com/no.html")
except urllib.error.HTTPError as e:
    if e.code == 404:
        print(404)   # 404


urllib.parse

urllib.parse 用於解析 URL,格式如下:

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

urlstring 為 字符串的 url 地址,scheme 為協議類型,

allow_fragments 參數為 false,則無法識別片段標識符。相反,它們被解析為路徑,參數或查詢組件的一部分,並 fragment 在返回值中設置為空字符串。

實例

from urllib.parse import urlparse
o = urlparse("https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B")
print(o)

以上實例輸出結果為:

ParseResult(scheme='https', netloc='www.runoob.com', path='/', params='', query='s=python+%E6%95%99%E7%A8%8B', fragment='')

從結果可以看出,內容是一個元組,包含 6 個字符串:協議,位置,路徑,參數,查詢,判斷。

我們可以直接讀取協議內容:

實例

from urllib.parse import urlparse
o = urlparse("https://www.runoob.com/?s=python+%E6%95%99%E7%A8%8B")
print(o.scheme)

以上實例輸出結果為:

https

完整內容如下:

屬性

索引

值(如果不存在)

scheme

0

URL協議

scheme 參數

netloc

1

網絡位置部分

空字符串

path

2

分層路徑

空字符串

params

3

最後路徑元素的參數

空字符串

query

4

查詢組件

空字符串

fragment

5

片段識別

空字符串

username

用戶名

None

password

密碼

None

hostname

主機名(小寫)

None

port

端口號為整數(如果存在)

None


urllib.robotparser

urllib.robotparser 用於解析 robots.txt 文件。

robots.txt(統一小寫)是一種存放於網站根目錄下的 robots 協議,它通常用於告訴搜索引擎對網站的抓取規則。

urllib.robotparser 提供了 RobotFileParser 類,語法如下:

class urllib.robotparser.RobotFileParser(url='')

這個類提供了一些可以讀取、解析 robots.txt 文件的方法:

  • set_url(url) - 設置 robots.txt 文件的 URL。

  • read() - 讀取 robots.txt URL 並將其輸入解析器。

  • parse(lines) - 解析行參數。

  • can_fetch(useragent, url) - 如果允許 useragent 按照被解析 robots.txt 文件中的規則來獲取 url 則返回 True。

  • mtime() -返回最近一次獲取 robots.txt 文件的時間。 這適用於需要定期檢查 robots.txt 文件更新情況的長時間運行的網頁爬蟲。

  • modified() - 將最近一次獲取 robots.txt 文件的時間設置為當前時間。

  • crawl_delay(useragent) -為指定的 useragent 從 robots.txt 返回 Crawl-delay 形參。 如果此形參不存在或不適用於指定的 useragent 或者此形參的 robots.txt 條目存在語法錯誤,則返回 None。

  • request_rate(useragent) -以 named tuple RequestRate(requests, seconds) 的形式從 robots.txt 返回 Request-rate 形參的內容。 如果此形參不存在或不適用於指定的 useragent 或者此形參的 robots.txt 條目存在語法錯誤,則返回 None。

  • site_maps() - 以 list() 的形式從 robots.txt 返回 Sitemap 形參的內容。 如果此形參不存在或者此形參的 robots.txt 條目存在語法錯誤,則返回 None。

實例

>>> import urllib.robotparser
>>> rp = urllib.robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rrate = rp.request_rate("*")
>>> rrate.requests
3
>>> rrate.seconds
20
>>> rp.crawl_delay("*")
6
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved