python5 data storage

1 txt file storage

  Normal calling the file python file operations

  https://www.cnblogs.com/x2x3/p/9979919.html

2 json file storage

  

In the JavaScript language, everything is an object. Thus, any type of support can be represented by the JSON, such as strings, numbers, objects, and other arrays, but the special objects and arrays are two common types and, following a brief overview thereof.

  • Object: It is the use of braces in JavaScript {}wrapped up the contents of the data structure as {key1:value1, key2:value2, ...}a key-value pair structure. In object-oriented languages, the keyproperty of the object, valuethe corresponding value. Keys can be used to represent integers and strings. Type values may be of any type.
  • Array: An array is square brackets in JavaScript []wrapped content, the data structure for the ["java", "javascript", "vb", ...]index structure. In JavaScript, the array is a special type of data, it can also be use as key-value pairs like objects, but still much more useful index. Similarly, the type can be any type of value.

So, a JSON object can be written as follows:

  [{

    "name": "Bob",

    "gender": "male",

    "birthday": "1992-10-18"

}, {

     "name": "Selina",

    "gender": "female",

    "birthday": "1995-10-18"

}]

2
3
4
5
6
7
8
9
[ {
     "name" : "Bob" ,
     "gender" : "male" ,
     "birthday" : "1992-10-18"
} , {
     "name" : "Selina" ,
     "gender" : "female" ,
     "birthday" : "1995-10-18"
} ]

Python provides us with easy to use library to read and write operations JSON file, we can call the library loads()method JSON text string to JSON objects, it can dumps()JSON object method will be converted into text strings

Notably, JSON data surrounded with double quotes, not single quotes. For example, using the form represented, an error occurs

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 8)

 

另外,如果JSON中包含中文字符,会怎么样呢?例如,我们将之前的JSON的部分值改为中文,再用之前的方法写入到文本:

import json

data = [{
'name': '王伟',
'gender': '男',
'birthday': '1992-10-18'
}]
with open('data.json', 'w') as file:
file.write(json.dumps(data, indent=2))

json.dumps('中国你好')

'中国你好' 是ascii 字符码,而不是真正的中文。

这是因为json.dumps 序列化时对中文默认使用的ascii编码

想输出真正的中文需要指定ensure_ascii=False

json.dumps中可以放置json字符串,但是也必须指定ensure_ascii=False


---------------------
作者:蜡笔小心丶
来源:CSDN
原文:https://blog.csdn.net/u011615787/article/details/73089523/
版权声明:本文为博主原创文章,转载请附上博文链接!

 

# -*- coding:utf-8 -*-
import json

str = '''
[{
    "name": "木头",
    "gender": "马尾",
    "birthday": "1992-10-18"
}, {
    "name": "Selina",
    "gender": "female",
    "birthday": "1995-10-18"
}]
'''
print(type(str))
data=json.loads(str)
print(type(data))
# 另外,如果想保存JSON的格式,可以再加一个参数indent,代表缩进字符个数
str=json.dumps(data,indent=2,ensure_ascii=False)
print(type(str))
with open('file.txt','w+',encoding='utf-8') as f:
    f.write(str)
    f.flush()
    f.seek(0)
    data=f.read()
    print(json.loads(data))
View Code

 

请千万注意JSON字符串的表示需要用双引号,否则loads()方法会解析失败。

可以看到,中文字符都变成了Unicode字符,这并不是我们想要的结果。

被写入的文件 中文显示为Unicode字符

为了输出中文,还需要指定参数ensure_asciiFalse,另外还要规定文件输出的编码

可以发现,这样就可以输出JSON为中文了

 

3 csv文件存储

  CSV,全称为Comma-Separated Values,中文可以叫作逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔。每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符。不过所有记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。它比Excel文件更加简介,XLS文本是电子表格,它包含了文本、数值、公式和格式等内容,而CSV中不包含这些内容,就是特定字符分隔的纯文本,结构简单清晰。所以,有时候用CSV来保存数据是比较方便的

fieldnames表示,然后将其传给DictWriter来初始化一个字典写入对象,接着可以调用writeheader()方法先写入头信息,然后再调用writerow()方法传入相应字典即可

#csv_write_test
import csv
with open('data.csv','w') as csvfile:
    writer=csv.writer(csvfile)
    writer.writerow(['id', 'name', 'age'])   #写入单行
    writer.writerow(['001','walker','18'])
    writer.writerows([['001','walker','18'],['001','walker','18']])  #写入多行,参数为列表中包含列表

with open('data.csv','w') as csvfile:
    writer=csv.writer(csvfile,delimiter=' ')  #delimiter 指定分隔符
    writer.writerow(['id', 'name', 'age'])
    writer.writerow(['001','walker','18'])

#json 格式的csv存储
with open('json.csv','w') as csvfile:
    #用fieldnames表示,然后将其传给DictWriter来初始化一个字典写入对象,
    # 接着可以调用writeheader()方法先写入头信息,然后再调用writerow()方法传入相应字典即可。
    # 最终写入的结果是完全相同的
    filenames=['id', 'name', 'age']
    writer=csv.DictWriter(csvfile,fieldnames=filenames,delimiter=',')
    #json依然可以传入分隔符;也可以通过writerows写入多行
    writer.writeheader()
    writer.writerow({'id': '10004', 'name': 'Durant', 'age': 22})

#读取csv文件
with open('json.csv', 'r', encoding='utf-8') as csvfile:
    #这里我们构造的是Reader对象,通过遍历输出了每行的内容,每一行都是一个列表形式。
    # 注意,如果CSV文件中包含中文的话,还需要指定文件编码
    reader = csv.reader(csvfile)
    for row in reader:
        print(row)
#另一种读取方法
import pandas  as pd
df = pd.read_csv('data.csv')
print(df)
View Code

 

mysql存储

# -*- coding:utf-8 -*-
import pymysql
db = pymysql.connect(host='localhost',user='root', password='123456', port=3306)
cursor = db.cursor()
#在很多情况下,我们要达到的效果是插入方法无需改动,做成一个通用方法,只需要传入一个动态变化的字典就好了。比如,构造这样一个字典
#然后SQL语句会根据字典动态构造,元组也动态构造,这样才能实现通用的插入方法。所以,这里我们需要改写一下插入方法:
data = {
    'id': '20120001',
    'name': 'Bob',
    'age': 20
}
table = 'students'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
try:
   if cursor.execute(sql, tuple(data.values())):
       print('Successful')
       db.commit()
except:
    print('Failed')
    db.rollback()
db.close()
#这里我们传入的数据是字典,并将其定义为data变量。表名也定义成变量table。接下来,就需要构造一个动态的SQL语句了。

# 首先,需要构造插入的字段id、name和age。这里只需要将data的键名拿过来,然后用逗号分隔即可。+所以
# ', '.join(data.keys())的结果就是id, name, age,然后需要构造多个%s当作占位符,有几个字段构造几个即可。比如,
# 这里有三个字段,就需要构造%s, %s, %s。这里首先定义了长度为1的数组['%s'],然后用乘法将其扩充为['%s', '%s', '%s'],
# 再调用join()方法,最终变
# INSERT INTO students(id, name, age) VALUES (%s, %s, %s)
View Code

 

三 非关系型数据库mongodb

NoSQL,全称Not Only SQL,意为不仅仅是SQL,泛指非关系型数据库。NoSQL是基于键值对的,而且不需要经过SQL层的解析,数据之间没有耦合性,性能非常高

对于爬虫的数据存储来说,一条数据可能存在某些字段提取失败而缺失的情况,而且数据可能随时调整。另外,数据之间还存在嵌套关系。如果使用关系型数据库存储,一是需要提前建表,二是如果存在数据嵌套关系的话,需要进行序列化操作才可以存储,这非常不方便。如果用了非关系型数据库,就可以避免一些麻烦,更简单高效。

  MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象

连接mongodb

连接MongoDB时,我们需要使用PyMongo库里面的MongoClient。一般来说,传入MongoDB的IP及端口即可,其中第一个参数为地址host,第二个参数为端口port(如果不给它传递参数,默认是27017):

import pymongo
client = pymongo.MongoClient(host='localhost', port=27017)

这样就可以创建MongoDB的连接对象了。

 

另外,MongoClient的第一个参数host还可以直接传入MongoDB的连接字符串,它以mongodb开头,例如:

client = MongoClient('mongodb://localhost:27017/')

指定数据库

MongoDB中可以建立多个数据库,接下来我们需要指定操作哪个数据库。这里我们以test数据库为例来说明,下一步需要在程序中指定要使用的数据库

 db = client.test

4. 指定集合

MongoDB的每个数据库又包含许多集合(collection),它们类似于关系型数据库中的表。

下一步需要指定要操作的集合,这里指定一个集合名称为students。与指定数据库类似,指定集合也有两种方式

  collection = db.students

  collection = db['students']

5. 插入数据

在MongoDB中,每条数据其实都有一个_id属性来唯一标识。如果没有显式指明该属性,MongoDB会自动产生一个ObjectId类型的_id属性。insert()方法会在执行后返回_id

实际上,在PyMongo 3.x版本中,官方已经不推荐使用insert()方法了。当然,继续使用也没有什么问题。官方推荐使用insert_one()insert_many()方法来分别插入单条记录和多条记录

student = {

    'id': '20170101',
    'name': 'Jordan',
    'age': 20,
    'gender': 'male'
}
 
result = collection.insert_one(student)
print(result)
print(result.inserted_id)

insert()方法不同,这次返回的是InsertOneResult对象,我们可以调用其inserted_id属性获取_id

对于insert_many()方法,我们可以将数据以列表形式传递

insert()方法不同,这次返回的是InsertOneResult对象,我们可以调用其inserted_id属性获取_id

对于insert_many()方法,我们可以将数据以列表形式传递,示例如下

student1 = {
'id': '20170101',
'name': 'Jordan',
'age': 20,
'gender': 'male'
}

student2 = {
'id': '20170202',
'name': 'Mike',
'age': 21,
'gender': 'male'
}

result = collection.insert_many([student1, student2])
print(result)
print(result.inserted_ids)

该方法返回的类型是InsertManyResult,调用inserted_ids属性可以获取插入数据的_id列表

6. 查询

find_one()find()方法进行查询,其中find_one()查询得到的是单个结果,find()则返回一个生成器对象

result = collection.find_one({'name': 'Mike'})
print(type(result))
print(result)

对于多条数据的查询,我们可以使用find()方法

results = collection.find({'age': 20})

print(results)
for result in results:
    print(result)

表5-3 比较符号

符号

含义

示例

$lt

小于

{'age': {'$lt': 20}}

$gt

大于

{'age': {'$gt': 20}}

$lte

小于等于

{'age': {'$lte': 20}}

$gte

大于等于

{'age': {'$gte': 20}}

$ne

不等于

{'age': {'$ne': 20}}

$in

在范围内

{'age': {'$in': [20, 23]}}

$nin

不在范围内

{'age': {'$nin': [20, 23]}}

 

更高级查询

表5-4 功能符号

符号

含义

示例

示例含义

$regex

匹配正则表达式

{'name': {'$regex': '^M.*'}}

name以M开头

$exists

属性是否存在

{'name': {'$exists': True}}

name属性存在

$type

类型判断

{'age': {'$type': 'int'}}

age的类型为int

$mod

数字模操作

{'age': {'$mod': [5, 0]}}

年龄模5余0

$text

文本查询

{'$text': {'$search': 'Mike'}}

text类型的属性中包含Mike字符串

$where

高级条件查询

{'$where': 'obj.fans_count == obj.follows_count'}

自身

7. 计数

要统计查询结果有多少条数据,可以调用count()方法

count = collection.find().count()
print(count)

 或者统计符合某个条件的数据:

count = collection.find({'age': 20}).count()
print(count)

8. 排序

排序时,直接调用sort()方法,并在其中传入排序的字段及升降序标志即可。示例如下:

 

11

 

运行结果如下:

 

 

这里我们调用pymongo.ASCENDING指定升序。如果要降序排列,可以传入pymongo.DESCENDING

 
 

11. 删除

删除操作比较简单,直接调用remove()方法指定删除的条件即可,此时符合条件的所有数据均会被删

result = collection.remove({'name': 'Kevin'})
print(result)

另外,这里依然存在两个新的推荐方法——delete_one()delete_many()

result = collection.delete_one({'name': 'Kevin'})
print(result)
print(result.deleted_count)
result = collection.delete_many({'age': {'$lt': 25}})
print(result.deleted_count)

delete_one()即删除第一条符合条件的数据,delete_many()即删除所有符合条件的数据。它们的返回结果都是DeleteResult类型,可以调用deleted_count属性获取删除的数据条数

Guess you like

Origin www.cnblogs.com/x2x3/p/10923757.html