52、Python 网络数据处理与编码实用指南

Python 网络数据处理与编码实用指南

1. hashlib 模块

hashlib 模块实现了多种安全哈希和消息摘要算法,如 MD5 和 SHA1。要计算哈希值,需调用以下函数,函数名与所代表的算法相同:
| 函数 | 描述 |
| — | — |
| md5() | MD5 哈希(128 位) |
| sha1() | SHA1 哈希(160 位) |
| sha224() | SHA224 哈希(224 位) |
| sha256() | SHA256 哈希(256 位) |
| sha384() | SHA384 哈希(384 位) |
| sha512() | SHA512 哈希(512 位) |

这些函数返回的摘要对象实例 d 具有以下接口:
| 方法或属性 | 描述 |
| — | — |
| d.update(data) | 用新数据更新哈希。data 必须是字节串。重复调用等同于使用连接数据的单次调用。 |
| d.digest() | 以原始字节串形式返回摘要值。 |
| d.hexdigest() | 返回以十六进制数字编码的摘要值的文本字符串。 |
| d.copy() | 返回摘要的副本。副本保留原始摘要的内部状态。 |
| d.digest_size | 结果哈希的字节大小。 |
| d.block_size | 哈希算法的内部块大小(字节)。 |

该模块还提供了另一种构造接口:
- new(hashname) :创建一个新的摘要对象。 hashname 是一个字符串,如 ‘md5’ 或 ‘sha256’,指定要使用的哈希算法的名称。哈希名称可以是上述任何一种哈希算法,也可以是 OpenSSL 库公开的哈希算法(取决于安装情况)。

2. hmac 模块

hmac 模块支持 HMAC(用于消息认证的键控哈希),该算法在 RFC - 2104 中有所描述。HMAC 是一种基于 MD5 和 SHA - 1 等加密哈希函数的消息认证机制。

2.1 创建 HMAC 对象

  • new(key [, msg [, digest]]) :创建一个新的 HMAC 对象。这里, key 是一个字节串,包含哈希的起始密钥; msg 包含要处理的初始数据; digest 是用于加密哈希的摘要构造函数。默认情况下, digest hashlib.md5 。通常,初始密钥值是使用加密强随机数生成器随机确定的。

2.2 HMAC 对象的方法

方法 描述
h.update(msg) 将字符串 msg 添加到 HMAC 对象。
h.digest() 返回到目前为止处理的所有数据的摘要,并返回一个包含摘要值的字节串。字符串的长度取决于底层哈希函数。对于 MD5,为 16 个字符;对于 SHA - 1,为 20 个字符。
h.hexdigest() 以十六进制数字字符串形式返回摘要。
h.copy() 复制 HMAC 对象。

2.3 示例

hmac 模块的主要用途是在需要对消息发送者进行身份验证的应用程序中。以下是一个示例:

import hmac

secret_key = b"peekaboo"  # 仅我知道的字节串。通常,你会希望使用 os.urandom() 或类似方法计算的随机字节串
data = b"Hello World"  # 要发送的消息

# 发送消息
# out 代表一个套接字或其他 I/O 通道,我们通过它发送数据
h = hmac.new(secret_key)
h.update(data)
# 这里假设 out 是一个有效的发送通道
# out.send(data)  # 发送数据
# out.send(h.digest())  # 发送摘要

# 接收消息
# in 代表一个套接字或其他 I/O 通道,我们通过它接收数据
h = hmac.new(secret_key)
# 这里假设 in 是一个有效的接收通道
# data = in.receive()  # 获取消息数据
# h.update(data)
# digest = in.receive()  # 获取发送者发送的摘要
# if digest != h.digest():
#     raise AuthenticationError('Message not authenticated')

该示例展示了如何使用 hmac 模块进行消息身份验证。发送者使用密钥创建 HMAC 对象,更新对象并发送消息和摘要;接收者使用相同的密钥和消息数据计算自己的摘要,并与接收到的摘要进行比较。

3. HTMLParser 模块

在 Python 3 中,该模块名为 html.parser HTMLParser 模块定义了一个 HTMLParser 类,可用于解析 HTML 和 XHTML 文档。要使用此模块,需定义自己的类,继承自 HTMLParser 并根据需要重新定义方法。

3.1 创建 HTML 解析器

  • HTMLParser() :这是用于创建 HTML 解析器的基类,无需任何参数进行初始化。

3.2 HTMLParser 实例的方法

方法 描述
h.close() 关闭解析器并强制处理任何剩余的未解析数据。在所有 HTML 数据都已提供给解析器后调用此方法。
h.feed(data) 向解析器提供新数据。此数据将立即解析。如果数据不完整(例如,以不完整的 HTML 元素结尾),不完整的部分将被缓冲,下次调用 feed() 并提供更多数据时进行解析。
h.getpos() 以元组 (line, offset) 形式返回当前行号和该行中的字符偏移量。
h.get_starttag_text() 返回与最近打开的开始标签对应的文本。
h.handle_charref(name) 每当遇到字符引用(如 ‘&#ref;’)时调用此处理方法。 name 是一个包含引用名称的字符串。
h.handle_comment(data) 每当遇到注释时调用此处理方法。 data 是一个包含注释文本的字符串。
h.handle_data(data) 调用此处理程序处理标签之间出现的数据。 data 是一个包含文本的字符串。
h.handle_decl(decl) 调用此处理程序处理声明(如 ‘<!DOCTYPE HTML …>’)。 decl 是一个包含声明文本的字符串,不包括开头的 ‘<!’ 和结尾的 ‘>’。
h.handle_endtag(tag) 每当遇到结束标签时调用此处理程序。 tag 是转换为小写的标签名称。
h.handle_entityref(name) 调用此处理程序处理实体引用(如 ‘&name‘)。 name 是一个包含引用名称的字符串。
h.handle_pi(data) 调用此处理程序处理处理指令(如 ‘<?processing instruction>’)。 data 是一个包含处理指令文本的字符串,不包括开头的 ‘<?’ 或结尾的 ‘>’。对于 XHTML 风格的指令 ‘<?…?>’,最后一个 ‘?’ 将包含在 data 中。
h.handle_startendtag(tag, attrs) 处理 XHTML 风格的空标签(如 ‘ ‘)。 tag 是一个包含标签名称的字符串。 attrs 包含属性信息,是一个元组列表,形式为 (name, value) ,其中 name 是转换为小写的属性名称, value 是属性值。如果派生类中未定义此方法,默认实现会调用 handle_starttag() handle_endtag()
h.handle_starttag(tag, attrs) 处理开始标签(如 ‘ ‘)。 tag attrs 的含义与 handle_startendtag() 中描述的相同。
h.reset() 重置解析器,丢弃任何未处理的数据。

3.3 异常

  • HTMLParserError :由于解析错误而引发的异常。该异常有三个属性: msg 属性包含描述错误的消息, lineno 属性是解析错误发生的行号, offset 属性是该行中的字符偏移量。

3.4 示例

以下示例使用 urllib 包获取 HTML 文档,并打印所有通过 ‘ ’ 声明指定的链接:

# printlinks.py
try:
    from HTMLParser import HTMLParser
    from urllib2 import urlopen
except ImportError:
    from html.parser import HTMLParser
    from urllib.request import urlopen
import sys

class PrintLinks(HTMLParser):
    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            for name, value in attrs:
                if name == 'href':
                    print(value)

p = PrintLinks()
u = urlopen(sys.argv[1])
data = u.read()
charset = u.info().getparam('charset')  # Python 2
# charset = u.info().get_content_charset()  # Python 3
p.feed(data.decode(charset))
p.close()

此示例展示了如何使用 HTMLParser 解析 HTML 文档并提取链接。需要注意的是,使用 urllib 获取的 HTML 以字节串形式返回,需要根据文档字符集编码将其解码为文本。

4. json 模块

json 模块用于序列化和反序列化使用 JavaScript 对象表示法(JSON)表示的对象。JSON 格式实际上是 JavaScript 语法的一个子集,与 Python 表示列表和字典的语法非常相似。

4.1 JSON 值与 Python 值的映射

JSON 类型 Python 类型
object dict
array list (tuple)
string unicode (str, bytes)
number int, float
true True
false False
null None

对于字符串数据,应假设使用 Unicode。编码时遇到字节串,默认使用 ‘utf - 8’ 解码为 Unicode 字符串(可控制)。解码时,JSON 字符串始终以 Unicode 形式返回。

4.2 编码函数

  • dump(obj, f, **opts) :将对象 obj 序列化为类文件对象 f opts 是一组关键字参数,可用于控制序列化过程:
    • skipkeys :布尔标志,控制当字典键(而非值)不是字符串或数字等基本类型时的处理方式。如果为 True,则跳过这些键;如果为 False(默认),则引发 TypeError
    • ensure_ascii :布尔标志,确定是否可以将 Unicode 字符串写入文件 f 。默认值为 False。仅当 f 是能正确处理 Unicode 的文件(如由 codecs 模块创建或使用特定编码打开的文件)时,才将其设置为 True。
    • check_circular :布尔标志,确定是否检查容器中的循环引用。默认值为 True。如果设置为 False 且遇到循环引用,则引发 OverflowError 异常。
    • allow_nan :布尔标志,确定是否序列化超出范围的浮点值(如 NaN、inf、 - inf)。默认值为 True。
    • cls :要使用的 JSONEncoder 子类。如果通过继承 JSONEncoder 创建了自己的自定义编码器,则指定此参数。如果 dump() 有任何其他关键字参数,则将其作为参数传递给此类的构造函数。
    • indent :一个非负整数,设置打印数组和对象成员时使用的缩进量。设置此参数会产生一种漂亮打印的效果。默认值为 None,结果以最紧凑的表示形式呈现。
    • separators :形式为 (item_separator, dict_separator) 的元组,其中 item_separator 是包含数组项之间分隔符的字符串, dict_separator 是包含字典键和值之间分隔符的字符串。默认值为 (', ', ': ')
    • encoding :用于 Unicode 字符串的编码,默认值为 ‘utf - 8’。
    • default :用于序列化不支持的基本类型对象的函数。它应返回一个可序列化的值(即字符串)或引发 TypeError 。默认情况下,对于不支持的类型引发 TypeError
  • dumps(obj, **opts) :与 dump() 相同,只是返回包含结果的字符串。

4.3 解码函数

  • load(f, **opts) :从类文件对象 f 反序列化 JSON 对象并返回。 opts 是一组关键字参数,可用于控制解码过程:
    • encoding :用于解释解码的任何字符串值的编码,默认值为 ‘utf - 8’。
    • strict :布尔标志,确定是否允许 JSON 字符串中出现字面(未转义)换行符。默认值为 True,即对于此类字符串会生成异常。
    • cls :用于解码的 JSONDecoder 子类。仅当通过继承 JSONDecoder 创建了自定义解码器时才指定此参数。 load() 的任何额外关键字参数将提供给类构造函数。
    • object_hook :对每个解码的 JSON 对象的结果调用的函数。默认情况下,这是内置的 dict() 函数。
    • parse_float :用于解码 JSON 浮点值的函数。默认情况下,这是内置的 float() 函数。
    • parse_int :用于解码 JSON 整数值的函数。默认情况下,这是内置的 int() 函数。
    • parse_constant :用于解码 JSON 常量(如 ‘NaN’、’true’、’false’ 等)的函数。
  • loads(s, **opts) :与 load() 相同,只是从字符串 s 反序列化对象。

需要注意的是,这些函数虽然与 pickle marshal 模块中的函数同名且用于序列化数据,但使用方式不同。不应使用 dump() 将多个 JSON 编码对象写入同一文件,同样, load() 也不能用于从同一文件读取多个 JSON 编码对象。

4.4 自定义编码和解码

如果要自定义编码或解码过程,可以继承以下基类:
- JSONDecoder(**opts) :用于解码 JSON 数据的类。 opts 是一组关键字参数,与 load() 函数使用的参数相同。实例 d 具有以下两个方法:
- d.decode(s) :返回字符串 s 中 JSON 对象的 Python 表示形式。
- d.raw_decode(s) :返回一个元组 (pyobj, index) ,其中 pyobj 是字符串 s 中 JSON 对象的 Python 表示形式, index s 中 JSON 对象结束的位置。可用于从输入流中解析对象,且流末尾有额外数据的情况。
- JSONEncoder(**opts) :用于将 Python 对象编码为 JSON 的类。 opts 是一组关键字参数,与 dump() 函数使用的参数相同。实例 e 具有以下方法:
- e.default(obj) :当 Python 对象 obj 无法根据任何正常编码规则进行编码时调用的方法。该方法应返回一个可编码的类型(如字符串、列表或字典)的结果。
- e.encode(obj) :调用此方法创建 Python 对象 obj 的 JSON 表示形式。
- e.iterencode(obj) :创建一个迭代器,在计算 Python 对象 obj 的 JSON 表示形式的字符串时生成这些字符串。创建 JSON 字符串的过程本质上是高度递归的。例如,它涉及遍历字典的键并深入到沿途找到的其他字典和列表中。如果使用此方法,可以逐块处理输出,而不是将所有内容收集到一个巨大的内存字符串中。

如果定义继承自 JSONDecoder JSONEncoder 的子类,且类中定义了 __init__() ,需要注意处理所有关键字参数。以下是一个示例:

class MyJSONDecoder(JSONDecoder):
    def __init__(self, **kwargs):
        # 获取自己的参数
        foo = kwargs.pop('foo', None)
        bar = kwargs.pop('bar', None)
        # 用剩余的参数初始化父类
        JSONDecoder.__init__(self, **kwargs)

5. mimetypes 模块

mimetypes 模块用于根据文件名扩展名猜测与文件关联的 MIME 类型,还可将 MIME 类型转换为标准文件名扩展名。MIME 类型由类型/子类型对组成,例如 ‘text/html’、’image/png’ 或 ‘audio/mpeg’。

5.1 猜测 MIME 类型

  • guess_type(filename [, strict]) :根据文件名或 URL 猜测文件的 MIME 类型。返回一个元组 (type, encoding) ,其中 type 是 “type/subtype” 形式的字符串, encoding 是用于传输数据编码的程序(如 compress 或 gzip)。如果无法猜测类型,则返回 (None, None) 。如果 strict 为 True(默认),则使用严格的 MIME 类型匹配规则。

以下是一个使用 mimetypes 模块的简单示例:

import mimetypes

filename = 'example.html'
mime_type, encoding = mimetypes.guess_type(filename)
print(f"MIME type: {mime_type}, Encoding: {encoding}")

这个示例展示了如何使用 guess_type 函数来猜测文件的 MIME 类型和编码。

综上所述,这些模块在 Python 的网络数据处理和编码方面提供了强大的功能。hashlib 和 hmac 模块用于哈希计算和消息认证,HTMLParser 模块用于解析 HTML 和 XHTML 文档,json 模块用于 JSON 数据的序列化和反序列化,mimetypes 模块用于猜测文件的 MIME 类型。通过合理使用这些模块,可以更高效地处理和传输网络数据。

6. 模块使用流程总结

6.1 hashlib 模块使用流程

graph LR
    A[选择哈希算法函数] --> B[创建摘要对象]
    B --> C{是否有新数据?}
    C -- 是 --> D[调用 update 方法更新数据]
    C -- 否 --> E[获取摘要值]
    D --> E
    E --> F[可选: 复制摘要对象]

6.2 hmac 模块使用流程

graph LR
    A[确定密钥] --> B[创建 HMAC 对象]
    B --> C[更新 HMAC 对象数据]
    C --> D[发送消息和摘要]
    D --> E[接收消息和摘要]
    E --> F[验证摘要]

6.3 HTMLParser 模块使用流程

graph LR
    A[定义继承类] --> B[创建解析器实例]
    B --> C[获取 HTML 数据]
    C --> D[解码数据]
    D --> E[向解析器提供数据]
    E --> F[关闭解析器]

6.4 json 模块使用流程

编码流程
graph LR
    A[选择编码函数] --> B[确定对象和参数]
    B --> C[生成 JSON 数据]
解码流程
graph LR
    A[选择解码函数] --> B[确定数据源和参数]
    B --> C[解析 JSON 数据]

6.5 mimetypes 模块使用流程

graph LR
    A[提供文件名或 URL] --> B[调用 guess_type 函数]
    B --> C[获取 MIME 类型和编码]

7. 注意事项和常见问题

7.1 hashlib 模块

  • 不同的哈希算法产生的摘要长度不同,如 MD5 为 128 位(16 字节),SHA1 为 160 位(20 字节)等,使用时要根据需求选择合适的算法。
  • 在更新摘要对象时,传入的数据必须是字节串。

7.2 hmac 模块

  • 密钥必须是字节串,且要保证发送者和接收者使用相同的密钥。
  • 处理消息时,要确保消息数据和摘要的完整性,避免传输过程中数据丢失或被篡改。

7.3 HTMLParser 模块

  • 该模块的解析能力有限,对于复杂或格式错误的 HTML 文档,可能会出现解析错误。
  • 使用 urllib 获取的 HTML 数据是字节串,需要根据文档字符集编码进行解码。

7.4 json 模块

  • 不要使用 dump() 函数将多个 JSON 编码对象写入同一文件,也不要使用 load() 函数从同一文件读取多个 JSON 编码对象。
  • 处理自定义类型时,需要自定义编码器或解码器。

7.5 mimetypes 模块

  • guess_type 函数的猜测结果可能不准确,特别是对于一些不常见的文件扩展名。

8. 综合示例

以下是一个综合使用上述模块的示例,实现一个简单的网络消息认证和数据处理程序:

import hmac
import hashlib
from html.parser import HTMLParser
import json
import mimetypes
from urllib.request import urlopen
import sys

# 模拟消息发送和认证
secret_key = b"mysecretkey"
message = b"Hello, this is a test message."
h = hmac.new(secret_key, digestmod=hashlib.sha256)
h.update(message)
digest = h.digest()

# 模拟消息接收和验证
received_h = hmac.new(secret_key, digestmod=hashlib.sha256)
received_h.update(message)
if received_h.digest() == digest:
    print("Message authenticated successfully.")
else:
    print("Message authentication failed.")

# 解析 HTML 文档并提取链接
class PrintLinks(HTMLParser):
    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            for name, value in attrs:
                if name == 'href':
                    print(value)

try:
    u = urlopen(sys.argv[1])
    data = u.read()
    charset = u.info().get_content_charset()
    p = PrintLinks()
    p.feed(data.decode(charset))
    p.close()
except IndexError:
    print("Please provide a URL as a command-line argument.")

# JSON 数据处理
data = {
    "name": "John",
    "age": 30,
    "city": "New York"
}
json_data = json.dumps(data)
print("JSON data:", json_data)
parsed_data = json.loads(json_data)
print("Parsed data:", parsed_data)

# 猜测文件的 MIME 类型
filename = 'example.html'
mime_type, encoding = mimetypes.guess_type(filename)
print(f"MIME type: {mime_type}, Encoding: {encoding}")

这个示例展示了如何在一个程序中综合使用 hmac HTMLParser json mimetypes 模块,实现消息认证、HTML 解析、JSON 数据处理和 MIME 类型猜测等功能。

通过对这些模块的学习和使用,我们可以更好地处理 Python 中的网络数据,提高数据处理的效率和安全性。在实际应用中,要根据具体需求选择合适的模块和方法,并注意处理可能出现的异常情况。

【复现】并_离网风光互补制氢合成氨系统容量-调度优化分析(Python代码实现)内容概要:本文围绕“并_离网风光互补制氢合成氨系统容量-调度优化分析”的主题,提供了基于Python代码实现的技术研究复现方法。通过构建风能、太阳能互补的可再生能源系统模型,结合电解水制氢合成氨工艺流程,对系统的容量配置运行调度进行联合优化分析。利用优化算法求解系统在不同运行模式下的最优容量配比和调度策略,兼顾经济性、能效性和稳定性,适用于并网离网两种场景。文中强调通过代码实践完成系统建模、约束设定、目标函数设计及求解过程,帮助读者掌握综合能源系统优化的核心方法。; 适合人群:具备一定Python编程基础和能源系统背景的研究生、科研人员及工程技术人员,尤其适合从事可再生能源、氢能、综合能源系统优化等相关领域的从业者;; 使用场景及目标:①用于教学科研中对风光制氢合成氨系统的建模优化训练;②支撑实际项目中对多能互补系统容量规划调度策略的设计验证;③帮助理解优化算法在能源系统中的应用逻辑实现路径;; 阅读建议:建议读者结合文中提供的Python代码进行逐模块调试运行,配合文档说明深入理解模型构建细节,重点关注目标函数设计、约束条件设置及求解器调用方式,同时可对比Matlab版本实现以拓宽工具应用视野。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值