urllib.request模板的高级用法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/85939449

一 urllib.request的各种Handler

Handler简而言之,我们可以把它理解为各种处理器,有专门处理登录验证的,有处理Cookies的,有处理代理设置的。利用它们,我们几乎可以做到HTTP请求中所有的事情。

首先,介绍一下urllib.request模块里的BaseHandler类,它是所有其他Handler的父类,它提供了最基本的方法,例如default_open()、protocol_request()等。各种Handler子类继承这个BaseHandler类。

  • HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常。

  • HTTPRedirectHandler:用于处理重定向。

  • HTTPCookieProcessor:用于处理Cookies。

  • ProxyHandler:用于设置代理,默认代理为空。

  • HTTPPasswordMgr:用于管理密码,它维护了用户名和密码的表。

  • HTTPBasicAuthHandler:用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。

二 OpenerDirector介绍

OpenerDirector,我们可以称为Opener。我们之前用过urlopen()这个方法,实际上它就是urllib为我们提供的一个Opener。

那么,为什么要引入Opener呢?因为需要实现更高级的功能。之前使用的Request和urlopen()相当于类库为你封装好了极其常用的请求方法,利用它们可以完成基本的请求,但是现在不一样了,我们需要实现更高级的功能,所以需要深入一层进行配置,使用更底层的实例来完成操作,所以这里就用到了Opener。

Opener可以使用open()方法,返回的类型和urlopen()如出一辙。那么,它和Handler有什么关系呢?简而言之,就是利用Handler来构建Opener。

三 验证

1 场景

有些网站在打开时就会弹出提示框,直接提示你输入用户名和密码,验证成功后才能查看页面,例如:

2 代码举例

from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError

username = 'username'
password = 'password'
url = 'http://localhost:8000/account/my-information/'

p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
# 这里首先实例化HTTPBasicAuthHandler对象,其参数是HTTPPasswordMgrWithDefaultRealm对象,
# 它利用add_password()添加进去用户名和密码,这样就建立了一个处理验证的Handler。
auth_handler = HTTPBasicAuthHandler(p)
# 利用这个Handler并使用build_opener()方法构建一个Opener,这个Opener在发送请求时就相当于已经验证成功了。
opener = build_opener(auth_handler)

try:
    # 利用Opener的open()方法打开链接,就可以完成验证了。这里获取到的结果就是验证后的页面源码内容。
    result = opener.open(url)
    html = result.read().decode('utf-8')
    print(html)
except URLError as e:
    print(e.reason)

四 代理

1 点睛

在做爬虫的时候,免不了要使用代理,如果要添加代理,可以像下面这样做。

2 代码

from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener

# 这里使用了ProxyHandler,其参数是一个字典,
# 键名是协议类型(比如HTTP或者HTTPS等),键值是代理链接,可以添加多个代理。
proxy_handler = ProxyHandler({
    # 这里我们在本地搭建了一个代理,它运行在8000端口上
    'http': 'http://127.0.0.1:8000',
    'https': 'https://127.0.0.1:8000'
})
# 利用这个Handler及build_opener()方法构造一个Opener,之后发送请求即可
opener = build_opener(proxy_handler)
try:
    response = opener.open('https://www.baidu.com')
    print(response.read().decode('utf-8'))
except URLError as e:
    print(e.reason)

五 Cookies

1 获取网站Cookies

1.1 代码

import http.cookiejar, urllib.request
# 必须声明一个CookieJar对象。
cookie = http.cookiejar.CookieJar()
# 利用HTTPCookieProcessor来构建一个Handler
handler = urllib.request.HTTPCookieProcessor(cookie)
# 利用build_opener()方法构建出Opener
opener = urllib.request.build_opener(handler)
# 执行open()函数即可
response = opener.open('http://www.baidu.com')
for item in cookie:
    print(item.name + "=" + item.value)

1.2 执行结果

E:\WebSpider\venv\Scripts\python.exe E:/WebSpider/3_1_1.py
BAIDUID=80E7B05274F7644E00E3FA0142947F25:FG=1
BIDUPSID=80E7B05274F7644E00E3FA0142947F25
H_PS_PSSID=1454_21089_28205_28132_28267_28139
PSTM=1546766806
delPer=0
BDSVRTM=0
BD_HOME=0

2 将Cookies保存成文本

2.1 代码

import http.cookiejar, urllib.request
filename = 'cookies.txt'
# 这时CookieJar就需要换成MozillaCookieJar,它在生成文件时会用到,是CookieJar的子类,
# 可以用来处理Cookies和文件相关的事件,比如读取和保存Cookies,可以将Cookies保存成Mozilla型浏览器的Cookies格式。
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

2.2 生成文件内容如下

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file!  Do not edit.

.baidu.com    TRUE    /    FALSE    3694250720    BAIDUID    18FC099E164E6C0B70DA82B6B1BB27F1:FG=1
.baidu.com    TRUE    /    FALSE    3694250720    BIDUPSID    18FC099E164E6C0B70DA82B6B1BB27F1
.baidu.com    TRUE    /    FALSE        H_PS_PSSID    1426_21125_28205_28132_26350_28267_28139
.baidu.com    TRUE    /    FALSE    3694250720    PSTM    1546767074
.baidu.com    TRUE    /    FALSE        delPer    0
www.baidu.com    FALSE    /    FALSE        BDSVRTM    0
www.baidu.com    FALSE    /    FALSE        BD_HOME    0

3 将Cookies保存成LWP格式

3.1 代码

import http.cookiejar, urllib.request
filename = 'cookies1.txt'
# 文件保存成LWP格式的Cookies文件
cookie = http.cookiejar.LWPCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

3.2 生成文件内容如下

#LWP-Cookies-2.0
Set-Cookie3: BAIDUID="09D84C55FF9E09D21860188E0987C4AD:FG=1"; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2087-01-24 12:49:12Z"; version=0
Set-Cookie3: BIDUPSID=09D84C55FF9E09D21860188E0987C4AD; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2087-01-24 12:49:12Z"; version=0
Set-Cookie3: H_PS_PSSID=1425_21106_18560_28206_28132_26350_28266_28140_27509; path="/"; domain=".baidu.com"; path_spec; domain_dot; discard; version=0
Set-Cookie3: PSTM=1546767306; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2087-01-24 12:49:12Z"; version=0
Set-Cookie3: delPer=0; path="/"; domain=".baidu.com"; path_spec; domain_dot; discard; version=0
Set-Cookie3: BDSVRTM=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0
Set-Cookie3: BD_HOME=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0

4 利用生成了Cookies文件

import http.cookiejar, urllib.request
cookie = http.cookiejar.LWPCookieJar()
# 这里调用load()方法来读取本地的Cookies文件,
# 获取到了Cookies的内容。不过前提是我们首先生成了LWPCookieJar格式的Cookies,
# 并保存成文件,然后读取Cookies之后使用同样的方法构建Handler和Opener即可完成操作。
cookie.load('cookies1.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
# 运行结果正常的话,会输出百度网页的源代码。
print(response.read().decode('utf-8'))

猜你喜欢

转载自blog.csdn.net/chengqiuming/article/details/85939449