Разбор испанского текста и сохранение его в БД - PullRequest
2 голосов
/ 14 ноября 2010

Я анализирую веб-страницу, написанную на испанском языке, с scrapy .Проблема в том, что я не могу сохранить текст из-за неправильной кодировки.

Это функция разбора:

def parse(self, response):
        hxs = HtmlXPathSelector(response)
        text = hxs.select('//text()').extract() # Ex: [u' Sustancia mineral, m\xe1s o menos dura y compacta, que no es terrosa ni de aspecto met\xe1lico.']
        s = "".join(text)
        db = dbf.Dbf("test.dbf", new=True)
        db.addField(
            ("WORD", "C", 25),
            ("DATA", "M", 15000), # Memo field
        )
        rec = db.newRecord()
        rec["WORD"] = "Stone"
        rec["DATA"] = s
        rec.store()
        db.close()

Когда я пытаюсь сохранить его в БД (dbfdb) я получаю ошибку ASCII (128).Я попытался декодировать / кодировать, используя utf-8 и latin1, но безуспешно.

Редактировать:

Для сохранения БД я использую dbfpy .Я добавил код сохранения dbf в функцию разбора выше.

Это сообщение об ошибке:

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 1179, in mainLoop
    self.runUntilCurrent()
  File "/usr/lib/python2.6/dist-packages/twisted/internet/base.py", line 778, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 280, in callback
    self._startRunCallbacks(result)
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 354, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "/usr/lib/python2.6/dist-packages/twisted/internet/defer.py", line 371, in _runCallbacks
    self.result = callback(self.result, *args, **kw)
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/rae_spider.py", line 54, in parse
    rec.store()
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/record.py", line 211, in store
    self.dbf.append(self)
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/dbf.py", line 214, in append
    record._write()
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/record.py", line 173, in _write
    self.dbf.stream.write(self.toString())
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/record.py", line 223, in toString
    for (_def, _dat) in izip(self.dbf.header.fields, self.fieldData)
  File "/home/katy/Dropbox/proyectos/rae/rae/spiders/fields.py", line 215, in encodeValue
    return str(value)[:self.length].ljust(self.length)
exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 18: ordinal not in range(128)

Ответы [ 2 ]

1 голос
/ 22 ноября 2010

Пожалуйста, не забывайте, что DBF-файлы вообще не поддерживают юникод , и я также предлагаю использовать пакет dbf Этана Фурмана (ссылка в другом ответе)

Вы можете использоватьтолько 'table = dbf.Table (' filename ') для угадывания реального типа.

Пример использования с кодировкой не cp437:

#!/usr/bin/env python
# coding: koi8-r
import dbf
text = 'текст в koi8-r'
table = dbf.Table(':memory:', ['test M'], 128, False, False, True, False, 'dbf', 'koi8-r')
record = table.append()
record.test = text

Обратите внимание на следующую информацию о версии0.87.14 и тип таблицы 'dbf':


В пакете DBF 0.87.14 вы можете найти исключение 'TypeError: ord () за исключением символа ...' в "... /site-packages / dbf / tables.py ", строка 686

Эта таблица затрагивает только тип таблицы 'dbf'!

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ : я не знаюдействительно правильные значения для использования в следующих значениях, так что не вините меня в несовместимости с этим «исправлением».

Вы можете заменить значения '' на '\ 0' (как минимум) в строках 490 и 491чтобы сделать этот тест работоспособным.

0 голосов
/ 14 ноября 2010

Похоже, http://sourceforge.net/projects/dbfpy - это то, о чем вы говорите. Что бы дало вам идею, что он может справиться с созданием VFP-совместимого DBF-файла, просто добавив в него Unicode? Нет документов, достойных описания AFAICT, и источник просто не содержит .encode(, и нет поддерживаемого способа изменить стандартную «подпись» на 0x03 (очень простой dBaseIII dile) /

Если вы закодируете свои текстовые поля в cp850 или cp437 перед тем, как бросить их в dbf, это может сработать, но вам нужно будет проверить, что вы можете открыть полученный файл с помощью VFP и что все ваши акцентированные испанские символы отображаются правильно при просмотре текстовых полей на экране.

Если это не сработает (и даже если это сработает), вам следует взглянуть на пакет dbf Этана Фурмана ... он имеет целью узнать все об идентификаторах VFP и языковых драйверов, а также кодовых страницах и подобный.

Обновление: Я вижу, что у вас определено 15000-байтовое мемо-поле. Один из нас что-то упустил ... код, который я читаю, говорит в fields.py о строке 330 Note: memos aren't currenly [sic] completely supported, за которой следует два вхождения raise NotImplementedError ... обратно в строку 3: TODO: - make memos work , Когда я попробовал код, который, как вы говорите, использовал (с простыми данными ASCII), он вызвал NotImplementedError из rec.store(). Вам удалось заставить его работать вообще?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...