百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

爬虫必备(3)- urllib基础超级详解

zhezhongyun 2025-03-10 22:33 47 浏览

当我们研究如何借助Python来实现网络连接与操作时,往往可以发现许多参考书籍以及文献均会推荐采用第三方套件requests以完成此项工作。诚然,requests的众多优点使得其成为了当今Python环境中进行HTTP请求的事实上的行业标准。然而,值得注意的是,Requests实际上是由Python自行开发并基于urllib模块实现的。因此,在实际运用这一三方库前,深入理解Python原生的请求发送库urllib及其运作流程和应用技巧无疑是十分必要的。

Python

urllib作为Python的一项标准库,其主要功能在于管理和处理URL地址,同时也负责进行网络通讯。这个库内含多个子模块,各自承担着不同的任务,例如用于打开和读取URL地址、处理URL地址的异常状况、对URL地址进行解析等等。作为一款内置的HTTP请求库,并不需要事先进行任何额外的安装便可立即投入使用。

网络执行流程

urllib中包含有四大模块用以满足不同的需求:

1. request模块:该模块主要用于发起各类请求,从而构成了一个最基础的HTTP请求核心部分;

2. error模块:顾名思义,这个模块专门用于处理在请求过程中共有的异常情况,并为之后可能发生的行为作出预设,如允许重试;

3. parse模块:作为一种工具型模块,提供了许多实用有效的URL处理方法,包括分割、解析等多种操作;

4. robotparser模块:针对网站的robots.txt文件(即网络君子协议)进行分析和解构。

发送请求(基础请求)

urllib库中request模块提供了构建HTTP请求请求的基本方法,并且还具备处理授权验证、重定向、cookies等浏览器功能的功能。以下是该模块的基础使用方式:

from urllib import request

# 使用urlopen访问地址
# 响应结果为HTTPResponse
res = request.urlopen("https://www.baidu.com")
print(res)

# 可以获取到百度页面的内容
# 

通过request.urlopen 方法即可获取指定网址的内容,返回的内容被包装到了HTTPResponse 类中

在使用 urlopen 时还可以指定其他参数:

request.urlopen(url, # 访问地址
                data=None, # 参数
                [timeout]*, # 超时时间
                cafile=None, # CA证书
                capath=None, # CA证书路径
                cadefault=False,  # 已弃用
                context=None  # 用来设置ssl
               )
  1. data: 可选参数,用来添加访问参数,需要注意的是,只要 data 有值,则请求自动改为 post。同时 data 参数需要做字节流转换。如下使用
from urllib import request, parse

data = {
    'country': 'China'
}
# 将data转为字节流
data = parse.urlencode(data).encode('utf-8')
res = request.urlopen('http://httpbin.org/post', data=data)
print(res)
# 
  1. timeout: 可选参数,用于设置请求超时时间,单位为秒,如果请求在指定的时间内没有返回响应信息,则抛出异常。
  2. context: 可选参数,必须是 ssl.SSLContext 类型,指定 SSL 设置。
  3. cafile capath 参数分别用来指定 CA 证书和路径,一般用于 HTTPS 链接
  4. cadefault 已被弃用,默认为 False。

Request 请求对象(复杂请求对象)

对于简单的请求,我们可以直接使用urlopen发起请求。然而,在实际的网络中,一次完整的请求往往需要许多参数,如添加请求头(Headers)、cookies等,这就需要我们借助Request对象来构建请求

req = request.Request(
    url, 
    data=None, 
    headers={}, 
    origin_req_host=None, 
    unverifiable=False, 
    method=None)
  1. url: 为必传参数,用于请求的 URL 地址
  2. data: 为选填字段,必须传入 bytes 类型,如果为字典则需要使用parse.urlencode 进行编码
  3. headers:为选填参数,类型是一个字典,在构造请求时指定 headers 参数,也可以通过实例 add_header 方法添加。
  4. origin_req_host:用于指定请求方 host 或 IP 地址。
  5. unverifiable: 用于表示请求是否无法验证,默认为 False,指的是用户没有足够权限来选择接收这个请求的结果。
  6. method:用于指定请求类型,如 GET,POST 和 PUT 等。

使用示例:

from urllib import request, parse

# 请求地址
url = "http://httpbin.org/post"

# 构造请求头
headers = {
    "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 Edg/120.0.0.0",
    "Host": "httpbin.org"
}

# 构造请求数据
data = {
    "country": "china"
}

# 构造Request对象,并编码data数据
req = request.Request(url=url, 
                      # data数据要转为字节(byte)类型
                      data=parse.urlencode(data).encode("utf-8"), 
                      headers=headers, 
                      method="POST")
# urlopen接收Request对象
res = request.urlopen(req)

print(res.read().decode('utf-8'))

HTTPResponse 响应对象

请求成功后,Python会将响应结果封装到HTTPResponse对象中。了解此对象可使我们更熟练地从响应结果中获取数据。该对象提供了许多方法和属性,用于获取响应结果的状态和内容以下代码示例)。

from urllib import request

# 使用urlopen访问地址
# 响应结果为HTTPResponse
res = request.urlopen("https://www.baidu.com")

# 获取http协议版本号,10->1.0, 11-> 1.1
print(res.version)

# 获取响应码
print(res.status)
print(res.getcode())

# 响应描述字符
print(res.reason)

# 获取实际请求页面(用于校验是否重定向)
print(res.geturl())

# 获取所有头信息,返回为元组列表
print(res.getheaders())

# 获取指定头信息
print(res.getheader("host"))

# 获取响应头信息
print(res.info())

# 获取响应结果内容, 
print(res.read().decode("utf-8"))
print(res.readline())
print(res.readlines())

需要注意的是 响应体如果是可以被缓存的内容如“application/gzip”,则可以多次调用来获取,但是如果内容为text/html类型,因为响应内容为流式数据,则只能调用一次来获取内容,后续虽然可以再次调用,但无法读取到任何内容,如果确实有需求做多次内容读取,可以使用 BytesIO 等工具在内存中将响应结果数据做缓存,后续即可多次读取

异常处理

网络请求并非总是可以成功响应,在某些条件下可能会导致请求失败,因此处理异常也是非常有必要的。在 urllib 中使用 error 模块来定义 request 所产的的异常。主要有以下 2 个

  1. URLError(基础异常类)

URLError 类是 error 异常模块的基础错误,所有 request 产生的异常都可以通过捕获此类来处理,并通过 reason 属性来获取返回的错误内容。

try:
    # 访问一个不存在的网址
    request.urlopen("http://www.coasdfla.com")
except error.URLError as e:
    print(e.reason)

# [Errno 11001] getaddrinfo failed
  1. HTTPError

HTTPError 是 URLError 的子类, 用来处理 HTTP 请求的错误,比如 404 网页不存在,500 服务器异常等。HTTPError 有 3 个属性,code:获取 http 状态码,reason:返回错误信息,headers:返回请求头

try:
    # 访问一个不存在的资源
    request.urlopen("http://www.baidu.com/i.html")
except error.HTTPError as e:
    print(e.reason)

# Not Found
    
# 404
    
# Content-Length: 204
# Content-Type: text/html; charset=iso-8859-1
# Date: Tue, 02 Jan 2024 07:47:04 GMT
# Server: Apache
# Set-Cookie: BAIDUID=762B2AF189BFC59272CB9C1CE5DBAF0F:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000
# Set-Cookie: BAIDUID_BFESS=762B2AF189BFC59272CB9C1CE5DBAF0F:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None
# Connection: close

在实际的开发中,应遵循一个原则:请求异常的捕获应先小后大的原则,依次处理

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

相关推荐

Go语言标准库中5个被低估的强大package

在Go语言的世界里,开发者们往往对fmt、net/http这些“明星包”耳熟能详,却忽略了标准库里藏着的一批“宝藏工具”。它们功能强大却低调内敛,能解决并发控制、内存优化、日志管理等核心问题。今天就带...

作为测试人,如何优雅地查看Log日志?

作为一名测试工程师,测试工作中和Linux打交道的地方有很多。比如查看日志、定位Bug、修改文件、部署环境等。项目部署在Linux上,如果某个功能发生错误,就需要我们去排查出错的原因,所以熟练地掌握查...

Java 从底层与接口实现了解String、StringBuffer、StringBuilder

String、StringBuffer和StringBuilder的接口实现关系:String:字符串常量,字符串长度不可变。Java中String是immutable(不可变)的。用于存放字符...

FluentData 从入门到精通:C#.NET 数据访问最佳实践

简介FluentData是一个微型ORM(micro-ORM),主打「FluentAPI」风格,让开发者在保持对原生SQL完全控制的同时,享受链式调用的便捷性。它与Dapper、Massi...

团队协作-代码格式化工具clang-format

环境:clang-format:10.0.0前言统一的代码规范对于整个团队来说十分重要,通过git/svn在提交前进行统一的ClangFormat格式化,可以有效避免由于人工操作带来的代码格式问题。C...

C# 数据操作系列 - 15 SqlSugar 增删改查详解(超长篇)

0.前言继上一篇,以及上上篇,我们对SqlSugar有了一个大概的认识,但是这并不完美,因为那些都是理论知识,无法描述我们工程开发中实际情况。而这一篇,将带领小伙伴们一起试着写一个能在工程中使用的模...

Mac OS 下 Unix 使用最多的100条命令(收藏级)

MacOS内置基于Unix的强大终端(Terminal),对开发者、运维工程师和日常用户来说,掌握常用的Unix命令是提升效率的关键。本文整理了100条在MacOS下最常用的U...

C语言字符串操作总结大全(超详细)

C语言字符串操作总结大全(超详细)1)字符串操作strcpy(p,p1)复制字符串strncpy(p,p1,n)复制指定长度字符串strcat(p,p1)附加字符串strncat...

经常使用到开源的MySQL,今天我们就来系统地认识一下

作为程序员,我们在项目中会使用到许多种类的数据库,根据业务类型、并发量和数据要求等选择不同类型的数据库,比如MySQL、Oracle、SQLServer、SQLite、MongoDB和Redis等。今...

电脑蓝屏代码大全_电脑蓝屏代码大全及解决方案

0X0000000操作完成0X0000001不正确的函数0X0000002系统找不到指定的文件0X0000003系统找不到指定的路径0X0000004系统无法打开文件0X0000005拒绝...

8个增强PHP程序安全的函数_php性能优化及安全策略

安全是编程非常重要的一个方面。在任何一种编程语言中,都提供了许多的函数或者模块来确保程序的安全性。在现代网站应用中,经常要获取来自世界各地用户的输入,但是,我们都知道“永远不能相信那些用户输入的数据”...

css优化都有哪些优化方案_css性能优化技巧

CSS优化其实可以分成几个层面:性能优化、可维护性优化、兼容性优化以及用户体验优化。这里我帮你梳理一份比较系统的CSS优化方案清单,方便你参考:一、加载性能优化减少CSS文件体积压缩CSS...

筹划20年,他终于拍成了这部电影_筹划20年,他终于拍成了这部电影英语

如果提名好莱坞最难搞影星,你第一时间会联想到谁?是坏脾气的西恩·潘,还是曾因吸毒锒铛入狱的小罗伯特·唐尼,亦或是沉迷酒精影响工作的罗素·克劳?上述大咖,往往都有着这样或那样的瑕疵。可即便如此,却都仍旧...

Keycloak Servlet Filter Adapter使用

KeycloakClientAdapters简介Keycloakclientadaptersarelibrariesthatmakeitveryeasytosecurea...

一些常用的linux常用的命令_linux常用命令有哪些?

在Linux的世界里,命令是与系统交互的基础。掌握常用命令不仅能让你高效地管理文件、进程和网络,还能为你进一步学习系统管理和自动化打下坚实的基础。本文将深入探讨一些最常用且功能强大的Linux...