Python MySQL CSV ส่งออกไปยังการเข้ารหัส json แปลก ๆ

ฉันได้รับไฟล์ csv ที่ส่งออกจากฐานข้อมูล MySQL (ฉันคิดว่าการเข้ารหัสเป็น latin1 เนื่องจากภาษาเป็นภาษาสเปน) ขออภัย การเข้ารหัสไม่ถูกต้อง และฉันไม่สามารถดำเนินการได้เลย ถ้าฉันใช้ไฟล์:

$ file -I file.csv file.csv: text/plain; charset=unknown-8bit

ฉันได้ลองอ่านไฟล์ใน python แล้วแปลงเป็น utf-8 เช่น:

r.decode('latin-1').encode("utf-8")

หรือใช้ mysql_latin1_codec:

r.decode('mysql_latin1').encode('UTF-8')

ฉันกำลังพยายามแปลงข้อมูลเป็นวัตถุ json ข้อผิดพลาดเกิดขึ้นเมื่อฉันบันทึกไฟล์:

'UnicodeEncodeError: ตัวแปลงสัญญาณ 'ascii' ไม่สามารถเข้ารหัสอักขระในตำแหน่งได้'

คุณรู้ไหมว่าฉันจะแปลงเป็นตัวอักษร utf-8 ปกติได้อย่างไร หรือฉันจะแปลงข้อมูลเป็น json ที่ถูกต้องได้อย่างไร ขอบคุณ!!


person alexsc    schedule 25.10.2016    source แหล่งที่มา
comment
คุณช่วยยกตัวอย่างสิ่งที่คุณพยายามถอดรหัสได้ไหม เพราะเพียงข้อผิดพลาดนั้นไม่ใช่เรื่องง่ายที่จะสร้างปัญหาขึ้นมาใหม่และค้นหาแนวทางแก้ไขที่เป็นไปได้...   -  person coder    schedule 25.10.2016
comment
แน่นอนว่าใน csv ช่องต่างๆ จะปรากฏดังนี้: เช่น DIRECCI��N บาร์เซโลนา, v��lida hasta, ฯลฯ   -  person alexsc    schedule 25.10.2016


คำตอบ (3)


ฉันได้ผลลัพธ์ที่ดีจริงๆ จากการใช้ pandas dataframe จาก Continuum Analytics

คุณสามารถทำสิ่งที่ชอบ:

import pandas as pd
from pandas import *

con='Your database connection credentials user, password, host, database to use'
data=pd.read_sql_query('SELECT * FROM YOUR TABLE',conn=con)

ถ้าอย่างนั้นคุณก็สามารถทำได้:

data.to_csv('path_with_file_name')

หรือแปลงเป็น JSON:

data.to_json(orient='records')

หรือหากคุณต้องการปรับแต่งรูปแบบ json ของคุณ โปรดดูเอกสารประกอบที่นี่: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_json.html

person Beatriz Kanzki    schedule 27.12.2016
comment
สวัสดี Beatriz จริง ๆ แล้ว ฉันใช้แพนด้าเพื่อเปิด csv และปรับใช้กับ json โดยใช้ force_ascii=True และมันใช้งานได้ - person alexsc; 17.02.2017

คุณได้ลองใช้โมดูลตัวแปลงสัญญาณแล้วหรือยัง:

import codecs
....
codecs.EncodedFile(r, 'latin1').reader.read()

ฉันจำได้ว่าเคยมีปัญหาที่คล้ายกันมาระยะหนึ่งแล้ว และคำตอบคือเกี่ยวข้องกับวิธีการเข้ารหัสก่อน Python 3 ดูเหมือนว่า Codecs จะจัดการกับปัญหานี้ได้ค่อนข้างดี

ตามที่ผู้เขียนโค้ดกล่าวไว้ในความคิดเห็นของคำถาม เป็นการยากที่จะระบุปัญหาโดยไม่สามารถทำซ้ำได้ ดังนั้นฉันอาจจะเห่าต้นไม้ผิดต้น

person Adam Henderson    schedule 25.10.2016
comment
ฉันได้ลองสิ่งนั้นและอย่างอื่นแล้วก็ไม่ประสบความสำเร็จ :( ขอบคุณ! - person alexsc; 25.10.2016

คุณอาจมีปัญหาสองประการ แต่ขอถอยออกไปก่อน... เราไม่สามารถบอกได้ว่าข้อความนั้นนำเข้าไม่ถูกต้อง ส่งออกไม่ถูกต้อง หรือแสดงในลักษณะที่โง่เขลาเท่านั้น

ก่อนอื่นผมจะพูดถึง "การนำเข้า"...

อย่าพยายามแก้ไขการเข้ารหัส แทนที่จะอยู่กับการเข้ารหัส แต่ก่อนอื่น เรามาทำความเข้าใจก่อนว่าการเข้ารหัสคืออะไร อาจเป็น latin1 หรือ utf8 (หรือชุดอักขระที่มีแนวโน้มน้อยกว่าจำนวนมาก)

ค้นหาเลขฐานสิบหกของไฟล์ที่เข้ามา ใน Python โค้ดจะเป็นดังนี้สำหรับการทิ้งเลขฐานสิบหก (ฯลฯ) สำหรับสตริง u:

for i, c in enumerate(u):
    print i, '%04x' % ord(c), unicodedata.category(c),
    print unicodedata.name(c)

คุณสามารถไปที่นี่เพื่อดูรายการ ค่าเลขฐานสิบหกสำหรับอักขระ latin1 ทั้งหมด พร้อมด้วยเลขฐานสิบหก utf8 ตัวอย่างเช่น ó คือ latin1 F3 หรือ utf8 C2B3

ตอนนี้ เมื่อรู้การเข้ารหัสแล้ว บอก MySQL ได้เลย

LOAD DATA INFILE ...
    ...
    CHARACTER SET utf8  -- or latin1
    ...;

ในขณะเดียวกัน มันไม่สำคัญว่า CHARACTER SET ... ตาราง หรือ คอลัมน์ จะถูกกำหนดให้เป็นอะไร mysql จะแปลงรหัสหากจำเป็น ตัวอักษรภาษาสเปนทั้งหมดมีอยู่ใน latin1 และ utf8

ไปที่คำถามและคำตอบนี้< /em> .

ฉันแนะนำว่าคุณมีข้อผิดพลาดสองประการ ข้อหนึ่งคือกรณี "เพชรดำ" ที่กล่าวถึงในนั้น มีอย่างอื่นเป็นอย่างอื่น แต่... ปฏิบัติตาม "Best Practice" ที่กล่าวมา

กลับมาที่คำถามเรื่อง "การส่งออก"...

คุณต้องตรวจสอบเลขฐานสิบหกของไฟล์เอาต์พุตอีกครั้ง อีกครั้งมันไม่สำคัญว่าจะเป็น latin1 หรือ utf8 อย่างไรก็ตาม... หากเลขฐานสิบหกคือ C383C2B3 สำหรับเพียง ó แสดงว่าคุณมี "การเข้ารหัสสองครั้ง" หากคุณมี ให้ตรวจสอบเพื่อดูว่าคุณได้ลบการเรียกใช้ฟังก์ชันการแปลงด้วยตนเองแล้ว และเพียงบอก MySQL ว่าอะไรคืออะไร

นี่คือutf8+Python tips เพิ่มเติมบางส่วนสำหรับคุณ อาจต้องการ

หากคุณต้องการความช่วยเหลือเพิ่มเติม ให้ทำตามข้อความทีละขั้นตอน แสดงรหัสที่ใช้ในการย้าย/แปลงในแต่ละขั้นตอน และแสดง HEX ในแต่ละขั้นตอน

person Rick James    schedule 25.10.2016
comment
สวัสดี Rick และขอขอบคุณสำหรับคำอธิบายที่ยอดเยี่ยมของคุณ ฉันทราบเคล็ดลับของคุณแล้ว แต่น่าเสียดายที่ฉันไม่มีสิทธิ์เข้าถึง MySQL ฉันถูกจำกัดไว้เฉพาะไฟล์ csv บางไฟล์ที่ส่งออกผิดไปแล้ว:(. - person alexsc; 25.10.2016
comment
คุณสามารถใช้ Python เพื่อค้นหาเลขฐานสิบหกในไฟล์ได้หรือไม่? บางทีอ่านเป็นไบนารีแล้วดูเลขฐานสิบหก? (ฉันไม่พูด Python ดังนั้นฉันจึงช่วยเรื่องโค้ดเฉพาะไม่ได้) หรืออาจเป็นยูทิลิตี้ hex-dump? - person Rick James; 25.10.2016
comment
คุณหมายถึงสิ่งนี้: \x89\xe3\xa2 ? - person alexsc; 25.10.2016
comment
ยัก \x89\xe3\xa2 คือ ‰ã¢ ในภาษาละติน1; เข้ารหัสไม่ถูกต้องเป็น utf8, ในภาษาเกาหลี (euckr) ฯลฯ ควร คืออะไร - person Rick James; 26.10.2016
comment
อืม... ฉันไม่เห็นวิธีที่จะอยู่ระหว่าง © ถึงเลขฐานสิบหก 89e3a3 คุณมีตัวอย่างของสตริงและเลขฐานสิบหกอื่นหรือไม่? - person Rick James; 26.10.2016
comment
แน่นอน: M\xc3\x81LAGA สำหรับมาลากา - person alexsc; 28.10.2016
comment
C381 เป็นการเข้ารหัส utf8 ของ Á; C3A1 เป็นเวอร์ชันตัวพิมพ์เล็ก ข้อความจริงเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก? - person Rick James; 28.10.2016
comment
ฉันได้รับอักขระประเภทนี้: �� - person alexsc; 30.10.2016
comment
อาจหมายความว่าคุณกำลังเชื่อมต่อเป็น latin1 ดูลิงก์ของฉันและมองหา Black Diamond - person Rick James; 30.10.2016
comment
ลิงค์ไหนที่คุณอ้างอิงถึง? - person alexsc; 01.11.2016