网络爬虫【爬虫库urllib】

news2025/3/19 18:29:04

  我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步

今天来讲一讲爬虫

urllib介绍

Urllib是Python自带的标准库,无须安装,直接引用即可。

Urllib是一个收集几个模块来使用URL的软件包,大致具备以下功能。
● urllib.request:用于打开和读取URL。
● urllib.error:包含提出的例外urllib.request。
● urllib.parse:用于解析URL。
● urllib.robotparser:用于解析robots.txt文件。

发送请求

`urllib.request.urlopen`是 Python 中`urllib`模块的一个函数,用于打开和读取网络资源。以下是关于`urlopen`的语法和参数的详细说明:

语法

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

参数解释

1. url

• 含义:需要访问的网络资源的 URL 地址。

• 要求:URL 格式必须完整,包括协议(如`http://`或`https://`)。例如:

url = "https://movie.douban.com"


 • 错误示例:如果省略协议,如只写`movie.douban.com`,程序会提示无法识别 URL 的错误。
2. data

• 含义:用于发送请求的数据。

• 默认值:`None`。

• 请求方式:

• 如果`data`为`None`,则表示发送的是 GET 请求。

• 如果`data`不为`None`,则表示发送的是 POST 请求。

• 数据格式:`data`必须是字节类型(`bytes`),通常需要将字典通过`urllib.parse.urlencode()`转换为字符串,再用`encode()`转换为字节。例如:
 

import urllib.parse
data = {"key": "value"}
data = urllib.parse.urlencode(data).encode("utf-8")

3. timeout

• 含义:设置请求的超时时间(以秒为单位)。

• 默认值:未设置超时时间时,程序会一直等待,直到请求完成或发生错误。

• 作用:避免程序因网络延迟或服务器无响应而无限等待。例如:

response = urllib.request.urlopen(url, timeout=10)  # 超时时间为10秒

4. cafile

• 含义:指定用于验证服务器证书的 CA 证书文件路径。

• 默认值:`None`。

• 作用:在使用 HTTPS 请求时,用于验证服务器的身份。如果未指定,Python 会使用系统默认的 CA 证书。


5. capath

• 含义:指定包含 CA 证书的目录路径。

• 默认值:`None`。

• 作用:与`cafile`类似,但指定的是一个目录,而不是单个文件。


6. cadefault

• 含义:已废弃,不应使用。


7. context

• 含义:用于配置 SSL 上下文,通常用于 HTTPS 请求。

• 默认值:`None`。

• 作用:可以自定义 SSL 设置,例如禁用证书验证(不推荐,可能不安全)。例如:

import ssl
context = ssl._create_unverified_context()  # 禁用证书验证
response = urllib.request.urlopen(url, context=context)

示例代码

import urllib.request
import urllib.parse

# 示例:发送 GET 请求
url = "https://movie.douban.com"
response = urllib.request.urlopen(url)
print(response.read())  # 读取响应内容

# 示例:发送 POST 请求
data = {"key": "value"}
data = urllib.parse.urlencode(data).encode("utf-8")
response = urllib.request.urlopen(url, data=data)
print(response.read())  # 读取响应内容

注意事项

• 在使用`urlopen`时,需要确保 URL 格式正确,否则会引发`ValueError`或其他异常。

• 如果需要处理异常,可以使用`try-except`块捕获错误,例如超时或网络错误。

• 对于 HTTPS 请求,建议使用默认的证书验证,以确保安全。

 

更灵活的请求

`urllib.request.Request`是 Python 的`urllib`模块中用于创建 HTTP 请求对象的类。通过这个类,可以自定义请求头(headers)、请求方法(method)等信息,从而实现更灵活的网络请求。以下是关于`urllib.request.Request`的语法和参数的详细说明:
---

语法

urllib.request.Request(url, data=None, headers={}, method=None, origin_req_host=None, unverifiable=False, *, method=None)

---

参数解释

1. url

• 含义:需要访问的网络资源的 URL 地址。

• 要求:必须是完整的 URL,包括协议(如`http://`或`https://`)。例如:

url = "https://movie.douban.com"

• 作用:指定请求的目标地址。

2. data

• 含义:请求的附加数据。

• 默认值:`None`。

• 请求方式:

• 如果`data`为`None`,则默认为 GET 请求。

• 如果`data`不为`None`,则为 POST 请求。

• 数据格式:`data`必须是字节类型(`bytes`)。通常需要将字典通过`urllib.parse.urlencode()`转换为字符串,再用`encode()`转换为字节。例如:
 

import urllib.parse
data = {"key": "value"}
data = urllib.parse.urlencode(data).encode("utf-8")

3. headers

• 含义:自定义的 HTTP 请求头信息。

• 默认值:`{}`(空字典)。

• 作用:通过设置请求头,可以模拟浏览器的行为,绕过某些网站的反爬虫机制,或者添加必要的认证信息。例如:

headers = {
         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
         "Accept-Language": "en-US,en;q=0.9"
     }


• 常见请求头字段:

• `User-Agent`:标识客户端的软件版本。

• `Accept-Language`:指定客户端的语言偏好。

• `Referer`:标识请求的来源页面。

• `Content-Type`:指定请求体的格式(如`application/json`或`application/x-www-form-urlencoded`)。


4. method

• 含义:显式指定请求方法(如 GET、POST、PUT、DELETE 等)。

• 默认值:根据`data`参数自动判断(`data=None`时为 GET,否则为 POST)。

• 作用:允许显式指定请求方法,避免依赖`data`参数来判断。例如:
 

request = urllib.request.Request(url, method="GET")

5. origin_req_host

• 含义:指定请求的来源主机名或 IP 地址。

• 默认值:`None`。

• 作用:用于某些特定的 HTTP/1.1 请求,通常不需要手动设置。


6. unverifiable

• 含义:标记请求是否为不可验证的请求。

• 默认值:`False`。

• 作用:用于某些特定的 HTTP/1.1 请求,通常不需要手动设置。


---示例代码
以下是一个使用`urllib.request.Request`设置请求头的完整示例:

import urllib.request
import urllib.parse

# 目标 URL
url = "https://movie.douban.com"

# 自定义请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Accept-Language": "en-US,en;q=0.9"
}

# 创建 Request 对象
request = urllib.request.Request(url, headers=headers)

# 发送请求
response = urllib.request.urlopen(request)

# 读取响应内容
print(response.read().decode("utf-8"))

注意事项

1. 请求头的重要性:某些网站会根据请求头中的信息(如`User-Agent`)判断请求是否来自合法的客户端。如果请求头设置不当,可能会被拒绝访问。

2. 数据编码:如果发送 POST 请求,`data`必须是字节类型。可以通过`urllib.parse.urlencode()`和`encode()`方法进行转换。

3. 显式指定方法:虽然`method`参数可以显式指定请求方式,但通常情况下,通过`data`参数来区分 GET 和 POST 请求已经足够。

通过`urllib.request.Request`,可以更灵活地控制 HTTP 请求的细节,从而实现更复杂的网络交互。

代理IP

原理

代理IP的原理:以本机先访问代理IP,再通过代理IP地址访问互联网,这样网站(服务器)接收到的访问IP就是代理IP地址。

以下是关于通过`urllib.request.ProxyHandler`动态设置 IP 池以及常见错误的描述:


---

动态设置 IP 池


在使用`urllib`进行网络请求时,可以通过`urllib.request.ProxyHandler`动态设置 IP 池,以实现代理请求。具体步骤如下:

1. 准备代理 IP 池:收集多个可用的代理 IP 地址,格式通常为`http://代理IP:端口`或`https://代理IP:端口`。

2. 创建`ProxyHandler`对象:将代理 IP 地址以字典形式传入`ProxyHandler`,例如:

proxies = {
       'http': 'http://代理IP1:端口',
       'https': 'https://代理IP2:端口'
}
proxy_handler = urllib.request.ProxyHandler(proxies)


3. 构建`Opener`对象:使用`urllib.request.build_opener`方法将`ProxyHandler`添加到请求处理器中,并通过`install_opener`安装该`Opener`对象,使其生效。

   opener = urllib.request.build_opener(proxy_handler)
   urllib.request.install_opener(opener)



4. 发送请求:使用`urllib.request.urlopen`方法发送请求,此时请求会通过指定的代理 IP 发送。

response = urllib.request.urlopen(url)



通过动态设置 IP 池,可以有效隐藏真实 IP 地址,避免被目标服务器封禁,同时提高请求的稳定性和安全性。


---

常见错误及原因


在使用代理 IP 池时,可能会遇到以下常见错误:
1. `ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接`

• 原因:该错误通常表示目标服务器主动关闭了连接。可能的原因包括:

• 代理 IP 被目标服务器封禁或限制访问。

• 请求频率过高,触发了服务器的反爬虫机制。

• 代理服务器不稳定或配置错误。

• 解决方法:更换代理 IP,降低请求频率,确保代理服务器的稳定性。


2. `urllib.error.URLError: urlopen error Remote end closed connection without response`

• 原因:目标服务器在接收到请求后未返回任何响应,可能是因为:

• 代理服务器无法正常连接到目标服务器。

• 目标服务器拒绝了代理 IP 的请求。

• 网络连接不稳定或超时。

• 解决方法:检查代理 IP 的可用性,尝试更换代理服务器,或增加请求的超时时间。


3. `urllib.error.URLError: urlopen error [WinError 10054] 远程主机强迫关闭了一个现有的连接`

• 原因:与`ConnectionResetError`类似,该错误表示目标服务器关闭了连接。可能的原因包括:

• 代理 IP 被目标服务器封禁。

• 请求格式或参数不正确,导致服务器拒绝响应。

• 解决方法:更换代理 IP,检查请求头和参数是否符合目标服务器的要求。


4. `TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,因此连接尝试失败`

• 原因:该错误表示请求超时,可能的原因包括:

• 网络连接不稳定或延迟过高。

• 代理服务器响应缓慢或无法连接到目标服务器。

• 请求的超时时间设置过短。

• 解决方法:增加请求的超时时间,更换代理服务器,或优化网络环境。


5. `urllib.error.URLError: urlopen error [WinError 10061] 由于目标计算机拒绝访问,因此`

• 原因:该错误表示目标服务器拒绝了连接请求,可能的原因包括:

• 目标服务器未运行或端口未开放。

• 代理 IP 被目标服务器拒绝访问。

• 请求的 URL 或端口错误。

• 解决方法:检查目标服务器的状态和端口是否开放,更换代理 IP,或验证请求的 URL 和端口是否正确。

cookies

通过提交数据实现用户登录之后,会生成带有登录状态的Cookies,这时可以将Cookies保存在本地文件中,下次程序运行的时候,可以直接读取Cookies文件来实现用户登录。特别对于一些复杂的登录,如验证码、手机短信验证登录这类网站,使用Cookies能简单解决重复登录的问题。

在 Python 中,`urllib`模块中的`HTTPCookieProcessor`用于处理 HTTP 请求中的 Cookies,而`MozillaCookieJar`是一个用于读写 Cookies 的工具。以下是一个使用`HTTPCookieProcessor`和`MozillaCookieJar`来处理 Cookies 的完整示例:


示例:使用`urllib`和`MozillaCookieJar`管理 Cookies

import http.cookiejar
import urllib.request

# 创建一个 MozillaCookieJar 对象实例来保存 cookie
cookie_jar = http.cookiejar.MozillaCookieJar('cookies.txt')

# 创建一个 HTTPCookieProcessor 对象并传入 cookie_jar
cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)

# 创建一个 opener 并传入 cookie_processor
opener = urllib.request.build_opener(cookie_processor)

# 创建请求对象
url = "http://example.com"  # 替换为需要访问的网站
request = urllib.request.Request(url)

# 使用 opener 发送请求并获取响应
response = opener.open(request)

# 打印响应内容
print(response.read().decode('utf-8'))

# 保存 cookies 到文件
cookie_jar.save(ignore_discard=True, ignore_expires=True)

# 从文件加载 cookies
cookie_jar.load('cookies.txt', ignore_discard=True, ignore_expires=True)

# 再次发送请求,此时会自动携带保存的 cookies
response_with_cookies = opener.open(request)
print(response_with_cookies.read().decode('utf-8'))


 

示例说明:

1. 创建`MozillaCookieJar`:用于保存和加载 Cookies。

• `cookie_jar = http.cookiejar.MozillaCookieJar('cookies.txt')`创建了一个`MozillaCookieJar`对象,并指定保存 Cookies 的文件名为`cookies.txt`。


2. 创建`HTTPCookieProcessor`:用于处理 HTTP 请求中的 Cookies。

• `cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)`将`cookie_jar`传递给`HTTPCookieProcessor`,以便在 HTTP 请求中自动处理 Cookies。


3. 创建`opener`:用于发送 HTTP 请求。

• `opener = urllib.request.build_opener(cookie_processor)`创建了一个`opener`对象,并传入`cookie_processor`。


4. 发送请求并保存 Cookies:

• 使用`opener.open(request)`发送请求。

• 调用`cookie_jar.save(ignore_discard=True, ignore_expires=True)`将获取到的 Cookies 保存到文件中。


5. 从文件加载 Cookies:

• 使用`cookie_jar.load('cookies.txt', ignore_discard=True, ignore_expires=True)`从文件中加载 Cookies。


6. 再次发送请求:

• 再次使用`opener.open(request)`发送请求时,`HTTPCookieProcessor`会自动将加载的 Cookies 添加到请求中。
注意事项:

• `ignore_discard`和`ignore_expires`参数:这两个参数用于在保存和加载 Cookies 时忽略过期时间。

• 网站的 Cookie 策略:某些网站可能使用会话 Cookie,这些 Cookie 在浏览器关闭后会失效。因此,保存的 Cookies 可能无法在后续请求中使用。

• 安全性:Cookies 可能包含敏感信息(如会话 ID),在保存和加载 Cookies 时要注意安全性,避免泄露。

如何获取cookies

在之前的代码中,虽然涉及到了保存和加载 Cookies 的操作,但没有明确展示如何直接读取和查看保存的 Cookies。

在 Python 中,可以通过`MozillaCookieJar`或`CookieJar`的方法直接读取和查看 Cookies。


完整示例:使用`urllib`和`MozillaCookieJar`管理并读取 Cookies


import http.cookiejar
import urllib.request

# 创建一个 MozillaCookieJar 对象实例来保存 cookie
cookie_jar = http.cookiejar.MozillaCookieJar('cookies.txt')

# 创建一个 HTTPCookieProcessor 对象并传入 cookie_jar
cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)

# 创建一个 opener 并传入 cookie_processor
opener = urllib.request.build_opener(cookie_processor)

# 创建请求对象
url = "http://example.com"  # 替换为需要访问的网站
request = urllib.request.Request(url)

# 使用 opener 发送请求并获取响应
response = opener.open(request)

# 打印响应内容
print(response.read().decode('utf-8'))

# 保存 cookies 到文件
cookie_jar.save(ignore_discard=True, ignore_expires=True)

# 从文件加载 cookies
cookie_jar.load('cookies.txt', ignore_discard=True, ignore_expires=True)

# 再次发送请求,此时会自动携带保存的 cookies
response_with_cookies = opener.open(request)
print(response_with_cookies.read().decode('utf-8'))

# 读取并打印 cookies
print("\n当前保存的 Cookies:")
for cookie in cookie_jar:
    print(f"Domain: {cookie.domain}, Name: {cookie.name}, Value: {cookie.value}")


 

补充说明:

1. 读取 Cookies:

• 在`MozillaCookieJar`对象中,可以通过迭代器的方式访问保存的 Cookies。

• `for cookie in cookie_jar:`遍历所有保存的 Cookies。

• 每个`cookie`对象是一个`http.cookiejar.Cookie`实例,包含以下属性:

• `cookie.domain`:Cookie 所属的域名。

• `cookie.name`:Cookie 的名称。

• `cookie.value`:Cookie 的值。


2. 打印 Cookies:

• 在代码中,通过`print(f"Domain: {cookie.domain}, Name: {cookie.name}, Value: {cookie.value}")`打印每个 Cookie 的详细信息。


3. 其他 Cookie 属性:

• 如果需要,还可以访问其他属性,例如:

• `cookie.path`:Cookie 的路径。

• `cookie.expires`:Cookie 的过期时间(时间戳)。

• `cookie.secure`:是否为安全 Cookie(仅在 HTTPS 下有效)。


示例输出:
假设访问的网站返回了以下 Cookies:

Set-Cookie: session_id=123456789; Path=/; Domain=example.com
Set-Cookie: user=guest; Path=/; Domain=example.com


运行代码后,打印的 Cookies 内容可能如下:
当前保存的 Cookies:

Domain: example.com, Name: session_id, Value: 123456789
Domain: example.com, Name: user, Value: guest

实际应用

在实际场景中,获取网站的 Cookies(尤其是登录相关的 Cookies)通常需要模拟登录过程,因为 Cookies 是服务器在用户登录后生成并返回的。如果直接访问一个需要登录的网站,而没有进行登录操作,服务器通常不会返回登录相关的 Cookies。


模拟登录以获取 Cookies
如果目标网站需要登录,那么在获取 Cookies 之前,必须先模拟登录过程。这通常涉及以下几个步骤:

1. 分析登录请求:查看登录页面的表单数据,确定需要提交的用户名、密码和其他参数。

2. 构造登录请求:使用`urllib`或其他库构造一个包含登录信息的 POST 请求。

3. 发送请求并获取响应:通过`HTTPCookieProcessor`自动处理服务器返回的 Cookies。

4. 保存和使用 Cookies:将获取到的 Cookies 保存到文件中,并在后续请求中使用这些 Cookies。


示例:模拟登录以获取 Cookies
以下是一个完整的示例,展示如何模拟登录一个需要认证的网站,并获取登录后的 Cookies。

import http.cookiejar
import urllib.request
import urllib.parse

# 创建一个 MozillaCookieJar 对象实例来保存 cookie
cookie_jar = http.cookiejar.MozillaCookieJar('cookies.txt')

# 创建一个 HTTPCookieProcessor 对象并传入 cookie_jar
cookie_processor = urllib.request.HTTPCookieProcessor(cookie_jar)

# 创建一个 opener 并传入 cookie_processor
opener = urllib.request.build_opener(cookie_processor)

# 登录信息
login_url = "https://example.com/login"  # 替换为实际的登录 URL
username = "your_username"
password = "your_password"

# 构造表单数据
login_data = {
    "username": username,
    "password": password
}

# 将表单数据编码为 bytes
encoded_data = urllib.parse.urlencode(login_data).encode('utf-8')

# 创建登录请求
login_request = urllib.request.Request(login_url, data=encoded_data)

# 发送登录请求
response = opener.open(login_request)

# 检查登录是否成功(可以根据响应内容或状态码判断)
if response.getcode() == 200:
    print("登录成功!")
    # 保存 cookies 到文件
    cookie_jar.save(ignore_discard=True, ignore_expires=True)
    print("Cookies 已保存到 cookies.txt")
else:
    print("登录失败!")

# 打印获取到的 Cookies
print("\n获取到的 Cookies:")
for cookie in cookie_jar:
    print(f"Domain: {cookie.domain}, Name: {cookie.name}, Value: {cookie.value}")


 

示例说明

1. 登录 URL 和表单数据:

• `login_url`是登录页面的 URL。

• `login_data`是需要提交的表单数据,通常包括用户名和密码。这些数据需要根据目标网站的登录表单进行调整。


2. 构造 POST 请求:

• 使用`urllib.parse.urlencode`将表单数据编码为 URL 编码格式。

• 将编码后的数据传递给`urllib.request.Request`,并指定请求方法为 POST。


3. 发送登录请求:

• 使用`opener.open(login_request)`发送登录请求。

• 如果登录成功,服务器会返回登录后的 Cookies,这些 Cookies 会被`HTTPCookieProcessor`自动保存到`cookie_jar`中。


4. 保存和打印 Cookies:

• 使用`cookie_jar.save()`将获取到的 Cookies 保存到文件中。

• 遍历`cookie_jar`并打印每个 Cookie 的详细信息。


注意事项

1. 登录失败的原因:

• 如果登录失败,可能是因为表单数据不正确(如用户名或密码错误)。

• 有些网站可能使用验证码或其他安全机制,需要额外处理。


2. 安全性:

• 在代码中明文存储用户名和密码是不安全的。在实际应用中,应避免将敏感信息硬编码到代码中。


3. HTTPS 和安全问题:

• 如果登录页面使用 HTTPS,确保在请求中正确处理 SSL/TLS 证书。

证书验证

当遇到一些特殊的网站时,在浏览器上会显示连接不是私密连接而导致无法浏览该网页。

CA证书,也称为SSL证书,是一种数字证书,类似于驾驶证、护照或营业执照的电子副本。由于它通常配置在服务器上,因此也被称为SSL服务器证书。SSL证书遵循SSL协议,由受信任的数字证书颁发机构(CA)颁发。在验证服务器身份后,CA会发放SSL证书,它具备服务器身份验证和数据传输加密的功能。SSL证书能够在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure Socket Layer,SSL)。SSL安全协议最初由Netscape Communication公司设计开发,主要用于对用户和服务器进行身份认证,对传输的数据进行加密和隐藏,并确保数据在传输过程中不被篡改,即保证数据的完整性。如今,SSL协议已成为该领域的全球化标准。

需要注意的是,一些特殊的网站可能会使用自己的证书,而不是由第三方CA颁发的标准证书。

遇到这类验证证书的网站,最简单而暴力的方法是直接关闭证书验证,可以在代码中引入SSL模块,设置关闭证书验证即可。

关闭 SSL 证书验证,发送一个 HTTP 请求到指定的 URL,并打印出响应的状态码。
 

import urllib.request
import ssl

# 关闭证书验证
ssl._create_default_https_context = ssl._create_unverified_context

url = 'https://kyfw.12306.cn/otn/leftTicket/init'
response = urllib.request.urlopen(url)

# 输出状态码
print(response.getcode())

代码解释:

1. 导入模块:

• `urllib.request`用于发送网络请求。

• `ssl`用于处理 SSL 证书。


2. 关闭 SSL 证书验证:

• `ssl._create_default_https_context = ssl._create_unverified_context`这行代码将默认的 HTTPS 上下文替换为不验证证书的上下文。这通常用于测试目的,因为它会忽略 SSL 证书验证,这在生产环境中是不安全的。


3. 定义 URL:

• `url`变量存储了需要访问的网址。


4. 发送请求:

• 使用`urllib.request.urlopen(url)`发送请求到指定的 URL。


5. 打印状态码:

• `response.getcode()`获取 HTTP 响应的状态码,并打印出来。


注意事项:

• 安全性:关闭 SSL 证书验证会使你的应用容易受到中间人攻击。在生产环境中,你应该总是验证 SSL 证书。

• URL 有效性:确保你访问的 URL 是有效的,否则`urlopen`可能会抛出异常。

url编码

Python 中`urllib`模块在发送网络请求时,根据请求方式(GET 或 POST)以及数据编码的要求来处理请求参数。


---

1.`urllib.request.urlopen()`方法与请求方式

• `urllib.request.urlopen()`是 Python 中用来发送网络请求的一个方法。

• 它本身不直接区分是 GET 请求还是 POST 请求,而是通过参数`data`来判断:

• 如果`data`参数为`None`,那么默认是 GET 请求。

• 如果`data`参数不为`None`,那么会被视为 POST 请求。


2.POST 请求时`data`的处理

• 当你想发送 POST 请求时,`data`参数不能直接传入普通的字符串或字典,而是需要经过编码处理。

• 这里的编码处理是通过`urllib.parse`模块完成的:

• 首先,需要将参数(通常是字典形式)转换为 URL 编码的格式(例如:`key1=value1&key2=value2`)。

• 然后,将编码后的字符串转换为字节类型(因为网络传输需要字节类型的数据)。


3.数据编码的必要性

• 在网络请求中,如果需要传递数据(无论是 GET 的 URL 参数,还是 POST 的请求体),数据都需要被编码成一种标准的格式,以便在网络中传输。

• `urllib`要求数据必须是 ASCII 文本字符串(经过百分比编码的格式),并且如果是 POST 请求,还需要将字符串编码为字节类型。

• 如果不按照要求编码,直接传入字符串,就会导致`TypeError`错误。


---

举例说明


假设你想通过 POST 请求向服务器发送以下参数:

data = {'username': 'kimi', 'password': '123456'}


你需要按照以下步骤处理:

1. 编码参数为 URL 编码格式:

import urllib.parse
encoded_data = urllib.parse.urlencode(data)  # 结果是:'username=kimi&password=123456'

2. 将编码后的字符串转换为字节类型:

byte_data = encoded_data.encode('utf-8')  # 结果是:b'username=kimi&password=123456'

3. 发送 POST 请求:

import urllib.request
response = urllib.request.urlopen('http://example.com/login', data=byte_data)

如果直接传入字符串(如`'username=kimi&password=123456'`)而没有转换为字节类型,就会报`TypeError`错误。

特殊字符处理

1.`quote()`和`unquote()`的作用

• `quote()`:用于对字符串进行 URL 编码(也称为百分比编码)。它会将字符串中的特殊字符(如中文、空格、`@`、`&`等)转换为`%`加上两位十六进制数的形式。例如:

import urllib.parse
encoded_str = urllib.parse.quote("你好,世界!")
print(encoded_str)  # 输出:%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81

这样编码后的字符串可以安全地放在 URL 中传输,因为 URL 只能包含 ASCII 字符。


• `unquote()`:用于对经过 URL 编码的字符串进行解码,将其还原为原始字符串。例如:
 

decoded_str = urllib.parse.unquote("%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C%EF%BC%81")
  print(decoded_str)  # 输出:你好,世界!

2.解决中文内容的问题


在 URL 中,中文字符是不被允许的,因为 URL 只能包含 ASCII 字符。如果直接将中文放入 URL 中,可能会导致错误或无法正确解析。例如:

url = "http://example.com/search?q=你好"

这种 URL 在某些情况下可能会报错,或者服务器无法正确解析。

为了避免这种情况,可以使用`quote()`对中文内容进行编码:

import urllib.parse
url = "http://example.com/search?q=" + urllib.parse.quote("你好")
print(url)  # 输出:http://example.com/search?q=%E4%BD%A0%E5%A5%BD


这样编码后的 URL 就可以安全地发送请求了。
---

3.与`urlencode()`的区别

• `urlencode()`是用来编码字典形式的参数,生成`key=value&key=value`格式的查询字符串。它主要用于处理多个参数的情况,例如:

data = {'q': '你好', 'page': 1}
encoded_data = urllib.parse.urlencode(data)
print(encoded_data)  # 输出:q=%E4%BD%A0%E5%A5%BD&page=1

• `quote()`是用来单独对字符串进行编码,适用于单个参数或 URL 中的部分内容。例如:

encoded_str = urllib.parse.quote("你好")
print(encoded_str)  # 输出:%E4%BD%A0%E5%A5%BD

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2317936.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

卷积神经网络 - 卷积层

卷积神经网络一般由卷积层、汇聚层和全连接层构成,本文我们来学习卷积层。 卷积层(Convolutional Layer)是卷积神经网络(CNN)的核心组件,专门用于处理具有网格结构的数据(如图像、音频、时间序…

玩转 Tailwind CSS:深入解析函数与指令

玩转 Tailwind CSS:深入解析函数与指令 如果你正在使用 Tailwind CSS,可能已经习惯了各种 text-center、mt-4 这样的类名,但你知道吗?Tailwind 其实还隐藏着一套 强大的函数与指令系统,可以让你的代码更加优雅、可维护…

Axure设计之下拉多选框制作教程C(中继器)

利用Axure制作下拉多选器组件可以极大地提升原型制作的效率和效果。以下是基于你提供的详细步骤的详细指导,帮助你在Axure中实现一个功能完善、高保真且可复用的下拉多选器组件。 一、案例预览 预览地址:https://pghy0i.axshare.com 实现效果包括&#…

Java基础语法练习42(基本绘图-基本的事件处理机制-小坦克的绘制-键盘控制坦克移动)

目录 一、图形的基本绘制 1.基本介绍: 2.入门代码如下: 3.常用图形的绘制, 示例代码如下: 二、坦克的绘制 三、事件处理机制 四、坦克的移动 一、图形的基本绘制 1.基本介绍: Component 类提供了两个和绘图相关最重要的方…

RabbitMQ 入门

RabbitMQ 入门 1RabbitMQ 介绍 RabbitMQ 是信息传输的中间者。本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发、缓冲…

yolo环境 pytorch环境配置 CUDA安装

我的成功案例:首先安装python 3.12.9的conda虚拟环境 (如果不安装3.12的会报错误ModuleNotFoundError:没有名为“numpy._core”的模块) 然后安装11.8cuda (其实我是可以最高安装12.6的cuda但我实测,太高版…

ESP32(4)TCP通信

本章重点讲解 lwIP 的 Socket接口如何配置 TCP客户端,并在此基础上实现收发功能。 TCP Client 连接流程 在实现 TCP 协议之前,用户需要按照以下步骤配置结构体 sockaddr_in 的成员变量,以便建立 TCPClient 连接: ①:…

数学建模:MATLAB循环神经网络

一、简述 1.循环神经网络 循环神经网络(RNN)是一种用于处理序列数据的神经网络。不同于传统的前馈神经网络,RNN在隐藏层中加入了自反馈连接,使得网络能够对序列中的每个元素执行相同的操作,同时保持一个“记忆”状态…

EagleTrader为何重申重要数据前后2分钟禁止交易?

3月12日,美国公布了2月份的CPI数据。 美国2月未季调CPI年率录得2.8%,为去年11月来新低,低于市场预期的2.9%。 美国2月季调后CPI月率录得0.2%,为去年10月来新低,预期值为0.3%,前值为0.5%。 数据公布后&#…

个人blog系统 前后端分离 前端js后端go

系统设计: 1.使用语言:前端使用vue,并使用axios向后端发送数据。后端使用的是go的gin框架,并使用grom连接数据库实现数据存储读取。 2.设计结构: 最终展示:仅展示添加模块,其他模块基本相似 前…

单元测试mock

一、背景 现在有A类,B类,C类,A类依赖B类,依赖C类,如果想要测试A类中的某个方法的业务逻辑。A类依赖其他类,则把其他类给mock,然后A类需要真实对象。这样就可以测试A类中的方法。 举例:Ticket类需要调用Flight类和Pas…

GreenKGC: A Lightweight Knowledge Graph Completion Method(论文笔记)

CCF等级:A 发布时间:2023年7月 代码位置 25年3月17日交 目录 一、简介 二、原理 1.整体 2.表示学习 3.特征修剪 4.决策学习 三、实验性能 1.主要结果 2.消融实验 四、结论和未来工作 一、简介 传统知识图谱补全方法中,嵌入维度…

SSM基础专项复习5——Maven私服搭建(2)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架(1)-CSDN博客 3、SSM基础专项复习3——Spring框架(2)-CSDN博客 4、SSM基础专项复习4——Maven项目管理工具(1&#xff…

ASP4644四通道降压稳压器的工业高效电源管理方案

ASP4644工业级型号(ASP4644I6B)是一款专为工业场景设计的四通道降压稳压器,支持-40C至85C工作温度。其核心特性包括: 宽输入电压范围:4V–14V,适配工业现场多变的电源环境。 高负载能力:单通道…

RabbitMq C++客户端的使用

1.RabbitMq介绍 RabbitMQ 是一款开源的消息队列中间件,基于 AMQP(高级消息队列协议)实现,支持多种编程语言和平台。以下是其核心特点和介绍: 核心特点 多语言支持 提供 Java、Python、C#、Go、JavaScript 等语言的客…

用通义大模型写爬虫程序,汇总各科成绩

需求:根据各科网址,输入学号、姓名查询成绩。 中间反反复复很多次,本文只记下重点的几次和大模型的沟通历史。 输入界面 查询界面 round0(最初的问题) 请在windows下,使用python的selenium库&#xff0…

电商项目Ts版本

文章目录 项目地址一、环境安装1.1 配置作为导入1.2 文件目录 二、路由2.1 publicRoutes 项目地址 教程作者:教程地址: 代码仓库地址: 所用到的框架和插件: dbt airflow一、环境安装 1.1 配置作为导入 vite.config.ts impor…

HarmonyOS Next中的弹出框使用

HarmonyOS Next弹出框概述及分类 弹出框是一种模态窗口,通常用于在保持当前上下文环境的同时,临时展示用户需关注的信息或待处理的操作。用户需在模态弹出框内完成相关交互任务之后,才能退出模态模式。弹出框可以不与任何组件绑定&#xff0…

FPGA中级项目4——DDS实现

FPGA中级项目4——DDS实现 DDS简介 DDS(直接数字频率合成器,Direct Digital Frequency Synthesis)是一种基于数字信号处理技术的频率合成方法,广泛应用于通信、雷达、仪器仪表等领域。在 FPGA中实现 DDS 具有灵活性高、集成度强、…

STM32 DAC详解:从原理到实战输出正弦波

目录 一、DAC基础原理1.1 DAC的作用与特性1.2 DAC功能框图解析 二、DAC配置步骤2.1 硬件配置2.2 初始化结构体详解 三、DAC数据输出与波形生成3.1 数据格式与电压计算3.2 正弦波生成实战3.2.1 生成正弦波数组3.2.2 配置DMA传输3.2.3 定时器触发配置 四、常见问题与优化建议4.1 …