网络爬虫【爬虫库urllib】

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

今天来讲一讲爬虫

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_contexturl = '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.rhkb.cn/news/36081.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中js简单创建一个事件中心/中间件/eventBus

vue中js简单创建一个事件中心/中间件/eventBus 目录结构如下: eventBus.js class eventBus {constructor() {this.events {};}// 监听事件on(event, callback) {if (!this.events[event]) {this.events[event] [];}this.events[event].push(callback);}// 发射…

弹球小游戏-简单开发版

一、需求 弹球小游戏是一个简单的互动游戏,玩家需要控制一个挡板在窗口底部左右移动,以接住从上方落下的球。游戏的主要需求包括: (1) 游戏界面 :创建一个指定尺寸的游戏窗口,显示球和挡板。 (2) 球的运动 &#xf…

Cursor与Blender-MCP生成3D模型

随着DeepSeek的热度,各行各业接入AI智能,当然作为一个深受3D爱好者喜爱的软件——Blender,也接入了AI智能,通过Blender-MCP,开启一场Blender的智能化模型创建的世界之旅。 目录 1.准备工作2.环境配置2.1 Mac安装2.2 W…

简单以太网配置

display arp //查看路由器mac地址 交换机配置命令: system-view // 从用户视图进入系统视图 dis mac-address //查看mac地址表 路由器配置命令: system-view // 从用户视图进入系统视图 int GigabitEthernet 0/0/0 //进入G口 0/0/0 进入之后配置网关: ip addre…

SpringBoot可以同时处理多少请求?

大家好,我是锋哥。今天分享关于【SpringBoot可以同时处理多少请求?】面试题。希望对大家有帮助; SpringBoot可以同时处理多少请求? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Boot 本身并不直接限制可以处…

一、初始 Linux

文章目录 一、操作系统概述二、Linux 初识1. Linux 的组成2. Linux 发行版 三、远程链接 Linux 系统1. 四、WSL (windows subsystem for linux)1. 什么是 WSL2. 如何下载 WSL3. 安装不同的 Linux 发行版4. 启动停止使用指定发行版5. 卸载与备份6. 文件共享7. 命令混用8. 用 vsc…

LogicFlow介绍

LogicFlow介绍 LogicFlow是一款流程图编辑框架,提供了一系列流程图交互、编辑所必需的功能和灵活的节点自定义、插件等拓展机制。LogicFlow支持前端自定义开发各种逻辑编排场景,如流程图、ER图、BPMN流程等。在工作审批流配置、机器人逻辑编排、无代码平…

Flask实时监控:打造智能多设备在线离线检测平台(升级版)

前言 武林之中,最讲究的便是“掌控”。若是手下弟子忽然失踪,若是江湖好友生死未卜,岂不令人寝食难安?今日,吾等化身技术侠客,祭出Flask实时监控大法,打造一款智能多设备在线离线检测平台&…

嵌入式编程优化技巧:do-while(0)、case范围扩展与内建函数

在嵌入式编程中,优化代码的性能和可靠性至关重要。无论是通过优化控制结构、提升代码的执行效率,还是利用编译器提供的内建函数来加速关键任务,开发者都需要掌握各种技巧和方法。本文将探讨三种在嵌入式编程中常用的优化技术:do-while(0)的使用、case范围扩展以及内建函数的…

MySQL开发陷阱与最佳实践:第1章:MySQL开发基础概述-1.1 MySQL简介与应用场景

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 MySQL开发陷阱与最佳实践:第1章:MySQL开发基础概述-1.1 MySQL简介与应用场景1.1.1 MySQL的发展历程与市场地位1.1.2 MySQL的核心特性与技术优势1.1.2…

Android Audio基础(18)——最小缓冲区

在创建 AudioTrack 时有一个缓冲区大小的参数,最小缓冲区参数通过 AudioTrack.getMinBufferSize() 获取。 一、最小缓冲区 为了让音频数据通路能正常运转,共享FIFO必须达到最小缓冲区的大小。如果数据缓冲区分配得过小,那么播放声音会频繁遭…

Vue:Vue2和Vue3创建项目的几种常用方式以及区别

前言 Vue.js 和 Element UI 都是用 JavaScript 编写的。 1、Vue.js 是一个渐进式 JavaScript 框架。2、Element UI 是基于 Vue.js 的组件库。3、JavaScript 是这两个项目的主要编程语言。 而Element Plus是基于TypeScript开发的。 一、Vue2 1、基于vuecli工具创建 vue2 …

游戏成瘾与学习动力激发策略研究——了解“情感解离”“创伤理论”

一、情感解离(Emotional Dissociation) 定义:情感解离是一种心理防御机制,指个体在经历无法承受的情绪压力或创伤时,通过切断情感体验与认知、记忆或现实感知的联系来保护自我。它不是简单的“麻木”,而是大脑为应对极端刺激而启动的“紧急逃生通道”。 核心特征 1、意…

WPF跨平台开发探讨:借助相关技术实现多平台应用

WPF跨平台开发探讨:借助相关技术实现多平台应用 一、前言二、WPF 跨平台开发的现状与挑战2.1 WPF 的平台局限性2.2 跨平台开发面临的挑战 三、实现 WPF 跨平台开发的相关技术3.1.NET MAUI 简介3.2.NET MAUI 的关键特性3.3 其他相关技术和工具 四、借助.NET MAUI 实现…

ImGui 学习笔记(五) —— 字体文件加载问题

ImGui 加载字体文件的函数似乎存在编码问题,这一点可能跟源文件的编码也有关系,我目前源文件编码是 UTF-16。 当参数中包含中文字符时,ImGui 内部将字符转换为宽字符字符集时候,采用的 MultiByteToWideChar API 参数不太对&#…

汽车一键启动PKE无钥匙系统

移动管家汽车一键启动PKE舒适无钥匙遥控远程系统是一种集成了多项先进功能的汽车电子系统,主要目的是提高驾驶便利性和安全性。 以下是该系统的具体功能: 功能类别 功能描述 无钥匙进入 感应无钥匙进入(自动感应开关门) 一…

【从零开始学习计算机科学与技术】计算机网络(五)网络层

【从零开始学习计算机科学与技术】计算机网络(五)网络层 网络层无连接服务的实现:数据报子网面向连接服务的实现:虚电路子网IP协议子网及子网划分子网掩码子网规划可变长子网掩码 (VLSM)无类别域间路由—CIDRIP路由转发过程ARP与RARPARP的工作过程:RARP的工作过程如下:DH…

HTML5扫雷游戏开发实战

HTML5扫雷游戏开发实战 这里写目录标题 HTML5扫雷游戏开发实战项目介绍技术栈项目架构1. 游戏界面设计2. 核心类设计 核心功能实现1. 游戏初始化2. 地雷布置算法3. 数字计算逻辑4. 扫雷功能实现 性能优化1. DOM操作优化2. 算法优化 项目亮点技术难点突破1. 首次点击保护2. 连锁…

docker安装node部分问题

sudo n latest sudo: n: command not found 如果运行 sudo n latest 时出现: sudo: n: command not found 说明 n 版本管理工具 未安装 或 未添加到 PATH 环境变量。 🛠 解决方案 1️⃣ 先检查 n 是否已安装 运行: which n或者&#xff1…

2025-03-17 NO.1 Quest3 开发环境配置教程

文章目录 准备条件1 Quest3 激活1.1 下载 Oculus 助手1.2 打开 quest 热点1.3 Quest3 连接 wifi1.4 参考教程 2 登录 Oculus(*)2.1 创建 Meta 账号(*)2.2 Oculus 软件下载与配置(*) 3 创建项目3.1 下载 Uni…