整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

使用requests爬虫「中文乱码」的解决方法

equests是一个较为简单易用的HTTP请求库,是python中编写爬虫程序最基础常用的一个库。对于初学者来说采集的数据【中文乱码】问题是很烦恼的。

本文将根据实践经验说明python中使用requests库编写爬虫程序时,出现【中文乱码】的原因及解决办法。

首先,本文的【中文乱码】情况,指的是原网页中的中文内容在使用requests获取后,中文完全无法识别的情况,区别于\x、\u等编码情况。如下图中的例子:

导致上图中【中文乱码】的原因:

使用requests库时,选择使用的文本响应方法不合适,且没有在代码中添加设置合适的编码,以致于使用【response.text】自动获取到的网页编码,与实际网页的编码不一致,进而产生【中文乱码】。

使用requests库时,可能已经形成了一个习惯,常用【response.text】进行文本响应,而【response.content】常用于图片、视频等。

这两者,最大的一个区别就是:

1、【response.text】会自动根据HTTP头部去推测网页的编码,解码并返回解码后的文本。

2、【response.content】不会解码,直接以二进制形式返回。

两种文本响应方法,如下表:

response.text

服务器响应的内容,会自动根据响应头部的字符编码进行解码。根据HTTP头部对响应的编码做出有根据的推测,推测文本编码。返回类型:str;常用于:响应文本

response.content

字节方式的响应体,不会根据HTTP头部对响应的编码做出有根据的推测。返回类型:bytes(二进制);常用于:图片、视频

最有效的解决方法:

获取网页编码、指定其编码,再提取文本

使用response的encoding、apparent_encoding,得到网页编码。

encoding、apparent_encoding两者最大的区别:

encoding是从header中去提取,而apparent_encoding是从网页源码去解析,apparent_encoding得到的结果更准确。

详细如下表:

response.encoding

从网页响应的header中,提取charset字段中的编码。若header中没有charset字段,则默认为ISO-8859-1编码模式,ISO-8859-1编码无法解析中文,这也是中文乱码的原因。

response.apparent_encoding

从网页的内容中(html源码)中分析网页编码的方式。所以apparent_encoding比encoding更加准确,获取到的才是原网页的实际编码。

print(response.apparent_encoding)
print(response.encoding)

使用encoding、apparent_encoding两种方法,所得的结果是不一致的,apparent_encoding才是原网页实际编码。如下图

根据上述方法,获得原网页的实际编码后,手动在代码中指定文本编码格式,即可解决【中文乱码】问题。如下图:

response.encoding=response.apparent_encoding

以上就是使用requests爬虫解决中文乱码的方法,如那位老师有更好的方法还望赐教,谢谢!

clipse运行页面显示中文乱码

页面源码

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta charset="ISO-8859-1">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<meta name="description" content="">

<meta name="author" content="">

<title>客户列表-BootCRM</title>

</head>

<body>

<h1>解决中文乱码</h1>

</body>

</html>

tomcat运行后

打开浏览器地址栏打就会出现乱码现象

分析问题

首先排查一下服务器是否启动,回看console最下面 server startup 表示服务器已经启动了 没有问题也没有报错。

其次查看页面源码,发现有三处编码为ISO-8859-1。

注意:数字英文都正常显示,只是中文乱码,是因为ISO-8859-1是单字节编码,此字符集支持部分于欧洲使用的语言,这个编码不支持中文,所以要换支持的编码啦,现在一般都通用UTF-8,因为ISO-8859-1是一个8位的容器。因为只有8位, 没那么多地方可以表示中文,但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用 ISO-8859-1编码来表示。而且在很多协议上,默认使用该编码。

解决办法

将代码中三处的ISO-8859-1 改成UTF-8就好了。

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<meta name="description" content="">

<meta name="author" content="">

<title>客户列表-BootCRM</title>

</head>

<body>

<h1>解决中文乱码</h1>

</body>

</html>

此时运行结果就正常了

要使用的是wkhtmltopdf的Python封装——pdfkit

安装

1. Install python-pdfkit:

$ pip install pdfkit

2. Install wkhtmltopdf:

  • Debian/Ubuntu:

$ sudo apt-get install wkhtmltopdf

  • Redhat/CentOS

sudo yum intsall wkhtmltopdf

  • MacOS

brew install Caskroom/cask/wkhtmltopdf

使用

一个简单的例子:

import pdfkit

pdfkit.from_url('http://google.com', 'out.pdf')

pdfkit.from_file('test.html', 'out.pdf')

pdfkit.from_string('Hello!', 'out.pdf')

你也可以传递一个url或者文件名列表:

pdfkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.pdf')

pdfkit.from_file(['file1.html', 'file2.html'], 'out.pdf')

也可以传递一个打开的文件:

with open('file.html') as f:

pdfkit.from_file(f, 'out.pdf')

如果你想对生成的PDF作进一步处理, 你可以将其读取到一个变量中:

# 设置输出文件为False,将结果赋给一个变量

pdf = pdfkit.from_url('http://google.com', False)

你可以制定所有的 wkhtmltopdf 选项 http://wkhtmltopdf.org/usage/wkhtmltopdf.txt. 你可以移除选项名字前面的 '--' .如果选项没有值, 使用None, False or * 作为字典值:

options = {

'page-size': 'Letter',

'margin-top': '0.75in',

'margin-right': '0.75in',

'margin-bottom': '0.75in',

'margin-left': '0.75in',

'encoding': "UTF-8",

'no-outline': None

}

pdfkit.from_url('http://google.com', 'out.pdf', options=options)

默认情况下, PDFKit 将会显示所有的 wkhtmltopdf 输出. 如果你不想看到这些信息,你需要传递一个 quiet 选项:

options = {

'quiet': ''

}

pdfkit.from_url('google.com', 'out.pdf', options=options)

由于wkhtmltopdf的命令语法 , TOC 和 Cover 选项必须分开指定:

toc = {

'xsl-style-sheet': 'toc.xsl'

}

cover = 'cover.html'

pdfkit.from_file('file.html', options=options, toc=toc, cover=cover)

当你转换文件、或字符串的时候,你可以通过css选项指定扩展的 CSS 文件。

# 单个 CSS 文件

css = 'example.css'

pdfkit.from_file('file.html', options=options, css=css)

# Multiple CSS files

css = ['example.css', 'example2.css']

pdfkit.from_file('file.html', options=options, css=css)

你也可以通过你的HTML中的meta tags传递任意选项:

body = """

<html>

<head>

<meta name="pdfkit-page-size" content="Legal"/>

<meta name="pdfkit-orientation" content="Landscape"/>

</head>

Hello World!

</html>

"""

pdfkit.from_string(body, 'out.pdf') #with --page-size=Legal and --orientation=Landscape

配置

每个API调用都有一个可选的参数。这应该是pdfkit.configuration()API 调用的一个实例. 采用configuration 选项作为初始化参数。可用的选项有:

  • wkhtmltopdf ——wkhtmltopdf二进制文件所在的位置。默认情况下pdfkit 会尝试使用which (在类UNIX系统中) 或 where (在Windows系统中)来判断
  • meta_tag_prefix -- pdfkit的前缀指定 meta tags(元标签) - 默认情况是pdfkit-

示例 :针对wkhtmltopdf不在系统路径中(不在$PATH里面)

PATH里面):

config = pdfkit.configuration(wkhtmltopdf='/opt/bin/wkhtmltopdf'))

pdfkit.from_string(html_string, output_file, configuration=config)

问题

IOError:'No wkhtmltopdf executable found':

确保 wkhtmltopdf 在你的系统路径中(PATH), 会通过 configuration进行了配置 (详情看上文描述)。 在Windows系统中使用where wkhtmltopdf命令 或 在 linux系统中使用 which wkhtmltopdf 会返回 wkhtmltopdf二进制可执行文件所在的确切位置.

  • IOError: 'Command Failed'

如果出现这个错误意味着 PDFKit不能处理一个输入。你可以尝试直接在错误信息后面直接运行一个命令来查看是什么导致了这个错误 (某些版本的 wkhtmltopdf会因为段错误导致处理失败)

  • 正常生成,但是出现中文乱码

确保两项:

1)、你的系统中有中文字体

2)、在html中加入

下面是我随便写的一个HTML表格:

<html>

<head><meta charset="UTF-8"></head>

<body>

<table width="400" border="1">

<tr>

<th align="left">Item....</th>

<th align="right">1</th>

</tr>

<tr>

<td align="left">衣服</td>

<td align="right">1.10</td>

</tr>

<tr>

<td align="left">化妆品</td>

<td align="right">.00</td>

</tr>

<tr>

<td align="left">食物</td>

<td align="right">0.40</td>

</tr>

<tr>

<th align="left">tOTAL</th>

<th align="right">01.50</th>

</tr>

</table>

</body>

</html>

下面是生成的PDF截图