urllib.request 模块
urllib.request模块定义了以下函数:
urllib.request.urlopen(url,data=None, [timeout, ]*,cafile=None,capath=None,cadefault=False,context=None)
参数:
打开url链接,可以是字符串或者是Request对象。
data必须是一个定义了向服务器所发送额外数据的对象,或者如果没有必要数据的话,就是None值。可以查阅Request获取详细信息。
url.request模块在HTTP请求中使用了HTTP/1.1,并且包含了Connection:close头部。
可选的timeout参数指定阻止诸如连接尝试等操作的超时时间(以秒为单位)(如果未指定,将使用全局默认超时设置)。这实际上只适用于HTTP,HTTPS和FTP连接。
如果指定了context,则它必须是描述各种SSL选项的ssl.SSLContext实例。 有关更多详细信息,请参阅HTTPSConnection。
可选的cafile和capath参数为HTTPS请求指定一组可信的CA证书。cafile应指向包含一系列CA证书的单个文件,而capath应指向散列证书文件的目录。 更多信息可以在ssl.SSLContext.load_verify_locations()中找到。
cadefault参数被忽略。
返回值:
该函数总是返回一个可以作为context manager使用的对象,并且具有方法,例如;
geturl()-返回检索的资源的URL,通常用于确定是否遵循重定向;
info()-以email.message_from_string()实例的形式返回页面的元信息(如headers)(可快速参考HTTP Headers);
getcode()-返回响应的HTTP状态码。
对于HTTP和HTTPS URL,此函数返回稍微修改的http.client.HTTPResponse对象。 除上述三种新方法之外,msg属性还包含与reason属性(服务器返回的原因短语)相同的信息,而不是HTTPResponse文档中指定的响应标头。
对于由传统URLopener和FancyURLopener类明确处理的FTP,文件和数据URL和请求,此函数返回一个urllib.response.addinfourl对象。
在协议错误上引发URLError。
请注意,如果没有处理请求的handler,则可能返回None(尽管默认安装的全局OpenerDirector使用UnknownHandler来确保永不发生这种情况)。
另外,如果检测到代理设置(例如,如果设置了诸如http_proxy的* _proxy环境变量),则默认安装ProxyHandler,并确保通过代理处理请求。
import urllib.request
response=urllib.request.urlopen('https://www.python.org')
#请求站点获得一个HTTPResponse对象
#print(response.read().decode('utf-8')) #返回网页内容
#print(response.getheader('server')) #返回响应头中的server值
#print(response.getheaders()) #以列表元祖对的形式返回响应头信息
#print(response.fileno()) #返回文件描述符
#print(response.version) #返回版本信息
#print(response.status) #返回状态码200,404代表网页未找到
#print(response.debuglevel) #返回调试等级
#print(response.closed) #返回对象是否关闭布尔值
#print(response.geturl()) #返回检索的URL
#print(response.info()) #返回网页的头信息
#print(response.getcode()) #返回响应的HTTP状态码
#print(response.msg) #访问成功则返回ok
#print(response.reason) #返回状态信息
# 按行读取
# print(response.readline())# 读取一行
# print(response.readline()) # 读取下一行
# print( response.readlines()) # 读取多行。得到一个列表 每个元素是一行
使用案例
1、简单读取网页信息
import urllib.request
response =urllib.request.urlopen('http://python.org/')
html =response.read()
2、使用request
urllib.request.Request(url, data=None, headers={}, method=None)
使用request()来包装请求,再通过urlopen()获取页面。
import urllib.request
req =urllib.request.Request('http://python.org/')
response =urllib.request.urlopen(req)
the_page =response.read()
3、发送数据,以登录知乎为例
import gzip
import re
import urllib.request
import urllib.parse
import http.cookiejar
defung zip(data):
try:
print("尝试解压缩...")
data =gzip.decompress(data)
print("解压完毕")
except:
print("未经压缩,无需解压")
returndata
def getXSRF(data):
cer =re.compile('name=\"_xsrf\" value=\"(.*)\"',flags =0)
strlist =cer.findall(data)
return strlist[0]
def getOpener(head):
# cookies 处理
cj =http.cookiejar.CookieJar()
pro =urllib.request.HTTPCookieProcessor(cj)
opener =urllib.request.build_opener(pro)
header =[]
forkey,value inhead.items():
elem =(key,value)
header.append(elem)
opener.addheaders =header
returnopener
# header信息可以通过firebug获得
header ={
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0',
'Accept-Encoding': 'gzip, deflate',
'Host': 'www.zhihu.com',
'DNT': '1'
}
url ='http://www.zhihu.com/'
opener =getOpener(header)
op =opener.open(url)
data =op.read()
data =ungzip(data)
_xsrf =getXSRF(data.decode())
url +="login/email"
email ="登录账号"
password ="登录密码"
postDict ={
'_xsrf': _xsrf,
'email': email,
'password': password,
'rememberme': 'y'
}
postData =urllib.parse.urlencode(postDict).encode()
op =opener.open(url,postData)
data =op.read()
data =ungzip(data)
print(data.decode())
4、http错误
import urllib.request
req =urllib.request.Request('http://www.lz881228.blog.163.com')
try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
print(e.code)
print(e.read().decode("utf8"))
5、异常处理
from urllib.request importRequest, urlopen
from urllib.error importURLError, HTTPError
req =Request("http://www.abc.com/")
try:
response =urlopen(req)
except HTTPError as e:
print('The server couldn't fulfill the request.')
print('Error code: ', e.code)
except URLError as e:
print('We failed to reach a server.')
print('Reason: ', e.reason)
else:
print("good!")
print(response.read().decode("utf8"))
6、http认证
import urllib.request
# create a password manager
password_mgr =urllib.request.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of None.
top_level_url ="https://www.jb51.net/"
password_mgr.add_password(None, top_level_url, 'rekfan', 'xxxxxx')
handler =urllib.request.HTTPBasicAuthHandler(password_mgr)
# create "opener" (OpenerDirector instance)
opener =urllib.request.build_opener(handler)
# use the opener to fetch a URL
a_url ="https://www.jb51.net/"
x =opener.open(a_url)
print(x.read())
# Install the opener.
# Now all calls to urllib.request.urlopen use our opener.
urllib.request.install_opener(opener)
a =urllib.request.urlopen(a_url).read().decode('utf8')
print(a)
7、使用代理
import urllib.request
proxy_support =urllib.request.ProxyHandler({'sock5': 'localhost:1080'})
opener =urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)
a =urllib.request.urlopen("http://www.baidu.com").read().decode("utf8")
print(a)
8、超时
import socket
import urllib.request
# timeout in seconds
timeout = 2
socket.setdefaulttimeout(timeout)
# this call to urllib.request.urlopen now uses the default timeout
# we have set in the socket module
req = urllib.request.Request('//www.jb51.net /')
a = urllib.request.urlopen(req).read()
print(a)
import urllib.request
response = urllib.request.urlopen("https://httpbin.org/get",timeout=1)
print(response.read().decode("utf-8"))