爬虫关于编解码

news/2024/12/20 14:31:04/文章来源:https://www.cnblogs.com/tjp40922/p/18619200

1.现象如下:

Traceback (most recent call last):File "E:\spiders\caipiao.py", line 37, in <module>print(response.content.decode('gbk', errors='strict'))
UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 2708: illegal multibyte sequence

 

2.原因是编码不能处理特殊字符(即使你使用的编码是对的,但是他能解码大部分字符,却解决不了特殊字符的解码问题),所以特殊字符的处理出错应该被忽略掉,或者用特殊的字符代替,如下一个例子

import requests
import chardet
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en-AS;q=0.7,en;q=0.6','Cache-Control': 'max-age=0','Connection': 'keep-alive',
    'Sec-Fetch-Dest': 'document','Sec-Fetch-Mode': 'navigate','Sec-Fetch-Site': 'none','Sec-Fetch-User': '?1','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36','sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',
}

response = requests.get('https://www.cjcp.cn/kaijiang/', headers=headers)
print(response.text)

         1.用response.text 属性可以直接解码,没有问题

         2.但是当我们使用预测的编码进行解码,依然出错,如:

print(response.content.decode(response.apparent_encoding))

       3.使用编码检测后,用检测到的编码进行解码,依然出错

detected_encoding = chardet.detect(response.content)['encoding']
#
# # 打印猜测的编码
print(detected_encoding)
# # 根据猜测的编码解码
decoded_content = response.content.decode(detected_encoding)# 打印解码后的网页内容
print(decoded_content)

  

 2.分析原因:

     1.第一个问题,其实三种情况用的其实是同一种编码区解码,为什么后面两种不行呢?

     2.看下第一种情况下的源码,看下标红的那行代码,就是她在转成字符串的时候,用空白字符策略替换不能解码的字符了,所以他能正常解码

 @propertydef text(self):"""Content of the response, in unicode.If Response.encoding is None, encoding will be guessed using``charset_normalizer`` or ``chardet``.The encoding of the response content is determined based solely on HTTPheaders, following RFC 2616 to the letter. If you can take advantage ofnon-HTTP knowledge to make a better guess at the encoding, you shouldset ``r.encoding`` appropriately before accessing this property."""# Try charset from content-typecontent = Noneencoding = self.encodingif not self.content:return str('')# Fallback to auto-detected encoding.if self.encoding is None:encoding = self.apparent_encoding# Decode unicode from given encoding.try: content = str(self.content, encoding, errors='replace')except (LookupError, TypeError):# A LookupError is raised if the encoding was not found which could# indicate a misspelling or similar mistake.#
            # A TypeError can be raised if encoding is None#
            # So we try blindly encoding.content = str(self.content, errors='replace')return content

 

 

3.解决问题,依葫芦画瓢,忽略特殊字符,或者用空白字符替换完都能正常处理

print(response.content.decode('gbk', errors='replace'))
print(response.content.decode('gbk', errors='ignore'))

 

 

4.题外话,我们后面两种解码方式不行的原因是因为他执行了严格模式,当解码出错,会进行报错吗,等同于

print(response.content.decode('gbk', errors='strict'))

 

5.策略都有哪些

在Python中,.decode() 方法的 errors 参数允许你指定如何处理解码过程中遇到的编码错误。以下是几种常见的错误处理策略及其描述:'strict':这是默认的错误处理策略。如果遇到任何编码错误,将抛出 UnicodeDecodeError 异常。'replace':如前所述,将所有无法解码的字节替换为一个占位符(通常是 Unicode 替换字符 ``)。'ignore':忽略所有无法解码的字节,这意味着这些字节将不会出现在解码后的字符串中。'xmlcharrefreplace':将无法解码的字节替换为 XML 特征引用(例如,&#nnnn;)。'backslashreplace':将无法解码的字节替换为它们的反斜杠转义序列(例如,\xhh)。'namereplace':将无法解码的字节替换为它们的 Unicode 名称(例如,\uXXXX 或 \U00000XXXX)。'surrogateescape':将无法解码的字节替换为 Unicode 代理对(surrogate pairs),每个字节被替换为一个 Unicode 代理项(在范围 \uD800 到 \uDBFF 之间)。'leftstrip':类似于 'strict',但会忽略开头的无法解码的字节。'strip':类似于 'strict',但会忽略所有无法解码的字节(开头、中间和结尾)。这些策略可以根据不同的场景和需求来选择,以确保数据的正确处理和解码。例如,如果你希望确保程序不会因为编码错误而中断,可能会选择 'replace''ignore' 策略。如果你需要保留所有数据,并且愿意处理可能的异常,'strict' 策略可能是更好的选择。

 

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

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

相关文章

面向教学科研智能感知系统应用开发实验室

车辆感知系统在智能驾驶中扮演着至关重要的角色,它如同车辆的“眼睛”和“耳朵”,负责实时监测和解读周围环境信息。该系统通过集成摄像头、雷达、激光雷达等多种传感器,能够准确识别道路状况、行人和其他车辆,为智能驾驶提供可靠的数据支持。经纬恒润推出面向教学及科研应…

Windows Server 2019 Datacenter 激活码——亲测可用

目前网络上流行的 Windows Server 2019 KMS 激活可以很方便且快速完成激活,而且不用担心安全问题。如果您是计算机运维人员,那么 Windows Server 2019 想必肯定有接触不少,那么现在就来一起看看如何激活该系统吧。 Windows Server 2019 有三个版本,在安装的时候我们可以采用…

swagger 导出swagger.json在线预览接口

导出swagger.jsonhttp://<your-host>:<your-port>/v2/api-docs http://<your-host>:<your-port>/v3/api-docs在线预览 将swagger.json数据放入左侧,右侧在线预览:https://editor.swagger.io/ 作者:陈彦斌 出处:https://www.cnblogs.com/chenyanbin…

密码学-RSA的学习

密码学-RSA的学习 前文 1.历史1977年,三位数学家RonRivest、Adi Shamir 和 Leonard Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法 2.加密与解密mod就是进行取模运算,通俗来说就是求余数 这个d... 对d不是很解了3.密钥的生成通过…

App端合并需求

用这次的测试版本,去对比上一次的release版本,看数据是否一致 马上分期Android? 数据看板,这三个去掉 新开发的在ors-portal-test,与最新的realse版本进行比对(原生的就和这个对比,向开发确认ctest4是否为最新的),web端与ctest1对比 这次是用这个来测试,这个是新开发的…

OSG开发笔记(四十):使用OSG自绘拟合球形顶点

前言OSG内置的几何图形并没有球面,那么绘制球面先要绘制球面的组成顶点,本篇解说绘制球面组成顶点的详细过程。 Demo组成面的时候,为了看到是否正确,取中间的几个圆环:   回顾OSG坐标系理解OSG的坐标系类似于Qt场景坐标系,场景有场景的坐标系,图元有图元的坐标系,视图…

流量治理架构对比:当Kmesh遇上Ambient Mesh

Kmesh在控制面升级时或者重启时,即使BPF程序更新,也不会导致业务的连接中断。而节点级用户态代理,天然不具备升级重启不影响业务通信的能力。本文分享自华为云社区《流量治理架构对比:当Kmesh遇上Ambient Mesh》,作者:云容器大未来。 Kmesh是业内首个内核级流量治理引擎,…

ISUP协议视频平台EasyCVR在网页端播放RTSP流对带宽有什么要求?

在现代网络监控系统中,RTSP流的播放是一个关键的技术环节,它涉及视频的实时传输和监控。然而,由于RTSP流的播放在网页端存在一定的技术挑战,需要考虑多种因素,如视频分辨率、编码格式、帧率等,这些因素都会对带宽产生影响。 本文将详细介绍这些因素如何影响带宽需求,并探…

字符串部分语法内容(更新中

字符串部分语法内容 一.字符与ASCII码 1.字符 Q:字符串的作用 A:在日常使用中,我们需要计算机帮我们处理各种各样的文字,比如写文档,写代码,各种文字记录在计算机中,就需要用到字符串或者字符数组将文字内容存储在计算机中。 字符串由字符组成,字符是单引号包含的一个字…

Java项目实战之基于springboot+vue+mysql+jpa+redis的企业网站搭建设计文档设计与实现

一、引言 1.1 项目背景 随着互联网的飞速发展,企业网站已成为企业展示形象、推广产品和服务、与客户沟通的重要窗口。为了提升企业的竞争力,需要构建一个功能完善、用户体验良好的企业网站。 1.2 项目目标 本项目旨在打造一个专业、高效、易用的企业网站,满足企业在品牌展示…

2024 新版Pycharm安装使用教程(附激活至2099年,以及常见问题处理)

Pycharm 简介 Pycharm 是一款非常强大的Python集成开发环境(IDE),由JetBrains公司开发。它提供了丰富的功能和工具,帮助开发者更高效地编写、调试和部署代码。 下面这种方式仅供交流学习,如果有能力还请支持正版 下载安装 为了方便,也可以去链接取 点击获取安装包开始安装下…

OpenCL 编程步骤 4. 创建命令队列 Command Queue

转载 https://deepinout.com/opencl/opencl-basic-tutorials/opencl-create-command-queue.html 在OpenCL上下文中,有内存、程序和内核对象,对这些对象的操作就需要使用命令队列。一条命令就是主机发送给设备的一条消息,用来告诉设备执行一个操作。这个操作包含主机与设备间…