解析西班牙文本并保存到数据库中

2 投票
2 回答
1091 浏览
提问于 2025-04-16 07:02

我正在用 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()

当我尝试把它保存到数据库(一个 dbf 数据库)时,出现了 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 个回答

0

看起来你说的是这个 http://sourceforge.net/projects/dbfpy。你怎么会觉得它能通过简单地输入Unicode来创建一个兼容VFP的DBF文件呢?我觉得这里没有什么值得一提的文档,而且源代码里也没有 .encode( 这个东西,而且没有支持的方法来改变默认的“签名”,它是0x03(很普通的dBaseIII格式)。

如果你在把文本字段放入dbf之前,先用 cp850cp437 编码,可能会有效,但你需要确认能否用VFP打开生成的文件,并且在查看文本字段时,所有带重音的西班牙字符是否都能正确显示。

如果这样还不行(即使有效),你应该看看 Ethan Furman的dbf包……它声称对VFP、语言驱动程序ID和代码页等方面非常了解。

更新:我看到你定义了一个15000字节的备忘字段。我们其中一个人可能漏掉了什么……我看到的代码在 fields.py 的第330行提到 注意:备忘录目前不完全支持,稍后又出现了两次 raise NotImplementedError……回到第3行:TODO: - 让备忘录工作。当我尝试你说你用的代码(用普通ASCII数据)时,它从 rec.store() 抛出了NotImplementedError。你有没有成功让它工作过?

1

请记住,DBF 文件根本不支持 Unicode,我还建议使用 Ethan Furman 的 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 中,你可能会在 ".../site-packages/dbf/tables.py" 的第 686 行遇到异常 'TypeError: ord() excepted character...'。

只有 'dbf' 表类型受到了这个问题的影响!

免责声明:我不知道在以下值中使用的正确值,所以不要因为这个“修复”而责怪我不兼容。

你可以在第 490 和 491 行将值 '' 替换为 '\0'(至少这样做),以使这个测试可以正常工作。

撰写回答