【问题标题】:Incorrect displaying of russian characters in Python / Django在 Python / Django 中不正确地显示俄语字符
【发布时间】:2016-04-25 00:59:16
【问题描述】:

我正在尝试使用 lxml 解析俄罗斯网站。但是,我在显示俄语字符时遇到了问题,我无法克服自己。

我们以这段 html 片段为例:

<a href="http://www.2do2go.ru/msk/events/41600/kvest-v-realnosti-karty-dengi-dva-stola" class="medium-events-list_link">Квест в реальности «Карты, деньги, два стола»</a>

我正在使用这个片段来解析它:

title = root.xpath('//*[@id="event-id-41600"]/div[3]/div[2]/a/text()')[0].encode('utf-8').strip()

这就是我得到的:

├É┬Ü├É┬▓├É┬Á├Ĺ┬ü├Ĺ┬é ├É┬▓ ├Ĺ┬Ç├É┬Á├É┬░├É┬╗├Ĺ┬î├É┬Ż├É┬ż├Ĺ┬ü├Ĺ┬é├É┬Ş ├é┬ź├É┬Ü├É┬░├Ĺ┬Ç├Ĺ┬é├Ĺ┬ő, ├É┬┤├É┬Á├É┬Ż├Ĺ┬î├É┬│├É┬Ş, ├É┬┤├É┬▓├É┬░ ├Ĺ┬ü├Ĺ┬é├É┬ż├É┬╗├É┬░├é┬╗

但在数据库中,我看到的不是西里尔字母:

ÐвеÑÑ Ð² ÑеалÑноÑÑи «ÐаÑÑÑ, денÑги, два ÑÑола»

哦,顺便说一句,供参考:

这件作品:

title = item.xpath('div[3]/div[2]/a')[0]
print etree.tostring(title)

给我这个:

<a href="http://www.2do2go.ru/msk/events/41600/kvest-v-realnosti-karty-dengi-dva-stola" class="medium-events-list_link">&#208;&#154;&#208;&#178;&#208;&#181;&#209;&#129;&#209;&#130; &#208;&#178; &#209;&#128;&#208;&#181;&#208;&#176;&#208;&#187;&#209;&#140;&#208;&#189;&#208;&#190;&#209;&#129;&#209;&#130;&#208;&#184; &#194;&#171;&#208;&#154;&#208;&#176;&#209;&#128;&#209;&#130;&#209;&#139;, &#208;&#180;&#208;&#181;&#208;&#189;&#209;&#140;&#208;&#179;&#208;&#184;, &#208;&#180;&#208;&#178;&#208;&#176; &#209;&#129;&#209;&#130;&#208;&#190;&#208;&#187;&#208;&#176;&#194;&#187;</a>

不确定它是否与数据库相关,与 python 编码有关。任何帮助表示赞赏:)

提前致谢。

编辑:我正在使用 MySQL 和 Django ORM

Django 设置:

DATABASE_OPTIONS = {
  "charset": "utf8_general_ci",
  "init_command": "SET storage_engine=INNODB"
}

网页:

<!DOCTYPE html>
<html lang="en" prefix="og: http://ogp.me/ns#" class="">
    <head>
        <title>Интересные события в Москве в январе  - феврале 2016</title>
        <meta charset="utf-8">

【问题讨论】:

  • 你用的是什么 Python 版本?
  • 我使用的是python 2.7.3
  • 尝试删除encode 部分:root.xpath('//*[@id="event-id-41600"]/div[3]/div[2]/a/text()')[0].strip() 可能会有所帮助。
  • UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-9: character maps to
  • 我刚刚意识到它在我的数据库中最终被编码为“latin-1”......不知道为什么......

标签: django python-2.7 unicode encoding lxml


【解决方案1】:

您的服务器上不存在/未设置西里尔文代码页。因此,即使在 UTF-8 中,您也无法在终端中查看俄语字符。但是 python 仍然可以正常使用 unicode。

通过这个命令:

title = root.xpath('//*[@id="event-id-41600"]/div[3]/div[2]/a/text()')[0].encode('utf-8').strip()

你得到 unicode string 并将其编码为 bytes(python2 中的 str)。并将字节保存在数据库中。

当你从数据库加载字符串时,python 使用默认代码页(可能是 Latin-1),你会得到这个:

ÐвеÑÑ Ð² ÑеалÑноÑÑи «ÐаÑÑÑ, денÑги, два ÑÑола»

所以,你应该在数据库中存储 unicode 字符串(不要使用编码)

title = root.xpath('//*[@id="event-id-41600"]/div[3]/div[2]/a/text()')[0].strip()

附:我不明白 encode('Latin-1') 如何帮助(来自 cmets),但问题已解决 :)

【讨论】:

  • 是的,但问题是我需要将这些记录保存在西里尔文的数据库中,如 Квест в реальности Карты, деньги, два стола。我怎样才能做到这一点?我知道 Django 假设所有数据库都使用 UTF-8 编码。所以我想我需要将字符集设置更改为 latin-1?我会试试的。
  • 解析时不应该使用encode。只需将字符串保存在数据库中,因为它已经在 unicode 中。
  • 是的,我明白 :) 但没有它,我最终会得到 ССОССБÑ С² ÑСμѰѻÑС½С¾ÑÑС¸ «ССПБÑÑÑ, ИССИ½ÑС³С¸, Б´СПСИ作为记录。我实际上不得不使用 .encode('latin-1') 来获得西里尔字母。但是感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
相关资源
最近更新 更多