考虑我想要抓取包含以下HTML的网站:
<a id="mylink" href="http://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premi%C3%A8r-cru-brocard-75cl">
此href是u'https://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premièr-cru-brocard-75cl'
我用Scrapy得到了这样的href:
u = response.xpath('//a[id="mylink"]/@href').extract_first()
Scrapy将变量u
设置为
u'http://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premi%C3%A8r-cru-brocard-75cl'
请注意,它错误地将页面的字节字符串(表示unicode字符串)解释为 unicode字符串本身,因此它是错误的 unicode对象,具有不同的unicode chars:
In [67]: print urllib.unquote(x)
http://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premièr-cru-brocard-75cl
实际需要的是Scrapy将href解释为字节字符串:
bs = 'http://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premi%C3%A8r-cru-brocard-75cl'
这样它代表正确的unicode对象,即
In [70]: print urllib.unquote(bs).decode('utf8')
http://www.sainsburys.co.uk/shop/gb/groceries/chablis/chablis-premièr-cru-brocard-75cl
我设法解决这个问题的唯一方法是使用一个小的清洁功能来纠正“错误”,如下所示:
def _deal_with_encoding(url):
# should give no encoding errors since url is ascii
pbs = url.encode('ascii')
# Get a regular (not percent enc) utf8 enc byte str
bs = urllib.unquote(pbs)
# Finally we can decode the utf8 to get correct unicode string
return bs.decode('utf8')
它有效,但似乎并不理想。这真的是唯一的方法吗?