专业编程基础技术教程

网站首页 > 基础教程 正文

爬虫必备(4)- urllib高级功能使用

ccvgpt 2024-07-23 01:33:23 基础教程 10 ℃

在上一节中,我们使用 urllib 实现了基本的网络请求,可以看到在实现各类网络请求方面,urllib已具备相当出色的功能。

然而urllib的功能远不止于此,除基本的HTTP请求操作之外,它还能够胜任较复杂及高阶的任务,如对cookie和代理服务器的支持。在此过程中,使用urllib内置的强大Handler工具较为关键。该工具内含多种专门的处理器,可用于应对各种特定场景下的情况。其中包括认证处理器Cookie处理器以及代理处理器等等。借助于这些高效的处理器助手,我们可以成功地完成几乎所有可能发生在HTTP请求中的各类相关工作。

爬虫必备(4)- urllib高级功能使用

有哪些Handler?

urllib 中提供了众多的 Handler,专门用来处理各种问题,通过这些处理器,我们几乎可以完成 HTTP 请求的所有的事情。

首先介绍一下urllib.request中BaseHandler 类,它所有其他 Handler 的父类,定义了许多基本的方法。以下是一些常用的 handler 类都继承自此类:

  1. HTTPDefaultErrorHandler: 用于处理 HTTP 响应请求的异常
  2. HTTPRedirectHandler: 用于处理重定向。
  3. HTTPCookieProcessor: 用于处理 Cookies。
  4. ProxHandler: 用于处理代理。
  5. HTTPPasswordMgr:用于处理密码,内部维护了一个密码表
  6. HTTPBasicAuthHandler: 用于权限管理处理

handler虽然用来完成实际的功能,但在使用之前需要构建为Opener才可以发起请求。

Opener

在使用 Handler 之前,还需要了解一个重要的类 OpenerDirector,简称 Opener。之前使用的 request.urlopen()方法,实际上就是一个 Opener。

request.urlopen 只是 urllib 提供的一个经过封装和简化了的请求方法,可以完成基本的请求功能。

Opener 可以使用 open 方法,返回类型和 urlopen 一致,那么如何使用 Opener 呢?就是使用上边提到的 Handler 来构建。以下是一些常用的使用案例。

授权验证

有些网站,在访问过程中需要输入用户名和密码,验证成功后才能正常浏览页面。如果直接访问请求会被拒绝。此时就需要借助 HTTPBasicAuthHandler 来完成相关的验证逻辑,代码如下:

from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener

username = "11"
password = "22"

url = "https://www.httpbin.org/basic-auth/11/22"

# 获取realm类
p = HTTPPasswordMgrWithDefaultRealm()
# 添加用户名和密码
p.add_password(None, url, username, password)
# 构建authHandler
auth_handler = HTTPBasicAuthHandler(p)
# 获取opener
opener = build_opener(auth_handler)
# 访问链接
result = opener.open(url)
# 获取访问内容
print(result.read().decode('utf-8'))

# {
#   "authenticated": true, 
#   "user": "11"
# }

上述代码中, 首先创建了HTTPBasicAuthHandler 对象, 参数是HTTPPasswordMgrWithDefaultRealm 对象, 通过add_password 设置用户名和密码,此时就创建了一个处理授权的 Handler,然后使用 build_opener 构建 Opener,后续使用 Opener 的 open 方法访问网络即可完成验证,并获取到页面的资源。

设置代理

使用代理是爬虫的基本操作,目标网站若发现同一个 IP 有短时大量的请求就会限制访问,通过设置代理可避免封 IP。以下为通过 urllib 设置代理的示例。

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

# 构建代理对象
proxy_handler = ProxyHandler({
     'http': 'http://127.0.0.1:123',
     'https': 'http://127.0.0.1:123'
})

# 构建opener
opener = build_opener(proxy_handler)

# 访问网络
try:
     res = opener.open("http://www.baidu.com")
     print(res.read().decode('utf-8'))
except URLError as e:
     print(e.reason)

上边是一个测试代理, 并使用ProxyHandler 返回一个代理对象, 通过build_opener 构建 Opener 之后,就可以发送请求了。

设置Cookies

Cookies是服务器设置本地内容的重要手段,许多网站会进行Cookies校验。在浏览器中,网站可以通过指令将Cookies保存到浏览器中,后续请求时便可重新读取,以验证用户信息的准确性。下面展示Python如何处理Cookies。

from http import cookiejar
from urllib import request

# 获取用于保存cookie的对象
cookie = cookiejar.CookieJar()
# 生产handler
handler = request.HTTPCookieProcessor(cookie)
# 构建opener
opener = request.build_opener(handler)
# 访问网络
response = opener.open("http://www.baidu.com")

# 访问成功后,
# cookie就被保存到上边cookie对象中
for item in cookie:
    print(item.name, item.value)

# BIDUPSID 1C4FFDD231A033EDCED0A4864E4B7CC8
# PSTM 1704188972
# H_PS_PSSID 39938_39974_40041_40053
# BAIDUID 1C4FFDD231A033EDCED0A4864E4B7CC8:FG=1
# BAIDUID_BFESS 1C4FFDD231A033EDCED0A4864E4B7CC8:FG=1

在获取页面响应的 cookie 时,需要先获取到CookieJar 对象,在通过HTTPCookieProcessor 获取 handler,访问成功后,所有的 cookie 就会被保存到 cookieJar 对象中。

补充内容:保存cookies文件

请求的 Cookies 可以保存为文件,只需要将上边的 Cookies 替换为MozillaCookieJar,此类为 CookieJar 的子类,用于处理文件相关的逻辑,并可以将 cookie 保存为 Mozilla 浏览器格式。

import http.cookiejar
from urllib import request

# 获取Mozilla cookie对象
cookie = http.cookiejar.MozillaCookieJar("baidu_cookies.txt")
# 获取Handler
handler = request.HTTPCookieProcessor(cookie)
# 获取opener
opener = request.build_opener(handler)
opener.open("http://www.baidu.com")
# 保存文件
cookie.save(ignore_discard=True, ignore_expires=True)

运行后,就可以生成以下文件内容。

#文章首发挑战赛# #挑战30天在头条写日记#

Tags:

最近发表
标签列表