准备写个爬虫,监控一个网页,如果有更新就将更新的内容采集并邮件通知我,结果开始就卡住了。。。
问题:月份提取出来中文显示为乱码,如:2018å¹´05æ
我看了网页源码,有声明 charset=utf-8
, 并且我用的是 python3.6,所以比较纳闷为何为出现乱码,在 Chrome 控制台下测试 xpath 时是没毛病的:
然后各种百度、谷歌的找,大部说到是编码问题,一篇篇的关于编码的文章看得脑壳麻,然后按所说的方法都不能解决,特发贴看有遇到同样问题的朋友没
尝试过的方法:
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
text.encode('utf-8').decode('unicode_escape')
PS: 打印 requests.get()
的 text
所有中文都显示为乱码
下面为测试的 demo:
import requests
'''
import re
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
'''
from lxml import html
url = 'http://www.wh-ccic.com.cn/node_13613.htm'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'
}
base_url = 'http://www.wh-ccic.com.cn'
page = requests.get(url, headers=headers)
tree = html.fromstring(page.text)
print(page.text)
all_a = tree.xpath('.//*[@class="STYLE13"]/a')
for a in all_a:
# print(a.attrs['href'])
# href = a.attrs['href']
# title = a.text.replace(u'\xe5', u' ')
href = a.attrib['href']
title = a.text
if '\\u' in title:
title = title.encode('utf-8').decode('unicode_escape')
print(title)
1
lifeishort 2018-05-11 01:12:22 +08:00 via iPhone 2
page = requests 后面加一行 page.encoding='utf-8'
|
2
fushall 2018-05-11 01:18:39 +08:00 1
楼上说的对
|
3
Sylv 2018-05-11 01:41:14 +08:00 2
requests 是通过 response 的头部( headers )来检测编码的。
虽然这页面在源码里声明了 charset,但是没在 'Content-Type' header 里声明 charset: Content-Type: text/html 所以 requests 就使用了默认的编码 'ISO-8859-1': >>> page.encoding 'ISO-8859-1' 于是就出现乱码问题了。 解决方法是手动设置 requests 解码这个页面使用的编码: >>> page.encoding = 'utf-8' >>> tree = html.fromstring(page.text) >>> title = tree.xpath('.//*[@class="STYLE13"]/a')[0].text >>> title '2018 年 05 期' |
4
Sylv 2018-05-11 01:44:51 +08:00 2
放上 requests 文档中关于编码的说明:
Encodings When you receive a response, Requests makes a guess at the encoding to use for decoding the response when you access the Response.text attribute. Requests will first check for an encoding in the HTTP header, and if none is present, will use chardet to attempt to guess the encoding. The only time Requests will not do this is if no explicit charset is present in the HTTP headers and the Content-Type header contains text. In this situation, RFC 2616 specifies that the default charset must be ISO-8859-1. Requests follows the specification in this case. If you require a different encoding, you can manually set the Response.encoding property, or use the raw Response.content. http://docs.python-requests.org/en/latest/user/advanced/#encodings |
5
sjmcefc2 2018-05-11 02:44:16 +08:00 1
也是遇到编码问题,至今没搞懂 2 和 3 的差别。只是觉得 2 更好用
|
6
Hopetree 2018-05-11 09:40:15 +08:00 1
1 楼正解
|
7
janxin 2018-05-11 09:43:59 +08:00 1
@sjmcefc2 当然是 2 不好用...不过 lz 的问题主要是 requests 非得按照标准来,不处理非标准情况的一些 corner case (当然基本上都是半瓶水码农的锅)。 https://github.com/requests/requests/issues/1737
|
8
yonoho 2018-05-11 10:43:05 +08:00
很多网站都有这个问题,一般国内默认 utf-8 就好。实在拿不准编码的时候也可以通过 page.content.decode($codec) 一个个试
|
9
Meli55a OP @Sylv 因为获取回来的 text 中的中文已经是乱码,所以也怀疑是 requests 那里有问题,可是不知如何解决,又找不到详细的 api 说明,还尝试过在 get 方法里面加 encoding 参数,结果是没有那个参数,却没想到变通一下多写一句。。。
|
10
sjmcefc2 2018-05-11 12:46:53 +08:00
@janxin 2 貌似读进来的都是编码格式的,而 3 貌似是默认 unicode,调用 chardet 就会出错。我的问题更奇葩,就是各种 utf-8,gb2312,gbk 混编,一行内各种编码混杂。。。。始终没有很完美的解决方法
|
11
lifeishort 2018-05-11 20:34:17 +08:00 via iPhone
@sjmcefc2 不知道编码的时候试试
resp.encoding=resp.apparent_encoding |