爬取与数据存储

ch5. 数据存储

  • 文件存储
  • JSON文件存储
  • 关系型数据库存储
  • Mysql

1. JSON文件存储

1. JSON中的对象和数组
  • *对象

​ 格式为 {key1:value1, key2:value2}. 其中键名可以为字符串, 整数, 值可以为任意类型

  • *数组

​ 格式为 ['content1', 'content2', ....], 值可以为任意类型
2. JSON的读取

  • json.loads(): 该方法需要读取对象的格式符合JSON文件格式的要求。输出结果为列表,可以对接过使用索引等操作。
  • 可以接受字符串,也可以接受文本文件。如:
import json
with open('data.json', 'r') as f:
    str = file.read()
    data = json.loads(str)
**3. JSON的输出**
* .dumps(): 该方法将json格式的对象转为字符串,若要将其输出至文件,还需要配合write()和open()方法。如:


import json
data = ...#data是符合json格式的对象
with open('data.json','w', encoding = 'utf-8') as f:
    file.write(json.dumps(data, ensure_ascii = False))
#若json中含有中文就需在open()中指定encoding='utf-8', write()中指定ensure_ascii = False

2. 关系型数据库—MySQL的存储

1. 链接到数据库及相关基本操作

  • pysql.connect(host = 'localhost', user = 'root', password = '*****', port(3306)): 成功连接后返回一个数据库对象 (令之为db),利用该数据库对象我们可以对数据库进行增添改查等操作。 参数说明
  • host,默认为localhost
  • user,登录数据库的用户名
  • password,数据库的密码
  • port,数据库端口,默认为3306
  • db.close(): 在操作完毕后需要将数据库对象关闭。
  • db.cursor(): 对数据库进行各种操作要通过cursor()方法返回的游标 _(令之为cr)_来进行。
  • cr.execute('sqlSentence') : 执行语句
  • cr.fetchone(): 取回sql中返回的结果
  • db.roolback(): 确保操作为原子操作,保持数据的一致性,即若失败则回退
  • db.commit(): 插入、更行等操作在执行完 db.execute()后还需要执行该方法才能真正是的操作生效

2. 创建表

创建表的操作关键在于sql语句的书写,以如下代码为例:

import pymqsql
db = pymysql.connect(host = 'localhost', user = 'root', password = '******', port = 3306, db = 'spider')
cr = db.cursor()
sqlSen = 'CREATE TABLE IF NOT EXISTS stuents(id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, age INT NOT NULL, PRIMARY KEY(id))'
cr.execute(sql)
db.close()

3. 插入数据(动态)

  • 静态插入语句:用拼接字符串的方式来完成
id = '1716240306'
user = 'bob'
age = '20'
db = pysql.connect(...)
cr = db.cursor()
sqlSen = 'INSERT INTO students(id, name, age)' values(%s, %s, %s)
try:
    cr.execute(sql, (id, user, age))
    db.commit()
except:
    db.roolback()
  • 动态插入语句
data = {
    'id':'1716240306',
    'name':'xzy',
    'age':20,
    'gender':'male'
}
tableS = 'studentes'# 用变量保存字段,以便于修改、调用
keysS = ','.join(data.keys())# 用','将data中的键分隔开,以供函数调用使用
valusS = ','.join(['%s'] * len(data))# '['%s'] * 3' == '['%s', '%s', '%s']'
sqlSen = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=tableS, keys = keysS, values = valuesS)
#str.format()用于填补字符串,填补入字符串中的{},format()中填入要填补的内容,从左向右按序填入。若字串中占位符形式为{argName},则需要在参数中使用argName=value的形式来传递参数
try:
    if cr.execute(sqlSen, tuple(data.values())):  #tuple()元组返回列表,以供sql语句提供参数
        print('successful')
        db.commit()
except:
    print('failed')
    db.roolback()
db.close()
  • 不重复的更新数据
data = {
    'id':'1716240306',
    'name':'xzy',
    'age':20,
    'gender':'male'
}
tableS = 'students'
keysS = ','.join(data.keys())
valuesS = ','.join(['%s']*len(data))
#['%s']*3 == ['%s','%s','%s']
sqlSen = 'INSERT INTO {table}({keys}) VALUES({values}) ON DUPLICATE KEY UPDATE'.format(table = tableS, keys = kyesS, value = valuesS)
#'ON DUPLICATE KEY UPDATE'表示若主键存在就执行更新操作,否则执行插入操作。
updatePart = ','.join(["{key} = %s".format(key = keyS) for key in data])
#In[13]: (["{key} = %s".format(key = keysS) for key in data])
#Out[13]: ['id = %s', 'name = %s', 'age = %s', 'gender = %s']
sqlSen += updatePart
try:
    if cr.execute(sqlSen, tuple(data.values())*2):
#因为在加入更新语句后sqlSen中共有六处需要填进参数,所以需要参数处需要'*2'
        db.commit()
        print('successful')
except:
    db.rollback()
    print('failed')
db.close
  • 查询数据
sqlSen = 'SELECT * FROM students WHERE age >= 20'
try:
    cr.execute(sqlSen)
    print('Count:',cr.rowcount)
    one = cr.fetchone()
    #从sql服务取回了一条结果,随后在sql中的指针自动向后偏移一位
    print('one row: ', one)
    results = cr.fetchall()
    #results保存了sql剩余的所有结果,(有一条结果被fetchone取走)
    pritn('results:', results)
    for aRow in results:
        print(aRow)
except:
    print('error')

Original: https://www.cnblogs.com/dysonxxxxx/p/16582046.html
Author: dysonkkk
Title: 爬取与数据存储

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/578854/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球