urlopen方法
打開指定的URL
urllib.request.urlopen(url, data=None, [timeout, ]*,
cafile=None, capath=None, cadefault=False, context=None)
url參數,可以是一個string,或者一個Request對象。
data一定是bytes對象,傳遞給服務器的數據,或者為None。目前只有HTTP requests會使用data,提供data時會是一個post請求,如若沒有data,那就是get請求。data在使用前需要使用urllib.parse.urlencode()函數轉換成流數據。
from urllib import request
resp=request.urlopen('http://www.baidu.com')
print(type(resp))
#可以看出,urlopen返回的是一個HTTPResponse對象
<class 'http.client.HTTPResponse'>
print(dir(resp))
#resp具有的方法和屬性如下,我們最常用的是read和readline
['__abstractmethods__', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_abc_cache', '_abc_negative_cache', '_abc_negative_cache_version', '_abc_registry', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_check_close', '_close_conn', '_get_chunk_left', '_method', '_peek_chunked', '_read1_chunked', '_read_and_discard_trailer', '_read_next_chunk_size', '_read_status', '_readall_chunked', '_readinto_chunked', '_safe_read', '_safe_readinto', 'begin', 'chunk_left', 'chunked', 'close', 'closed', 'code', 'debuglevel', 'detach', 'fileno', 'flush', 'fp', 'getcode', 'getheader', 'getheaders', 'geturl', 'headers', 'info', 'isatty', 'isclosed', 'length', 'msg', 'peek', 'read', 'read1', 'readable', 'readinto', 'readinto1', 'readline', 'readlines', 'reason', 'seek', 'seekable', 'status', 'tell', 'truncate', 'url', 'version', 'will_close', 'writable', 'write', 'writelines']
Request類
URL請求的抽象類。
urllib.request.Request(url, data=None, headers={},
origin_req_host=None, unverifiable=False, method=None)
Example
import urllib.request
with urllib.request.urlopen("http://www.baidu.com") as f:
print(f.read(300))
#最簡單的打開一個url的方法
#由於urlopen無法判斷數據的encoding,所以返回的是bytes對象。一般會對返回的數據進行decode。
b'<!DOCTYPE html><html lang="zh-cmn-Hans"><head> <meta charset="UTF-8"> <title>\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\xa5\xe9\x81\x93</title> <script type="text/javascript" src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script></head><body></body></html><script type="text/javascript">var urlNum="96659328_s_ha'
with urllib.request.urlopen("http://www.python.org") as f:
print(f.read(500).decode('utf-8'))
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 lt-ie8 lt-ie9"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" lang="en" dir="ltr"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="prefetch" href="//ajax.googleapis.com/ajax/libs/jqu
#如果想要檢索URL資源,並將其保存到一個臨時位置,可以使用urlretrieve函數
import urllib.request
local_filename,headers=urllib.request.urlretrieve('http://www.baidu.com')
print(local_filename)
print(headers)
C:\Users\張名昊\AppData\Local\Temp\tmpgvshi0fc
Content-Type: text/html; charset=utf-8
Content-Length: 561
Cache-Control: no-cache
Set-Cookie: jdERAezKGXbgHHHMMBwTrqQ=1;max-age=20;
Connection: close
#urlopen還可以接受Request對象,推薦使用這種方法,因為可以對Request對象進行深度的定制,不僅僅傳入一個URL
import urllib.request
req=urllib.request.Request('http://www.baidu.com')
with urllib.request.urlopen(req) as response:
page=response.read(300).decode('utf-8')#我們獲取的數據一般是ascii的,decode成utf-8.
print(page)
<!DOCTYPE html><html lang="zh-cmn-Hans"><head> <meta charset="UTF-8"> <title>百度一下,你就知道</title> <script type="text/javascript" src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script></head><body></body></html><script type="text/javascript">var urlNum="95855586_s_ha
Data
有時候,我們想想一個URL發送一些數據,一般使用POST請求,不過數據需要encode,然后傳遞給Request對象。encoding一般由urllib.parse庫的函數實現。
import urllib.parse as up
import urllib.request as ur
url='http://www.baidu.com'
values={
'name':'ZhangMinghao',
'location':'Shanghai',
'language':'Python3'
}
data=up.urlencode(values)
data=data.encode('ascii')#data應該是bytes,所以上傳給server時需要轉換成ascii數據。
req=ur.Request(url,data)
with ur.urlopen(req) as response:
page=response.read()
如果我們不想使用data參數,那么使用GET請求,將data內容與url連接到一起,發送到server。
import urllib.request
import urllib.parse
data={
'name':'ZhangMinghao',
'location':'Shanghai',
'language':'Python3'
}
url_values=urllib.parse.urlencode(data)
print(url_values)
url='http://www.baidu.com'
full_url=url+'?'+url_values
response=urllib.request.urlopen(full_url)
name=ZhangMinghao&location=Shanghai&language=Python3
Headers
有些網頁不希望被程序訪問,或者向不同的瀏覽器發送不同的內容。默認的urllib識別為Python-urllib/3.5,可能使server感到疑惑或者返回內容出錯。可以通過設置User-Agent來設置我們程序的瀏覽器識別碼,創建Request對象時,出入一個header的字典。
import urllib.parse
import urllib.request
url='http://www.baidu.com'
user_agent='Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
values={
'name':'ZhangMinghao',
'location':'Shanghai',
'language':'Python3'
}
headers={'User-Agent':user_agent}
data=urllib.parse.urlencode(values)
data=data.encode('ascii')
request=urllib.request.Request(url,data,headers)
with urllib.request.urlopen(req) as response:
the_page = response.read()
處理錯誤
urllib.error模塊中包含了相關的各種錯誤。
URLError,HTTPError等
URLError一般是因為沒有網絡連接或者server不存在。這種情況下,會產生一個reason屬性,是一個tuple,包含了錯誤碼和錯誤文本
import urllib.error
req=urllib.request.Request('http://www.pretend_server.com')
try: urllib.request.urlopen(req)
except urllib.error.URLError as e:
print(e.reason)
[Errno 11001] getaddrinfo failed
HTTPError
每個http請求都會返回一個狀態碼,一般處理程序會處理某些狀態嗎,但是有一些處理不了,就會返回HTTPError,比如404找不到頁面,403請求被禁止,401請求授權。不展開講其他錯誤碼了。
info和geturl
urllib.response模塊
geturl返回真正訪問的URL地址。
info,返回一個類似字典的對象,來描述獲取的對象,尤其是headers。
import urllib.request
resp=urllib.request.urlopen('http://www.baidu.com')
print(resp.info())
Content-Type: text/html; charset=utf-8
Content-Length: 561
Cache-Control: no-cache
Set-Cookie: tSMHvfupnLIgHHHMVijdstJ=1;max-age=20;
Connection: close
還有其他的幾個概念,比如授權,代理等,用到的時候再詳細講。
如果您覺得感興趣的話,可以添加我的微信公眾號:一步一步學Python

