首页 > 代码库 > scrapy抓取的页面中文会变成unicode字符串

scrapy抓取的页面中文会变成unicode字符串

不了解编码的,需要先补下:http://www.cnblogs.com/jiangtu/p/6245264.html

现象:从scrapy抓取的页面中文会变成unicode字符串,如下图

2017-03-28 23:00:12 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.lagou.com/jobs/2617468.html>
{‘describe‘: [u‘<div>\n        <p>\u5c97\u4f4d\u804c\u8d23</p>\n<p>\u8d1f\u8d23\u7f51\u7ad9\u4e0b\u8f7d\u5185\u5bb9\u7684\u65e5\u5e38\u66f4\u65b0\u7ef4\u62a
4\u4e0e\u5ba1\u6838</p>\n<p>\u8d1f\u8d23\u7ef4\u62a4\u7f51\u7ad9\u5404\u76f8\u5173\u9875\u9762\u7684\u65e5\u5e38\u66f4\u65b0\u63a8\u8350</p>\n<p>\u8d1f\u8d2
3\u8ddf\u8fdbSEO\u90e8\u95e8\u7684\u65b9\u6848\u5b9e\u65bd\u548c\u76f8\u5173\u9879\u76ee\u8ddf\u8fdb</p>\n<p>\u8f85\u52a9\u4e3b\u7f16\u534f\u8c03\u7ba1\u740
6\u548c\u5b89\u6392\u7f51\u7ad9\u5185\u90e8\u4eba\u5458\u7684\u5de5\u4f5c</p>\n<p><br></p>\n<p>\u5c97\u4f4d\u8981\u6c42</p>\n<p>\u7535\u8111\u548c\u624b\u67
3a\u64cd\u4f5c\u719f\u7ec3\uff0c\u638c\u63e1\u529e\u516c\u8f6f\u4ef6\u3001\u5b89\u5168\u8f6f\u4ef6\u548c\u56fe\u7247\u5904\u7406\u8f6f\u4ef6\u7684\u57fa\u67
2c\u4f7f\u7528</p>\n<p>\u4e86\u89e3\u76ee\u524d\u4e3b\u6d41\u7684\u70ed\u95e8PC\u8f6f\u4ef6/\u624b\u673a\u5e94\u7528/\u624b\u673a\u6e38\u620f\uff0c\u5bf9\u6
5b0\u5947\u7279\u7684\u8f6f\u4ef6\u6709\u4e00\u5b9a\u7684\u654f\u611f\u5ea6</p>\n<p>\u6709\u8d23\u4efb\u5fc3\u3001\u6709\u6c9f\u901a\u548c\u5b66\u4e60\u80fd
\u529b\uff0c\u80fd\u5403\u82e6\u8010\u52b3\u3001\u6027\u683c\u5f00\u6717</p>\n<p>\u6709SEO\u57fa\u7840\u6216\u76f8\u5173\u7f16\u8f91\u7ecf\u9a8c\u4f18\u5148
</p>\n<p><br></p>\n<p>\u85aa\u8d44\u5f85\u9047</p>\n<p>\u5de5\u4f5c\u65f6\u95f4\uff1a\u4e0a\u534810\uff1a00\u81f3\u4e0b\u534819\uff1a00\uff1b</p>\n<p>\u85aa
\u8d44\u7ed3\u6784\uff1a\u57fa\u672c\u5de5\u8d44+\u5c97\u4f4d\u5de5\u8d44+\u7ee9\u6548\u5de5\u8d44+\u5348\u9910\u8865\u52a9+\u591c\u9910\u8865\u52a9+\u6253u8f66\u8d39\u62a5\u9500+\u4e94\u9669\u4e00\u91d1+\u5e74\u7ec8\u5956\u7b49</p>\n<p>\u5176\u4ed6\u798f\u5229\uff1a\u53cc\u4f11+\u6cd5\u5b9a\u5047\u65e5\u4f11+
\u8fc7\u8282\u8d39/\u8282\u65e5\u793c\u54c1+\u5e74\u4f11\u5047\u7b49</p>\n\n        </div>‘],
 ‘title‘: [u‘\u7f51\u7ad9\u7f16\u8f91‘],
 ‘url‘: ‘https://www.lagou.com/jobs/2617468.html‘}

这个response的截图

技术分享

我取红框中的字符串(utf-8编码)做了本地处理,下图是此字符串对应的中文。

技术分享

然后在本地做了如下测试:

技术分享

可以看到,字符串本地查看时就是 unicode 字符串格式。print打印时会改变

 1 >>> s=u\u7f51
 2 >>> y={"a":s}
 3 >>> y
 4   {a: u\u7f51}
 5 >>> import json
 6 >>> t=json.dumps(y)
 7 >>> t
 8   {"a": "\\u7f51"}
 9 >>> fi=open(rC:\Users\zhensheng\Desktop\123,w)
10 >>> fi.write(t)
11 >>> fi.close()
12 >>> fii=open(rC:\Users\zhensheng\Desktop\123,r)
13 >>> tt=fii.readlines()
14 >>> tt
15   [{"a": "\\u7f51"}]
16 >>> json.loads(tt[0])
17   {ua: u\u7f51}
18 >>>

文件中的内容为:

{"a": "\u7f51"}

直接向文件中写  u‘\u7f51‘ 会报错,因为默认以ascii写入,然后碰到 第一个u 会报错。所以我将其用 json 序列化后写到文件里了

可以看到,读出的内容前加了 u 。

虽然我还是没弄懂为什么。。

捋一下流程:首先,Spider发送Request,网站返回了 Response,由于网络传输的原因,必然Response.body中的中文被utf-8编码转码了。所以是 \x..样式。然后,Scrapy对其进行处理,中间肯定有对其进行转码的过程,此处应该是正确将其编码了。就跟上图中的红框 Scrapy2jsonStr 显示的,是以u开头的,此时如果 print,是可以显示中文的,但是,由于Scrapy接下来对其进行了Json序列化以及某些包装处理,(若只有json序列化,应当为 {u‘a‘: u‘\u7f51‘} 这种形式,见上方代码16~17行)。所以 最后Scrapy输出的是{‘describe‘: [u‘<div>\n  \u..‘]}这种样式。其中, [u‘<div>\n  \u..‘]是list,因为Scrapy默认你匹配到的是多个(参考选择器里有addxpath,可见一斑)。

或许就是因为 Python 默认存储使用 unicode 方式的原因吧。(不知从那瞄得,忘记了)

虽不知确切原因,但是目前只能按以下方案暂行处理了:

  在 Pipeline 中对字段进行处理,只去列表中的第一个元素,这样,提取到的Json文档变为:{‘describe‘: u‘<div>\n  \u..‘},然后,若要print输出,则直接 print result[‘describe‘]即可,若要输出到文件,则对其进行编码即可: fi.write(result[‘describe‘].encode(‘utf-8‘))。

关于windows powershell输出还有坑,有兴趣的可以看下:http://www.cnblogs.com/jiangtu/p/6608212.html

 

scrapy抓取的页面中文会变成unicode字符串