在Scrapy中使用unicode刮取百分比编码的URL

时间:2017-05-13 16:01:01

标签: python-2.7 unicode utf-8 scrapy url-encoding

考虑我想要抓取包含以下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'

的utf8字节字符串表示的百分比编码

我用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')

它有效,但似乎并不理想。这真的是唯一的方法吗?

0 个答案:

没有答案