Я пытаюсь проанализировать RSS-канал с feedparser и вставить его в таблицу mySQL с помощью SQLAlchemy.Я действительно смог запустить это нормально, но сегодня в ленте был элемент с символом многоточия в описании, и я получаю следующую ошибку:
UnicodeEncodeError: кодек «latin-1» не может кодировать символu '\ u2026' в позиции 35: порядковый номер не в диапазоне (256)
Если я добавлю опцию convert_unicode = True к движку, я смогу получить вставку, чтобы пройти, но многоточие не показываетэто просто странные персонажи.Кажется, это имеет смысл, поскольку, насколько мне известно, в латинице-1 нет горизонтального многоточия.Даже если я установлю кодировку в utf-8, это, похоже, не будет иметь значения.Если я делаю вставку с использованием phpmyadmin и включаю многоточие, оно проходит нормально.
Я думаю, я просто не понимаю кодировки символов или как заставить SQLAlchemy использовать тот, который я указал.Кто-нибудь знает, как заставить текст вводиться без странных символов?
ОБНОВЛЕНИЕ
Я думаю, что я понял это, но я не совсем уверен, почему это важно ...
Вот код:
import sys
import feedparser
import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table
COMMON_CHANNEL_PROPERTIES = [
('Channel title:','title', None),
('Channel description:', 'description', 100),
('Channel URL:', 'link', None),
]
COMMON_ITEM_PROPERTIES = [
('Item title:', 'title', None),
('Item description:', 'description', 100),
('Item URL:', 'link', None),
]
INDENT = u' '*4
def feedinfo(url, output=sys.stdout):
feed_data = feedparser.parse(url)
channel, items = feed_data.feed, feed_data.entries
#adding charset=utf8 here is what fixed the problem
db = create_engine('mysql://user:pass@localhost/db?charset=utf8')
metadata = MetaData(db)
rssItems = Table('rss_items', metadata,autoload=True)
i = rssItems.insert();
for label, prop, trunc in COMMON_CHANNEL_PROPERTIES:
value = channel[prop]
if trunc:
value = value[:trunc] + u'...'
print >> output, label, value
print >> output
print >> output, "Feed items:"
for item in items:
i.execute({'title':item['title'], 'description': item['description'][:100]})
for label, prop, trunc in COMMON_ITEM_PROPERTIES:
value = item[prop]
if trunc:
value = value[:trunc] + u'...'
print >> output, INDENT, label, value
print >> output, INDENT, u'---'
return
if __name__=="__main__":
url = sys.argv[1]
feedinfo(url)
Вот вывод / трассировка от запуска кода без опции charset:
Channel title: [H]ardOCP News/Article Feed
Channel description: News/Article Feed for [H]ardOCP...
Channel URL: http://www.hardocp.com
Feed items:
Item title: Windows 8 UI is Dropping the 'Start' Button
Item description: After 15 years of occupying a place of honor on the desktop, the "Start" button will disappear from ...
Item URL: http://www.hardocp.com/news/2012/02/05/windows_8_ui_dropping_lsquostartrsquo_button/
---
Item title: Which Crashes More? Apple Apps or Android Apps
Item description: A new study of smartphone apps between Android and Apple conducted over a two month period came up w...
Item URL: http://www.hardocp.com/news/2012/02/05/which_crashes_more63_apple_apps_or_android/
---
Traceback (most recent call last):
File "parse.py", line 47, in <module>
feedinfo(url)
File "parse.py", line 36, in feedinfo
i.execute({'title':item['title'], 'description': item['description'][:100]})
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2758, in execute
return e._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2304, in _execute_clauseelement
return connection._execute_clauseelement(elem, multiparams, params)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1538, in _execute_clauseelement
compiled_sql, distilled_params
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1639, in _execute_context
context)
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 330, in do_execute
cursor.execute(statement, parameters)
File "build/bdist.linux-i686/egg/MySQLdb/cursors.py", line 159, in execute
File "build/bdist.linux-i686/egg/MySQLdb/connections.py", line 264, in literal
File "build/bdist.linux-i686/egg/MySQLdb/connections.py", line 202, in unicode_literal
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2026' in position 35: ordinal not in range(256)
Так что похоже на добавление кодировки кстрока подключения mysql сделала это.Я полагаю, по умолчанию это латиница-1?Я попытался установить флаг кодировки для content_engine в utf8, и это ничего не сделало.Кто-нибудь знает, почему он будет использовать латиницу-1, когда для таблиц и полей задан utf8 unicode?Я также пытался кодировать элемент ['description] с помощью .encode (' cp1252 ') перед его отправкой, и это работало также даже без добавления опции charset в строку подключения.Это не должно было работать с латиницей-1, но, видимо, это сработало?У меня есть решение, но я бы с удовольствием ответил:)