【问题标题】:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 139: ordinal not in range(128)UnicodeDecodeError:“ascii”编解码器无法解码位置 139 中的字节 0xe2:序数不在范围内(128)
【发布时间】:2015-09-19 15:05:41
【问题描述】:

我正在编写一个代码,该代码根据搜索词从 twitter 获取实时推文并将其保存到 Mysql 数据库。但是当我在插入数据库时​​运行代码时会引发错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 139: ordinal not in range(128)

我不明白这里的问题是要插入数据库的代码

tweet = json.loads(data);
    #print json.dumps(tweet, indent=4, sort_keys=True)
    #print tweet['text']
    tweetid = tweet['id_str']
    userid = tweet['user']['id_str']
    text = tweet['text'].encode('utf-8')
    cur.execute("""INSERT INTO twitterfeeeds(tweet_id, user_id,body,status) VALUES (%s,%s,%s,'0')"""%(tweetid,userid,text))
    db.commit()

这里的正文是推文中的文本,状态是它是否被处理。

【问题讨论】:

    标签: python mysql python-2.7 twitter


    【解决方案1】:

    不要将推文编码为 UTF-8,也不要使用字符串格式来创建查询。

    改用 SQL 参数:

    tweetid = tweet['id_str']
    userid = tweet['user']['id_str']
    text = tweet['text']
    cur.execute(
        """INSERT INTO twitterfeeeds(tweet_id, user_id,body,status) VALUES (%s, %s, %s, '0')""",
        (tweetid, userid, text))
    

    是的,上面的代码和你的有区别; tweetiduseridtext 值都作为一个单独的参数(元组)传递给 cursor.execute() 方法。

    游标负责处理正确转义数据以插入数据库。这样可以避免 SQL 注入攻击(;DROP TABLE twitterfeeeds 的推文会立即破坏您的数据库),并启用查询计划优化。

    这一切都需要您配置数据库连接以支持 Unicode 数据;在连接上将字符集设置为 UTF-8:

    conn = MySQLdb.connect(host="localhost", user='root', password='', 
                           db='', charset='utf8')
    

    或者更好的是,将数据库配置为使用 UTF8MB4 字符集(MySQL 使用的 UTF-8 版本无法处理表情符号或 U+FFFF 以外的其他代码点):

    # Note, no characterset specified
    con = MySQLdb.connect(host="localhost", user='root', password='', db='')
    cursor = con.cursor()
    cursor.execute('SET NAMES utf8mb4')
    cursor.execute('SET CHARACTER SET utf8mb4')
    cursor.execute('SET character_set_connection=utf8mb4')
    

    【讨论】:

    • 推文未编码时会引发另一个错误 UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026' in position 234: ordinal not in range(256)
    • @Harwee:不是作为查询参数传入时。
    • @Harwee:您需要将数据库配置为接受 UTF-8 Unicode 文本,目前您的数据库只能处理 Latin-1。
    【解决方案2】:

    使用可以使用 MySQLdb.escape_string 来转义 unicode 字符。

    >> MySQLdb.escape_string("'")
    "\\'"
    

    另外我认为你必须用'use_unicode'打开你的'mysql.connector':True config:

    config = {
    'user': ...,
    'password': ...,
    'host': '127.0.0.1',
    'use_unicode':True,
    'charset':'utf8',
    }
    db = mysql.connector.connect(**config)
    

    【讨论】:

      猜你喜欢
      • 2013-09-10
      • 2017-09-19
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      相关资源
      最近更新 更多