رفع مشکل کدگذاری فارسی در Python و pandas

pandas به جای فارسی نویسه‌های عجیب می‌خواند، با UnicodeDecodeError می‌ایستد، یا اکسل CSV خروجی شما را غلط نشان می‌دهد؟ در Python پارامتر encoding بین درست و خراب تصمیم می‌گیرد. موارد رایج این‌جاست – و فایل‌های خراب را همین بالا در مرورگر درست کنید.

با متن و این فایل‌ها کار می‌کند:

  • CSV
  • TXT
  • JSON
  • XML
  • SRT
  • VTT
  • SMI
  • TSV
  • MD
  • HTML
  • SQL
  • LOG

مثل خروجی اکسل، نسخه پشتیبان پایگاه داده، زیرنویس و کد وب‌سایت.

اصلاح

  1. فایل را بکشید یا متن را بچسبانید
  2. اصلاح خودکار انجام می‌شود
  3. نتیجه را کپی یا دانلود کنید
یا فایل را اینجا بکشید
  • بدون آپلود. فایل‌ها مستقیم داخل مرورگر شما اصلاح می‌شوند و هرگز از دستگاهتان خارج نمی‌شوند.

  • سرور در اتحادیه اروپا. Mojibuster روی سروری در فنلاند (اتحادیه اروپا) اجرا می‌شود؛ بنابراین مقررات عمومی حفاظت از داده‌ها (GDPR) برقرار است. متن مقررات (EUR-Lex، به انگلیسی)

UnicodeDecodeError هنگام خواندن

pd.read_csv UTF-8 انتظار دارد. اگر فایل با Windows-1256 (ANSI فارسی) ذخیره شده باشد، pandas با UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc7 می‌ایستد – بایت 0xC7 در Windows-1256 همان ا است. آن‌وقت کدگذاری را بگویید:

  • pd.read_csv('data.csv', encoding='cp1256') برای فایل‌های اکسل و ویندوز فارسی.
  • encoding='latin-1' هرگز خطا نمی‌دهد ولی فارسی را خراب می‌خواند – برای فارسی استفاده نکنید.
  • اگر کدگذاری را نمی‌دانید، فایل را در Mojibuster رها کنید: آن را تشخیص می‌دهد و فایل را UTF-8 ذخیره می‌کند.

نویسه‌های عجیب به جای فارسی در DataFrame

اگر DataFrame چیزی مثل ط¹ظ„غŒ نشان می‌دهد، فایل UTF-8 با cp1256 یا latin-1 خوانده شده – یا داده از قبل خراب بوده. در حالت اول encoding='utf-8' کافی است. اگر خود داده خراب است، برای مقدارهای تکی value.encode('cp1256').decode('utf-8') کمک می‌کند. ولی با داده مخلوط، همین‌که یک سلول سالم باشد شکست می‌خورد. ساده‌تر: فایل را با Mojibuster درست کنید و بعد بخوانید.

یک CSV از pandas که بدون BOM در اکسل باز شد

قبل

ظ†ط§ظ…,ط´ظ‡ط±,ط¯ط±ط¢ظ…ط¯
ط¹ظ„غŒ ع©ط±غŒظ…غŒ,طھظ‡ط±ط§ظ†,1250
ظ…ط±غŒظ… ط±ط¶ط§غŒغŒ,ط§طµظپظ‡ط§ظ†,980

بعد

نام,شهر,درآمد
علی کریمی,تهران,1250
مریم رضایی,اصفهان,980

to_csv: اکسل فایل را غلط نشان می‌دهد

df.to_csv('export.csv') فایل UTF-8 بدون BOM می‌نویسد. اکسل چنین فایلی را ANSI باز می‌کند و حروف فارسی خراب می‌شوند. با encoding='utf-8-sig' pandas یک BOM می‌نویسد و اکسل UTF-8 را می‌شناسد. بیشتر در اکسل و CSV: فارسی به‌هم‌ریخته.

open() در ویندوز

open('file.txt') بدون encoding در ویندوز از کدگذاری سیستم استفاده می‌کند، در ویندوز فارسی معمولاً cp1256. اسکریپتی که روی لینوکس کار می‌کند، همان فایل UTF-8 را روی ویندوز خراب می‌خواند. پس همیشه encoding='utf-8' بدهید یا متغیر محیطی PYTHONUTF8=1 را بگذارید. طبق PEP 686 در نسخه‌های بعدی Python هم UTF-8 پیش‌فرض می‌شود.

داده وب با requests

requests مقدار response.text را از سرآیند Content-Type درمی‌آورد. اگر پاسخ متنی آن‌جا مجموعه نویسه نداشته باشد، ISO-8859-1 فرض می‌کند و صفحه‌های UTF-8 فارسی خراب می‌شوند. اول response.encoding = 'utf-8' را بگذارید یا از response.json() استفاده کنید که UTF-8 را خودش تشخیص می‌دهد.

اگر متن با errors='replace' در کدگذاری‌ای نوشته شده که نویسه‌های لازم را ندارد، فایل ? دارد – آن‌وقت اطلاعات از بین رفته است، موجیباکه چیست را ببینید.

پرسش‌های متداول

کتابخانه Python برای این کار هست؟

بله، ftfy موجیباکه را داخل کد Python درست می‌کند. برای فایل‌های تکی بدون برنامه‌نویسی، Mojibuster سریع‌تر است و پیش از ذخیره هر تغییر را نشان می‌دهد.

کدام مقدارهای encoding را بیشتر لازم دارم؟

utf-8، utf-8-sig (UTF-8 با BOM)، cp1256 (ویندوز فارسی)، iso-8859-6 و utf-16. حروف کوچک و بزرگ و خط تیره فرقی نمی‌کنند.

جداکننده‌ها و عددها حفظ می‌شوند؟

بله. Mojibuster فقط نویسه‌های خراب را تغییر می‌دهد. ویرگول، گیومه و خط‌شکن‌ها دقیقاً همان‌طور می‌مانند.

راهنماهای دیگر