json
什么是json
JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度,
那么,JSON到底是什么?
JSON就是一串字符串 只不过元素会使用特定的符号标注。
{} 双括号表示对象
[] 中括号表示数组
“” 双引号内是属性或值
: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)
所以 {"name": "Michael"}
可以理解为是一个包含name
为Michae
l的对象
而[{"name": "Michael"},{"name": "Jerry"}]
就表示包含两个对象的数组
这里有个图看看
python处理json格式用到的函数
import josn
json.dumps() #将列表或字典转化为json格式的**字符串**。
json.loads() #把json格式的字符串转化为python对象
json.dump() #将列表或字典转化为json格式的字符串并且写入到文件中。
json.load() #从文件中把json格式的字符串转化为python对象
-
json字符串 转换为 字典,列表
import json ## 标准的json格式字符串 data = '[{"name":"爬虫","age":"100"},{"name":"张三","age":"19"}]' list_data = json.loads(data) print(data) print(type(data)) print(list_data) print(type(list_data)) ''' [{"name":"爬虫","age":"100"},{"name":"张三","age":"19"}] <class 'str'> [{'name': '爬虫', 'age': '100'}, {'name': '张三', 'age': '19'}] <class 'list'> # 打印出来好像就长了点,没啥区别,要看看类型 '''
-
列表 转换 json字符串
lt = [ {'name': '位符', 'age': 23}, {'name': '士大夫', 'age': 53}, {'name': '对对对', 'age': 253}, {'name': 'l的发r', 'age': 24} ] str_lt = json.dumps(lt) print(lt) print(type(lt)) print(str_lt) print(type(str_lt)) ''' [{'name': '位符', 'age': 23}, {'name': '士大夫', 'age': 53}, {'name': '对对对', 'age': 253}, {'name': 'l的发r', 'age': 24}] <class 'list'> [{"name": "\u4f4d\u7b26", "age": 23}, {"name": "\u58eb\u5927\u592b", "age": 53}, {"name": "\u5bf9\u5bf9\u5bf9", "age": 253}, {"name": "l\u7684\u53d1r", "age": 24}] <class 'str'> '''
-
写入文件
''' ## 看看以前的写法 lt2 = [ {'name': '位符', 'age': 23}, {'name': '士大夫', 'age': 53}, {'name': '对对对', 'age': 253}, {'name': 'l的发r', 'age': 24}, ] with open ('json2.josn','w') as f: f.write(json.dumps(lt2)) ''' ## 但这个太麻烦了,我们现在用json json.dump(lt2, open('json3.josn', 'w', encoding='utf8'))
-
读取json文件
obj = json.load(open('json3.json', 'r', encoding='utf8')) print(type(obj)) print(obj) ''' <class 'list'> [{'name': '位符', 'age': 23}, {'name': '士大夫', 'age': 53}, {'name': '对对对', 'age': 253}, {'name': 'l的发r', 'age': 24}] '''
json 小伙伴们应该都有了解,下面看CSV
CSV
什么是CSV:
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)
通俗点讲,有点像 Excel
操作
首先呢,这个csv
它不用安装,系统自带的 直接 import csv
就可以用啦 ~~~
import json
import csv
## 不用安装,自带的。
##使用是 我们要生成一个csv写入器
csv.writer() ##传入json文件
writerow()# 写入表头,传入的是字典或列表
writerows()# 写入内容
json文件转csv文件
把json 文件转换成 csv,注意啊,这里必须是标准json格式的文件,上面学json的时候我们生成过一个,就用那个改一改用吧。
- 分别读取json,创建csv文件
import json
import csv
json_fp=open('json_csv.josn','r')
csv_fp = open('csv1.csv','w')
- 提出表头
# json转化为python列表
data_list = json.load(json_fp)
# 提出表头,按我这个文件,返回的是一个列表,里面元素是字典
sheet_title=data_list[0].keys()
print(sheet_title)
## 也可以自己写表头
# sheet_title={"姓名","年龄"}
- 提出内容
sheet_data = []
for data in data_list:
sheet_data.append(data.values())
- 写入csv文件
# 生成csv写入器
writer = csv.writer(csv_fp)
# 写入表头
writer.writerow(sheet_title)
# 写入内容
writer.writerows(sheet_data)
# 关闭两个文件
json_fp.close()
csv_fp.close()
这样就转好了啊,打开看看
不要着急,不要着急,我们看看啊,
我这里是因为,VS Code 和我系统的编码不太一样,我们可以改一下Excel 的编码
文件另存为
或者在工具里
点击web选项
其实不要在VS Code 里打开,直接在电脑上打开就是正常的,VS Code 自动把编码格式转换了,然后保存起来了,所以下次在电脑上打开的时候就乱码了呢
我们可以看一下电脑默认的编码,打开 cmd 输入 chcp
,然后查找对应的地区编码
编码问题就说这么多,不同电脑不太一样,可以试一试然后就知道了。
实例:爬取 All IT eBooks
就是这个网站 ,好多书 All IT eBooks,国外的网站爬取的时候,速度超级慢,,我都想要睡着了。我们就爬取一下 书名,作者,简介,链接就好了
先看看这个网站
也是封装个类来爬取:
- 首先发送请求,获取响应,注意我们要爬取多页,所以需要拼接url
- 解析网页内容,这里我用xpath解析,伙伴们也可以试试bs4
- 保存数据,保存为 json 和 csv (都保存看看)
为了保证代码的完整,,代码后面放图图~~
import requests
import json
from lxml import etree
import csv
import time
class bookSpider(object):
def __init__(self):
self.base_url = 'http://www.allitebooks.org/page/{}'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
self.book_all_list = [] # 用于存放所有的书,每个书是一个字典,然后放在这个列表里
# 得到所有的url ,这里我就爬两页,
def get_url_list(self):
urllist = []
for i in range(1, 3):
url = self.base_url.format(i)
urllist.append(url)
return urllist
# 发送请求
def send_request(self, url):
data = requests.get(url, headers=self.headers).content.decode('utf8')
return data
# 这里我先用字节类型,然后再编码为utf8,为什么我不直接用text()这个方法呢,等会再说
# 解析数据
def parse_data(self, data):
tree = etree.HTML(data)
book_all = tree.xpath('//div/article')
# 看看我的截图,每一本书的信息全部都在article里保存,所以我先获取每一页所有书
# 为了保证代码的完整性,截图放下面了
j=1
for book in book_all:# 再通过xpath解析详细内容,方便保存
book_dict = {}
print('第 %d 本书开始解析'%j)
# 书名
book_dict['book_title'] = book.xpath('.//h2/a/text()')[0]
# 书的详情页链接
book_dict['book_link'] = book.xpath('.//h2/a/@href')[0]
# 图书的封面图片
book_dict['book_img'] = book.xpath('.//a/img/@src')[0]
# 作者,有的书有多个作者
book_author = book.xpath('.//h5/a/text()')
authors = ' , '.join(book_author)
book_dict['author'] = authors
# 简介
book_dict['book_summary'] = book.xpath('.//p/text()')[0]
# 放到列表里
self.book_all_list.append(book_dict)
## print(self.book_all_list)
j=j+1
# 保存数据
def save_data(self):
# 写入json 文件
json.dump(self.book_all_list, open('book.json', 'w', encoding='utf8'))
# 打开csv文件
fp = open('book.csv', 'w', encoding='utf8')
# 提出表头
sheet_title = self.book_all_list[0].keys()
# 提出内容
sheet_data = []
for book in self.book_all_list:
sheet_data.append(book.values())
# csv 写入器
writer = csv.writer(fp)
# 写入表头
writer.writerow(sheet_title)
# 写入内容
writer.writerows(sheet_data)
# 关闭
fp.close()
# 调用跑一下
def run(self):
urllist = self.get_url_list()
for url in urllist:
data = self.send_request(url)
self.parse_data(data)
self.save_data()
if __name__ == "__main__":
bookSpider().run()
这样就爬完了,速度巨慢,,,哭了,我们看一看啊
先看看我xpath 的解析
好了,剩下的就不一 一截图了,都是这个样子的,
但是,这里注意一下,我代码是通过book 又进行了 xpath 的解释,这个时候,就拿上图标题为例,我们路径的要写 .//h2/a/text()
双斜杠前的点 代表的是从当前节点开始,如果没有 点 则是跨节点,会全局查找,数据就比较乱,思路不清晰,有时候可能没有问题,但我们还算习惯把它写精确一些,
刚才代码里还说 先用字节类型,然后再编码为utf8
,为什么我不直接用text()
,也是一样,text()
的编码方式是计算机猜的,不是确定的,所以我们自己给它规定好,减少出错。
还有两个作者的问题,使用join()
方法后也解决了
现在看看结果吧
这个英文什么的有点长,放到csv中反而不太好看,(哭—),今天讲的还算比较多的
就到这里吧,明天我们学习一下MongoDB 这个数据库。(emmmm,具体的明天说吧)
又到了卑微的要赞环节,如果觉得可以学到些什么的话点个赞再走吧,欢迎各位路过的大佬评论指正,有问题也欢迎各位小伙伴们评论,私聊。