Как правильно обрабатывать кодирование при передаче данных из новостной ленты на сервер IRC? - PullRequest
0 голосов
/ 15 июля 2011

Код:

import socket, feedparser

feed = feedparser.parse("http://pwnmyi.com/feed")
latest = feed.entries[0]
art_name = latest.title

network = 'irc.rizon.net'
port = 6667
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
irc.connect((network, port))
print irc.recv(4096)
irc.send('NICK PwnBot\r\n')
irc.send('USER PwnBot PwnBot PwnBot :PwnBot by Fike\r\n')
irc.send('JOIN #pwnmyi\r\n')
while True:
    data = irc.recv(4096)
    if data.find('PING') != -1:
        irc.send('PONG ' + data.split() [1] + '\r\n')
    if data.find( '!latest' ) != -1:
        irc.send('PRIVMSG #pwnmyi :Latest Article: ' + art_name + '\r\n')

Он подключается и т. Д., Но потом, когда я делаю! Последний в канале, он просто выходит с этим:

    irc.send('PRIVMSG #pwnmyi :Latest Article: ' + art_name + '\r\n')
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 55: ordinal not in range(128)

Не могли бы вы помочь мне отладить этот код? Раньше у меня это работало.

Ответы [ 4 ]

1 голос
/ 15 июля 2011

протокол IRC не определяет конкретную кодировку набора символов, используемую для сообщений, скорее это 8-битный протокол, который имеет определенные октеты, используемые для управляющих символов. (См. rfc1459 раздел 2.2 .

Видимо популярный клиент mIRC будет декодировать последовательности utf8, если он распознает их как таковые, и это имеет довольно приличный смысл для использования irc, поскольку кодовые точки ascii кодируются теми же байтами, что и символы ascii, Все кодовые точки -ascii кодируются как значения> 127.

В питоне это пишется unicode.encode(encoding='utf8') примерно так:

>>> u'\u0ca0_\u0ca0'.encode('utf8')
'\xe0\xb2\xa0_\xe0\xb2\xa0'
0 голосов
/ 21 апреля 2012

Лично я бы порекомендовал преобразовать все строки в 'utf-8', вы можете кодировать / декодировать строки Unicode, используя это:

def decode(bytes):
    try:
        text = bytes.decode('utf-8')
    except UnicodeDecodeError:
        try:
            text = bytes.decode('iso-8859-1')
        except UnicodeDecodeError:
            text = bytes.decode('cp1252')
    return text


def encode(bytes):
    try:
        text = bytes.encode('utf-8')
    except UnicodeEncodeError:
        try:
            text = bytes.encode('iso-8859-1')
        except UnicodeEncodeError:
            text = bytes.encode('cp1252')
    return text

Это отличный сайт, который объясняет Unicode Python: http://farmdev.com/talks/unicode

Лучшие 3 совета от него:

  1. Раннее декодирование
  2. Unicode везде
  3. Позднее кодирование
0 голосов
/ 15 июля 2011

latest.title содержит символы не ASCII.

Вы должны либо удалить их, либо убежать от них, либо перевести их.

Дешевый и простой выход - использовать repr()

    irc.send('PRIVMSG #pwnmyi :Latest Article: ' + repr(art_name) + '\r\n')

Или лучше

    irc.send('PRIVMSG #pwnmyi :Latest Article: {0!r}\r\n'.format( art_name ) )

В долгосрочной перспективе вам необходимо обращаться к не-ASCII-символам во входных данных.

0 голосов
/ 15 июля 2011

Вам придется кодировать строку, которую вы отправляете на IRC-сервер.Кроме того, в зависимости от того, что возвращает feedparser, вы можете декодировать его из определенной кодировки.

Кодировка зависит от того, что содержит канал.

...