Scrapy的中文输出与存储
一、什么是json
json是一种在编程中常用的数据格式,属于一种轻量级的数据交换格式。json数据常见的基本存储结构有数组和对象两种。
数组结构的存储方式:
["苹果","梨子","葡萄"]
这种数组结构的存储方式,对应的值是通过索引的方式进行获取的,对应关系为:0->"苹果",1->"梨子",2->"葡萄"。
对象结构的存储方式:
对象结构的json文件中的数据一般通过{}括起来,里面的数据一般是键值对的形式,键与值之间通过“:”分开,各项数据间通过“,”分开,基本格式为:“{key1:value1,key2:value2...}”,比如:
{"姓名":"hzc","头发":"黑色","皮肤":"黄色"}
Python对象->json对象
import json
dic = {"name":"hzc","sex":"man"}
j1 = json.dumps(dic)
print(dic)
print(j1)
print(type(dic))
print(type(j1))
代码执行结果:
可以看出,json.dumps()函数,它用于将 Python对象编码成json字符串。
下面列出几个常用的参数:
Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(比如中文),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key。
dic = {"name":"hzc",(1,3):"man"} j1 = json.dumps(dic) print(j1) # TypeError: keys must be a string dic = {"name":"hzc",(1,3):"man"} j2 = json.dumps(dic,skipkeys=True) print(j2) # {"name": "hzc"}
ensure_ascii:默认值True,如果dict内含有non-ASCII的字符,则会类似\uXXXX的显示数据,设置成False后,就能正常显示。
dic = {"名字":"hzc","性别":"man"} j3 = json.dumps(dic) print(j3) # {"\u540d\u5b57": "hzc", "\u6027\u522b": "man"} dic = {"名字":"hzc","性别":"man"} j4 = json.dumps(dic,ensure_ascii = False) print(j4) # {"名字": "hzc", "性别": "man"}
indent:可以设置json的缩进格式。
dic = {'b':'I', 'a':123, 'c':'100'} j5 = json.dumps(dic, sort_keys = True, indent = 4) print (j5) # { # "a": 123, # "b": "I", # "c": "100" # }
separators:可以设置json对象的分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(',',':');这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。
dic = {'b':'I', 'a':123, 'c':'100'} j6 = json.dumps(dic, sort_keys = True, separators = ('$','@')) print (j6) # {"a"@123$"b"@"I"$"c"@"100"}
encoding:默认是UTF-8,设置json数据的编码方式。
sort_keys:将数据根据keys的值进行排序。
dic = {'b':'I', 'a':123, 'c':'100'} j7 = json.dumps(dic, sort_keys = True) print (j7) # 输出为:{"a": 123, "b": "I", "c": "100"}
json对象->Python对象
import json
dic = {"name":"hzc","sex":"man"}
j1 = json.dumps(dic)
print(j1)
# {"name": "hzc", "sex": "man"}
decode1 = json.loads(j1)
print(decode1)
# {'name': 'hzc', 'sex': 'man'}
json.loads()函数用于将json对象解码为python对象。
存取json文件
如果要将python对象存到json格式的文件中,此时不再用dumps,而是要用dump:
import json
dic_info = {'name':'hzc', 'sex':'男', 'age':21}
file = open ('E://test.json', 'w', encoding='utf-8')
json.dump(dic_info, file,ensure_ascii=False)
file.close()
如果要从json文件中读取内容存入python对象,不再用loads而是要用load:
import json
file = open ('E://test.json', 'r', encoding='utf-8')
hzc = json.load(file)
file.close()
print(hzc)
print(type(hzc))
二、Scrapy的中文存储
下面,我们来学习如何将Scrapy爬虫爬取到的含有中文的数据,存储为json格式的文件。
在这里我们主要进行的是爬取数据的后续处理,所以主要编写与修改的是一个项目中的pipelines文件。
在这里直接给出spiders文件夹下的爬虫文件:
import scrapy
from hzc.items import HzcItem
class MySpider(scrapy.Spider):
name = "hzc"
start_urls = ['http://www.baidu.com']
def parse(self, response):
item = HzcItem()
item["title"] = response.xpath("/html/head/title/text()")[0].extract()
print(item["title"])
yield item
该爬虫只是一个简单的获取百度网页title的程序,因为重点在于pipelines,所以在此不另讲爬虫。
打开项目对应文件夹中的pipelines文件,然后修改为如下所示,关键部分已给出注释:
import codecs
import json
class HzcPipeline(object):
def __init__(self):
self.file = codecs.open("E://hzc.json","w",encoding="utf-8")
def process_item(self, item, spider):
#通过dic(item)将item转化成一个字典
#然后通过json模块下的dumps()处理字典数据
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
#将line写入到文件中
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
在项目路径下通过执行命令行:scrapy crawl 项目名 得到生成的json文件:
注:在进行json.dumps()序列化的时候,中文信息会默认使用ASCII编码,所以需要把ensure_ascii参数设置为False,不使ASCII进行编码,这样就可以处理中文信息。