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

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

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

当我们研究如何借助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天在头条写日记#

相关推荐

「layui」表单验证:验证注册

注册界面手动验证获取短信验证码代码原文<!DOCTYPEhtml><htmllang="zh"><head>&...

Full text: Joint statement between China and Kenya on creating an inspiring example in the all-weather China-Africa community with a shared future for the new era

JointStatementBetweenthePeople'sRepublicofChinaandtheRepublicofKenyaonCreatinganInspi...

国际组织最新岗位信息送给你

国际刑警组织PostingTitleITLogisticsManagerGrade5DutyStationAbidjan,IvoryCoastDeadlineforApplicatio...

【新功能】Spire.PDF 8.12.5 支持设置表单域的可见与隐藏属性

Spire.PDF8.12.5已发布。该版本新增支持设置表单域的可见与隐藏属性、添加自定义的元数据以及给PDF文档的元数据添加新的命名空间。本次更新还增强了PDF到DOCX和图片的转换...

AI curbs show Biden&#39;s rejection of cooperation

AIcurbsshowBiden'srejectionofcooperation:ChinaDailyeditorial-Opinion-Chinadaily.com.cnT...

“煤气灯效应”上热搜,这几种有毒的“情感关系”也要注意了……

近日,“煤气灯效应”(theGaslightEffect)再次进入公众视野并登上热搜,引发网友广泛关注。那么,什么是“煤气灯效应”?以“爱”之名进行情绪控制在心理学中,通过“扭曲受害者眼中的真实”...

Qt编写推流程序/支持webrtc265/从此不用再转码/打开新世界的大门

一、前言在推流领域,尤其是监控行业,现在主流设备基本上都是265格式的视频流,想要在网页上直接显示监控流,之前的方案是,要么转成hls,要么魔改支持265格式的flv,要么265转成264,如果要追求...

写给运维的Nginx秘籍

要说Web服务器、代理服务器和调度服务器层面,目前使用最大的要数Nginx。对于一个运维工程师日常不可避免要和Nginx打交道。为了更好地使用和管理Nginx,本文就给大家介绍几个虫虫日常常用的秘籍。...

突破亚马逊壁垒,Web Unlocker API 助您轻松获取数据

在数据驱动决策的时代,电商平台的海量数据是十足金贵的。然而,像亚马逊这样的巨头为保护自身数据资产,构建了近乎完美的反爬虫防线,比如IP封锁、CAPTCHA验证、浏览器指纹识别,常规爬虫工具在这些防线面...

每日一库之 logrus 日志使用教程

golang日志库golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别、日志文件分割以及日志分发等方面并没有提供支持.所以催生了很多第三方...

对比测评:为什么AI编程工具需要 Rules 能力?

通义灵码ProjectRules在开始体验通义灵码ProjectRules之前,我们先来简单了解一下什么是通义灵码ProjectRules?大家都知道,在使用AI代码助手的时候,有时...

python 面向对象编程

Python的面向对象编程(OOP)将数据和操作封装在对象中,以下是深度解析和现代最佳实践:一、核心概念重构1.类与实例的底层机制classRobot:__slots__=['...

Windows系统下常用的Dos命令介绍(一)

DOS是英文DiskOperatingSystem的缩写,意思是“磁盘操作系统”。DOS主要是一种面向磁盘的系统软件,说得简单些,DOS就是人给机器下达命令的集合,是存储在操作系统中的命令集。主要...

使用 Flask-Admin 快速开发博客后台管理系统:关键要点解析

一、为什么选择Flask-Admin?Flask-Admin是Flask生态中高效的后台管理框架,核心优势在于:-零代码生成CRUD界面:基于数据库模型自动生成增删改查功能-高度可定制...

Redis淘汰策略导致数据丢失?

想象一下,你的Redis服务器是一个合租宿舍,内存就是床位。当新数据(新室友)要住进来,但床位已满时,你作为宿管(淘汰策略)必须决定:让谁卷铺盖走人?Redis提供了8种"劝退"方案,...