使用httplib2发起网页请求时,如果直接打印响应内容出现乱码二进制数据,说明响应的原始数据是字节流,没有按照正确的编码格式转换为字符串。这种情况在爬取不同编码格式的网页时非常常见,需要针对性处理。

问题产生的原因
httplib2的request方法返回的响应体中,内容默认是字节类型(bytes),如果网页使用的编码格式不是默认的UTF-8,或者响应头中没有正确携带字符集信息,直接解码就会出现乱码。常见的场景包括:
- 网页使用GBK、GB2312等中文编码,直接按UTF-8解码失败
- 响应头的
Content-Type字段没有标注charset信息,无法自动识别编码 - 部分网页的编码信息藏在HTML的meta标签中,httplib2不会自动解析这部分内容
解决方案一:手动指定编码格式
如果明确知道目标网页的编码格式,可以直接对返回的字节流进行解码。比如目标网页是GBK编码,处理方式如下:
import httplib2
# 创建httplib2的Http对象
http = httplib2.Http()
# 发起请求,返回响应头和响应体
response_headers, response_content = http.request("http://ipipp.com/test_gbk_page")
# 手动指定GBK编码解码
decoded_content = response_content.decode("gbk")
print(decoded_content)
解决方案二:从响应头获取编码信息
规范的网页会在响应头的Content-Type中标注字符集,我们可以先解析响应头获取编码格式,再进行解码:
import httplib2
import re
http = httplib2.Http()
response_headers, response_content = http.request("http://ipipp.com/test_page")
# 从Content-Type头中提取charset信息
content_type = response_headers.get("content-type", "")
charset_match = re.search(r"charset=([w-]+)", content_type)
if charset_match:
charset = charset_match.group(1)
# 按提取到的编码解码
decoded_content = response_content.decode(charset)
else:
# 没有提取到编码时默认使用UTF-8
decoded_content = response_content.decode("utf-8")
print(decoded_content)
解决方案三:解析HTML中的meta编码信息
如果响应头没有编码信息,部分网页会把编码放在HTML的<meta>标签中,我们可以解析响应内容获取编码:
import httplib2
import re
http = httplib2.Http()
response_headers, response_content = http.request("http://ipipp.com/test_meta_page")
# 先尝试用UTF-8解码,方便提取meta标签内容
try:
html_text = response_content.decode("utf-8")
except UnicodeDecodeError:
html_text = response_content.decode("gbk", errors="ignore")
# 匹配meta标签中的编码信息
meta_charset_match = re.search(r'<metas+charset=["']?([w-]+)["']?', html_text, re.IGNORECASE)
if not meta_charset_match:
meta_charset_match = re.search(r'<metas+http-equiv=["']?Content-Type["']?s+content=["']?text/html;s*charset=([w-]+)["']?', html_text, re.IGNORECASE)
if meta_charset_match:
charset = meta_charset_match.group(1)
# 重新用正确的编码解码原始字节流
decoded_content = response_content.decode(charset)
else:
decoded_content = response_content.decode("utf-8", errors="ignore")
print(decoded_content)
注意事项
处理编码时建议添加errors="ignore"参数,避免出现解码错误导致程序中断。如果目标网页是动态加载内容,httplib2只能获取初始静态响应,这种情况需要先确认请求的是否是真实的内容接口。另外,部分网站会限制爬虫请求,需要适当添加请求头模拟浏览器访问,避免被服务端拒绝返回正常内容。