【问题标题】:UnicodeWarning: Some characters could not be decoded, and were replaced with REPLACEMENT CHARACTERUnicodeWarning: 有些字符无法解码,被替换为 REPLACEMENT CHARACTER
【发布时间】:2017-04-14 10:53:13
【问题描述】:

我在代码中使用的是python+bs4+pyside,请看下面的代码部分:

enter code here 
#coding:gb2312
import urllib2
import sys
import urllib
import urlparse
import random
import time
from datetime import datetime, timedelta
import socket
from bs4 import BeautifulSoup
import lxml.html
from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtWebKit import *

def download(self, url, headers, proxy, num_retries, data=None):
    print 'Downloading:', url
    request = urllib2.Request(url, data, headers or {})
    opener = self.opener or urllib2.build_opener()
    if proxy:
        proxy_params = {urlparse.urlparse(url).scheme: proxy}
        opener.add_handler(urllib2.ProxyHandler(proxy_params))
    try:
        response = opener.open(request)
        html = response.read()
        code = response.code
    except Exception as e:
        print 'Download error:', str(e)
        html = ''
        if hasattr(e, 'code'):
            code = e.code
            if num_retries > 0 and 500 <= code < 600:
                # retry 5XX HTTP errors
                return self._get(url, headers, proxy, num_retries-1, data)
        else:
            code = None
    return {'html': html, 'code': code}
def crawling_hdf(openfile):
filename = open(openfile,'r')
namelist = filename.readlines()
app = QApplication(sys.argv)
for name in namelist:         
    url = "http://so.haodf.com/index/search?type=doctor&kw="+ urllib.quote(name)
    #get doctor's home page
    D = Downloader(delay=DEFAULT_DELAY, user_agent=DEFAULT_AGENT, proxies=None, num_retries=DEFAULT_RETRIES, cache=None)
    html = D(url)
    soup = BeautifulSoup(html)
    tr = soup.find(attrs={'class':'docInfo'})
    td = tr.find(attrs={'class':'docName font_16'}).get('href')
    print td
    #get doctor's detail information page
    loadPage_bs4(td)

filename.close()

if __name__ == '__main__':
crawling_hdf("name_list.txt")

运行程序后,显示警告消息:

警告(来自警告模块): 文件“C:\Python27\lib\site-packages\bs4\dammit.py”,第 231 行 “有些字符无法解码,并且是” UnicodeWarning: 一些字符无法解码,被替换为 REPLACEMENT CHARACTER。

我用过print str(html),发现tags里所有的中文都是乱码。

我尝试使用在本网站搜索的“decode or encode”和“gzip”解决方案,但在我的情况下不起作用。

非常感谢您的帮助!

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    看起来该页面是用gbk 编码的。问题是utf-8gbk 之间没有直接转换(我知道)。

    我以前见过这个workaround,试试看:

    html.encode('latin-1').decode('gbk').encode('utf-8')
    

    【讨论】:

    • “无直接转换”——你的意思是 在 Python 中? GBK没有什么特别之处,只是另一个regular encoding。另外:UTF8 只是一个存储系统(对于 Unicode),所以即使没有“直接”转换,你最好用它的正确名称来调用它,而不用 UTF8。
    • 我不确定你的意思。我对这个问题的理解是,有一个 dammit.py 无法转换为 utf-8 的 gbk 编码页面。我给出了一个我见过的使用 latin-1 作为“翻译器”的解决方法。鉴于上下文,我会说“在 Python 中”是给定的。 FWIW,如果这里有更好的从 a 到 b 的方法,我完全赞成!
    • 如果您找到的问题的答案已被接受,那么这个问题将是重复的……不过,“在 latin-1 上绕道而行令人震惊”的评论应该告诉您一些事情。
    • 您是建议更好的解决方案,还是什么?
    • @RadLexus 如果您已经有一个解码不正确的 Unicode 字符串,这是修复它的唯一方法。正确的解决方案是首先正确解码,但由于Mojibake,这通常是不可能的。 latin-1 工作并不“令人震惊”,因为 Unicode 以 Latin-1 为基础,因此前 256 个代码点直接映射到 Latin-1 字节——转换实际上是一个空操作。
    【解决方案2】:

    GBK 是 Python 中 codecs 中的 built-in encodings 之一。

    这意味着,只要有原始字节字符串,就可以使用方法decode 和适当的编解码器名称(或其别名)将其转换为本机 Unicode 字符串。

    以下作品(改编自https://stackoverflow.com/q/36530578/2564301),只要返回的文本不包含“垃圾”或“未知”字符,并且确实与源页面编码不同(通过将其保存为新文件和比较汉字的值)。

    from urllib import request
    
    def scratch(url,encode='utf-8'):
        user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
        headers = {'User-Agent':user_agent}
        req = request.Request(url,headers=headers)
        result = request.urlopen(req)
        page = result.read()
        u_page = page.decode(encoding="gbk")
        result.close()
        print(u_page)
        return u_page    
    
    page = scratch('http://so.haodf.com/index/search')
    print (page)
    

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 2013-02-08
      • 2015-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 2020-01-14
      • 1970-01-01
      相关资源
      最近更新 更多