解析西班牙文本并保存到数据库中
我正在用 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 个回答
看起来你说的是这个 http://sourceforge.net/projects/dbfpy。你怎么会觉得它能通过简单地输入Unicode来创建一个兼容VFP的DBF文件呢?我觉得这里没有什么值得一提的文档,而且源代码里也没有 .encode(
这个东西,而且没有支持的方法来改变默认的“签名”,它是0x03(很普通的dBaseIII格式)。
如果你在把文本字段放入dbf之前,先用 cp850
或 cp437
编码,可能会有效,但你需要确认能否用VFP打开生成的文件,并且在查看文本字段时,所有带重音的西班牙字符是否都能正确显示。
如果这样还不行(即使有效),你应该看看 Ethan Furman的dbf包……它声称对VFP、语言驱动程序ID和代码页等方面非常了解。
更新:我看到你定义了一个15000字节的备忘字段。我们其中一个人可能漏掉了什么……我看到的代码在 fields.py
的第330行提到 注意:备忘录目前不完全支持
,稍后又出现了两次 raise NotImplementedError
……回到第3行:TODO: - 让备忘录工作
。当我尝试你说你用的代码(用普通ASCII数据)时,它从 rec.store()
抛出了NotImplementedError。你有没有成功让它工作过?
请记住,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'(至少这样做),以使这个测试可以正常工作。