【问题标题】:Getting strings from database with encoding problems in outfile从数据库中获取输出文件中存在编码问题的字符串
【发布时间】:2016-11-17 20:16:14
【问题描述】:

我正在尝试从 MySql 数据库中获取一些推文数据。 我在开发这段代码时遇到了大量的编码错误。最后一个是我运行代码并让这个输出文件充满 \uxx 字符的唯一方法,如您在此处看到的:

[{..., "lang_tweet": "es", "text_tweet": "Recuerdo un d\u00eda de, *llamada a la 1:45*, \"Micho, me va a dar algo, estoy temblando, me tome un moster y un balium... Que me muero.!!\",...},...]

我一直在这里尝试不同的解决方案,但问题是我对编码和编码的抽象感到非常困惑。 我能做些什么来解决这个问题? 或者也许更容易抓住脏 JSON 并手动“解析”它解码这些字符。

如果你想看看我用来查询数据库的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import pymysql
import collections
import json

conn = pymysql.connect(host='localhost', user='sut', passwd='r', db='tweetsjun2016')
cur = conn.cursor()
cur.execute(""" 
            SELECT * FROM 20160607_tweets
            WHERE 20160607_tweets.creation_date >= '2016-06-07 10:51'
            AND 20160607_tweets.creation_date <= '2016-06-07 11:51'
            AND 20160607_tweets.lang_tweet = "es"
            AND 20160607_tweets.has_keyword = 1
            AND 20160607_tweets.rt = 0
            LIMIT 20
            """)

objects_list = []
for row in cur:
    d = collections.OrderedDict()
    d['download_date'] = row[1]
    d['creation_date'] = row[2]
    d['id_user'] = row[5]
    d['favorited'] = row[7]
    d['lang_tweet'] = row[10]
    d['text_tweet'] = row[11].decode('latin1')
    d['rt'] = row[12]
    d['rt_count'] = row[13]
    d['has_keyword'] = row[19]

    objects_list.append(d)
    # print(row[11].decode('latin1')) <- looks perfect, it prints with accents and fine


j = json.dumps(objects_list, default=date_handler, encoding='latin1')
objects_file = "test23" + "_dicts"
f = open(objects_file,'w')
print >> f, j

cur.close()
conn.close()

如果我从它的所有应用程序中删除 *.decode('latin1') 方法,我会收到此错误:

Traceback (most recent call last):
  File "test.py", line 51, in <module>
    j = json.dumps(objects_list, default=date_handler)
  File "C:\Users\Vichoko\Anaconda2\lib\json\__init__.py", line 251, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "C:\Users\Vichoko\Anaconda2\lib\json\encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\Vichoko\Anaconda2\lib\json\encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xed in position 13: invalid continuation byte

我真的不知道字符串是如何从数据库传到我的脚本的。

感谢阅读,如有任何想法将不胜感激。

编辑1: 在这里,您可以看到 JSON 文件是如何被导出的,并在文本 text_tweet key-val 中出现编码错误: https://github.com/Vichoko/real-time-twit/blob/master/auto_labeling/json/tweets_sismos/tweetsago20160.json

【问题讨论】:

  • 我开始认为只需 解析 oufile 并找到正则表达式 \u[a-f0-9]+ 并将其替换为相应的值会更容易。你推荐哪种语言或工具来做这样的事情?有什么想法吗?

标签: python mysql json string encoding


【解决方案1】:

尝试将charset 关键字参数传递给connect,如example on pymysql's github 所示。

【讨论】:

  • 令人惊讶的是,如果我将 arg charset='utf8mb4' 放入 conect,并删除 .decode('latin1')) 解码,并将后面的 json.dump encoding='latin1' 设置为 'utf-8';我在 outfile 中得到相同的输出字符串:"text_tweet": "Cuando as\u00ed",
  • @VicenteOyanedel - 你能得到SELECT col, HEX(col) FROM ... 这样我们就可以看到实际存储的内容。
  • @RickJames 当然,我对tweet_text 列执行了该查询并得到了以下响应:| text_tweet | HEX(20160801_tweets.text_tweet) | Que fue lo que provocó el sismo en la Ciudad de México, un nuevo desgajamiento en santa fe | 51756520667565206C6F207175652070726F766F63C3B320656C207 369736D6F20656E206C6120436975646164206465204DC3A97869636F2C20756E206E7565766F2064657367616A616D69656E746F20656E2073616E7461206665 | 正如您所看到的,查询中的重音符号和 LAT 字符看起来很好。我希望你能解码你想知道的 HEX。
  • 我设法将4D C3A9 78 69 63 6F 隔离为México 的有效utf8 编码。 é 的 Unicode 代码点是 00E9;你不应该看到那个。表中的数据是“正确的”;它的获取不正确。
  • @VicenteOyanedel - 只有当您执行json.dump 时才会出现问题?既然如此,那就不要使用那个功能。
【解决方案2】:

使用json_encode时,添加这个额外的参数:

$t = json_encode($s, JSON_UNESCAPED_UNICODE);

这会给你í而不是\u00ed。

(不要使用正则表达式,不要使用解码函数等,它们只会把你的洞挖得更深。)

【讨论】:

  • 嗨瑞克,谢谢你的回答!我应该在哪里添加?请注意,我没有明确使用 json_encode,只是使用了倾倒器的编码器。还有,你写的代码好像不是python,是什么?
  • @VicenteOyanedel - 哦。那是PHP代码。我不知道它发生在哪里。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多