Попытка преобразовать строки в Unicode для загрузки XML-файла UFT-8 - PullRequest
0 голосов
/ 13 мая 2018

Я строю скребок EPG, который создает XML-файл в кодировке UTF-8.Все хорошо, за исключением того, что у меня возникают проблемы с кодированием всех битов строк, которые я собираю вместе в строку Unicode, которую я могу загрузить в свой файл.

Мой код такой:

starttime = datetime.strptime(' '.join([str(now.year).encode('UTF-8'), str(e[4].encode('UTF-8')), str(e[0].encode('UTF-8'))]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
endtime = datetime.strptime(' '.join([str(now.year).encode('UTF-8'), str(e[4].encode('UTF-8')), str(e[1].encode('UTF-8'))]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')

global epg_data

clean_channel = str(channel.encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
clean_e2 = str(e[2].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
clean_e3 = str(e[3].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))
div_list3 = div_list2.encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;')
e5 = str(e[5].encode('UTF-8').replace('&', '&amp;').replace("'", "&apos;").replace('"', '&quot;').replace('<', '&lt;').replace('>', '&gt;'))

epg_data = ''.join([u'<programme start="',starttime,u' +0100" stop="',endtime,u' +0100" channel="',clean_channel,u'">\n', \
u'<title lang="eng">',e5,u'</title>\n<desc lang="eng">',clean_e2,' ',clean_e3,u'</desc>\n<icon src="',div_list3,u'" />\n', \
u'<country>UK</country>\n</programme>'])

У меня возникла проблема при попытке разобрать следующее (как напечатано в IDLE):

<programme start="20180514180500 +0100" stop="20180514190000 +0100" channel="BBC Entertainment">
<title lang="eng">Hustle</title>
<desc lang="eng">Hustle Tiger Troubles Season 6 Episode 3/6When a notorious hardman demands £500,000 from Albert by the end of the week, the team tries to raise the cash by targeting a playboy in possession of a gold tiger worth a vast amount of money. Emma is sent to persuade the owner to lend the item to a major museum, in the hope the gang can steal it, but an impenetrable vault causes complications. Guest starring former Doctor Who star Colin Baker and Lolita Chakrabarti : 8.2</desc>
<icon src="http://my.tvguide.co.uk/channel_logos/60x35/68.png" />
<country>UK</country>
</programme>

Сгенерированная ошибка выглядит так:

Traceback (most recent call last):
  File "G:\Python27\Kodi\Sky TV Guide Scraper.py", line 332, in soup_to_text
    u'<country>UK</country>\n</programme>'])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 75: ordinal not in range(128)

У меня вродеНемного сбился с пути с этим разобраться, так что любая помощь будет с благодарностью получена.

1 Ответ

0 голосов
/ 13 мая 2018

Поддержка Unicode в Python 2 довольно запутанная. Это 50 главных причин для перехода на Python 3. Кодирование str или unicode в utf-8 возвращает объект str, который неотличим от обычного ASCII строка. Вы просто должны помнить, что это закодировано. str(channel.encode('utf-8')) немного избыточен (его уже str, поэтому часть str(..) не нужна.

Когда вы вызывали ''.join([u'<programme start="', etc...]), вы смешивали unicode и str объекты, поэтому python пытался перевести все на unicode. Вы знали, что некоторые из этих str строк действительно были строками в кодировке utf-8, но python этого не знал. Python 3 знал бы это и громко лаял.

Общее правило для юникода - делать преобразования по краям. Декодировать при чтении материала, кодировать при записи материала. Если бы вы пропустили материал encode('utf-8') и просто вставили Юникод в предоставленный вами фрагмент, это сработало бы.

Еще две вещи, на которые стоит обратить внимание: Python может избежать строк за вас. cgi.escpae хорошо для старого HTML. xml.sax.saxutils.escape подходит для XML, XHTML и HTML5. И str.format может помочь сделать форматирование строк более читабельным.

Собираем все вместе ...

starttime = datetime.strptime(' '.join([now.year, e[4], e[0], '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')
endtime = datetime.strptime(' '.join([now.year, e[4], e[1]]), '%Y %a %d %b %I:%M%p').strftime('%Y%m%d%H%M%S')

global epg_data

epg_data = u"""\
<programme start="{starttime} +0100" stop="{endtime} +0100" channel="{channel}">
    <title lang="eng">{e5}</title>
    <desc lang="eng">{e2} {e3}</desc>
    <icon src="{div_list2}" />
    <country>UK</country>
</programme>""".format(channel=escape(channel), starttime=starttime, 
    endtime=endtime,e5=escape(e5), e2=escape(e2), e3=escape(e3), 
    div_list2=escape(div_list2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...