首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scrapy XPath选择器文本的Unicode和UTF-8编码问题

Scrapy XPath选择器文本的Unicode和UTF-8编码问题
EN

Stack Overflow用户
提问于 2011-04-12 05:37:25
回答 3查看 15.8K关注 0票数 3

我正在使用Scrapy和Python (作为Django项目的一部分)来抓取一个包含德语内容的站点。我已经安装了libxml2作为抓取选择器的后端。

如果我通过选择器提取单词'Hüftsitz' (这是它在站点上的显示方式),我得到:u'H\ufffd\ufffdftsitz' (Scrapy Unicode选择器返回XPath字符串)。

如果我把它编码成UTF-8,我得到:'H\xef\xbf\xbd\xef\xbf\xbdftsitz'。如果我打印出来,我得到的'H??ftsitz'是不正确的。我想知道为什么会发生这种情况。

站点上的character-set设置为UTF-8。我在sys.getdefaultencoding设置为UTF-8的Python shell上测试了上面的代码。在使用Django应用程序时,我看到了同样的行为,在该应用程序中,来自XPath选择器的数据被写入使用UTF-8字符集的MySQL数据库。

我是不是忽略了什么显而易见的东西?任何线索或帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-04-12 14:52:32

约翰和史蒂文,非常感谢你们的回答。你的回答让我有了不同的想法,这让我找到了问题的根源,也找到了一个可行的解决方案。

我正在使用以下测试代码:

代码语言:javascript
复制
import urllib
import urllib2
from scrapy.selector import HtmlXPathSelector
from scrapy.http import HtmlResponse

URL = "http://jackjones.bestsellershop.com/DE/jeans/clark-vintage-jos-217-sup/37246/37256"

url_handler = urllib2.build_opener()
urllib2.install_opener(url_handler)

handle = url_handler.open(URL)
response = handle.read()
handle.close()

html_response = HtmlResponse(URL).replace(body=response) # Problematic line
hxs = HtmlXPathSelector(html_response)

desc = hxs.select('//span[@id="attribute-content"]/text()')
desc_text = desc.extract()[0]
print desc_text
print desc_text.encode('utf-8')

在Scrapy shell中,当我提取描述数据时,它运行良好。这让我有理由怀疑我的代码中有问题,因为在pdb提示符上,我看到了提取的数据中的替换字符。

我查看了Response class的Scrapy文档,并将上面的代码调整为:

代码语言:javascript
复制
import urllib
import urllib2
from scrapy.selector import HtmlXPathSelector
from scrapy.http import HtmlResponse

URL = "http://jackjones.bestsellershop.com/DE/jeans/clark-vintage-jos-217-sup/37246/37256"

url_handler = urllib2.build_opener()
urllib2.install_opener(url_handler)

handle = url_handler.open(URL)
response = handle.read()
handle.close()

#html_response = HtmlResponse(URL).replace(body=response)
html_response = HtmlResponse(URL, body=response)
hxs = HtmlXPathSelector(html_response)

desc = hxs.select('//span[@id="attribute-content"]/text()')
desc_text = desc.extract()[0]
print desc_text
print desc_text.encode('utf-8')

我所做的更改是将行html_response = HtmlResponse(URL).replace(body=response)替换为html_response = HtmlResponse(URL, body=response)。我的理解是,从编码的角度来看,replace()方法以某种方式破坏了特殊字符。

如果有人愿意分享replace()方法到底做错了什么的任何细节,我将非常感谢您所做的努力。

再次感谢您。

票数 3
EN

Stack Overflow用户

发布于 2011-04-12 05:50:28

U‘ufffd’是"unicode replacement character",通常在黑色三角形内打印为问号。不是你的元音。所以问题一定出在上游的某个地方。检查返回的网页标题所说的编码,并验证它是否真实存在。

unicode替换字符通常是作为非法或无法识别的字符的替换插入的,这可能是由几个原因造成的,但最有可能的情况是编码并不是它声称的那样。

票数 3
EN

Stack Overflow用户

发布于 2011-04-12 06:02:28

U+FFFD是执行some_bytes.decode('some-encoding', 'replace')时得到的替换字符,some_bytes的某些子字符串无法解码。

有两个:u'H\ufffd\ufffdftsitz' ..。这表明u-umlaut被表示为两个字节,每个字节都无法解码。最有可能的是,该站点是用UTF-8编码的,但软件试图将其解码为ASCII。尝试解码为ASCII通常发生在发生到Unicode的意外转换时,并且ASCII用作默认编码。然而,在这种情况下,人们不会期望使用'replace'参数。更有可能的是,代码接受了编码,并且是由认为“不引发异常”的人编写的,他认为“不引发异常”意味着“工作”。

编辑您的问题以提供URL,并显示生成u'H\ufffd\ufffdftsitz'的最少代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5627868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档