吐槽

不得不说网络这个东西害死人,一群只会复制粘贴的瓜皮儿。 没一点有用的答案,还要写的像模像样装x

这个问题折腾了一个晚上,晚上找了各种方案,都是相互抄,然而都不能解决问题,找的过程中看到一个博主发出了这样的感慨,真的深表赞同啊,鱼目混杂的内容太多了。

lxml.etree.tostring 乱码的解决方案

话不多说,直接show code,很简单的一个示例代码。这里的关键是to string时用utf-8编码,然后用utf-8解码。

#!env python3
from urllib.request import urlopen
from lxml import etree

#读取baidu.com并解析
htmlFile = urlopen('http://www.baidu.com').read()
html = etree.HTML(htmlFile)

#获取title标签
htmlTitle = html.xpath( "//title")[0]

# to string 并打印
strTitle = etree.tostring(htmlTitle, encoding = "utf-8").decode("utf-8") # encoding和decode一个都不能少。
print(strTitle)

如果采用了上述方案还是乱码,请看这里

如果baidu.com能够正常显示中文,但是你的html解析出来中文还是乱码,那么这个时候很有可能是你的html有问题

下面是一个解析不会乱码的html示范。

<!Doctype html>
<html>

<head>
<!--下面的这个<meta>标签内容一个字都不能少,不然妥妥的乱码!!!
	建议放在<head>标签的开头,或者<html>标签的开头-->
<meta http-equiv=Content-Type content="text/html;charset=utf-8">  
</head>

<title>中文不乱码之终极奥义</title>
<body>哈哈哈哈哈哈哈哈哈老子终于成功了!!!!</body>
</html>

检查一下你的html是否有完整的<meta http-equiv=Content-Type content="text/html;charset=utf-8">,没有的话自己手动加上吧,如果手动添加不方便或者是html文件太多,可以直接解析之前通过代码添加,添加方式如下:

#!env python3
from lxml import etree

testhtml = open("baidu.html","r").read()
root = etree.HTML(testhtml)

#创建meta标签Element
attrs = {}
attrs["http-equiv"] = "Content-Type"
attrs["content"] = "text/html;charset=utf-8"
meta = etree.Element("meta", **attrs)

#插入到html的开头
root.insert(0, meta)

#to string并打印
strHtml = etree.tostring(root, encoding = "utf-8", pretty_print = True, method = "html").decode("utf-8")
print(strHtml)

Finall, Done