网络爬虫之数据存储方式(json、csv、mysql)

一、JSON文件存储

JSON,全称为 JavaScript 0bject Notation,也就是JavaSript 对象标记,它通过对象和数组的组合来表示数据,构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式。本节中,我们就来了解如何利用 Python 保存数据到SON 文件中。

(一)对象和数组

在JavaScript 语言中,一切都是对象。因此,任何支持的类型都可以通过JSON 来表示,例如如字串、数字、对象、数组等,但是对象和数组是比较特殊且常用的两种类型,下面简要介绍一下它们。

对象:

它在JavaScript 中是使用花括号 包裹起来的内容,数据结构为{key1: value1,key2: value2,.}的键值对结构。在面向对象的语言中,key 为对象的属性,value 为对应的值,键名可以使用整数和字符串来表示。值的类型可以是任意类型。

数组:

数组在JavaScript 中是方括号包裹起来的内容,数据结构为["Java""JavaScript",“vb”...] 的索引结构在Javascript 中,数组是一种比较特殊的数据类型,它也可以像对象那样使用键值对,但还是索引用得多。同样,值的类型可以是任意类型。

所以,一个JSON 对象可以写为如下形式:

[
  {
    "name": "张三",
    "age": "24",
    "birthday": "1999-07-12"
  },
  {
    "name": "李四",
    "age": "26",
    "birthday": "1999-08-12"
  }
]

由中括号包围的就相当于列表类型,列表中的每个元素可以是任意类型,这个示例中它是字典类型,由大括号包围。
JSON 可以由以上两种形式自由组合而成,可以无限次嵌套,结构清晰,是数据交换的极佳方式。

(二)数据写入规范

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

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

import json

date = [{
    'name':'李绍幸',
    'age':'24',
    'birthday':'1999-07-12'
}]
# w写 r读 a追加
with open('D:\桌面\date.json','w',encoding='utf-8') as file:
    # dumps通常是指json.dumps方法,它来源于内置的json模块。
    # 该方法用于将Python对象序列化为JSON格式的字符串。
    # 序列化是指将数据结构或对象状态转换成可存储或传输的格式的过程。
    #indent指定缩进级别为2,
    # ensure_ascii: 默认为 True,
    # 意味着所有非ASCII字符都会被转义成 \uXXXX 序列。如果设置为 False,这些字符将原样输出。
    file.write(json.dumps(date,indent=2,ensure_ascii=False))

二、CSV文件存储

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

(一)写入

简单例子:

import csv

# 以列表形式写入
with open('data.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['id', 'name', 'age'])
    writer.writerow(['10001','Mike',20])
    writer.writerow(['10002','Bob',22])
    writer.writerow(['10003','Jordan',21])

import pandas
dic = {
     '1':'张三',
     '2':'李四',
     '3':'王五'
    }
df = pd.DataFrame(dic)
df.to_csv('demo.csv',index=None)

首先,打开 data.csv 文件,然后指定打开的模式为 w (即写入),获得文件句柄,随后调用 csv 库的 writer 方法初始化写入对象,传入该句柄,然后调用 writerow 方法传入每行的数据即可完成写入。

如果想修改列与列之间的分隔符,可以传入 delimiter 参数,其代码如下:

import csv

# 以列表形式写入
with open('data.csv', 'w') as csvfile:
    writer = csv.writer(csvfile,delimiter='')
    writer.writerow(['id', 'name', 'age'])
    writer.writerow(['10001','Mike',20])
    writer.writerow(['10002','Bob',22])
    writer.writerow(['10003','Jordan',21])

(二)多行写入

调用 writerows 方法同时写入多行,此时参数就需要为二维列表,例如:

import csv

# 以列表形式写入
with open('data.csv', 'w') as csvfile:
    writer = csv.writer(csvfile,delimiter='')
    writer.writerow(['id', 'name', 'age'])
    writer.writerows([['10001','Mike',20],['10002','Bob',22],['10003','Jordan',21]])

(三)字典写入

用字典来表示。在 csv 库中也提供了字典的写入方式,示例如下:

import csv
with open('data.csv','w') as csvfile:
    fieldnames =['id','name','age']
    # 定义一个列表 fieldnames,其中包含我们希望出现在 CSV 文件第一行的字段名,
    # 它们作为列标题。
    writer = csv.DictWriter(csvfile,fieldnames=fieldnames)
    # 调用 writer.writeheader() 方法写入列标题。
    # 这会基于 fieldnames 列表中的字段名在 CSV 文件中创建第一行
    writer.writeheader ()
    writer.writerow({'id': '10001','name':'Mike','age': 203})
    writer.writerow({'id': '10002','name':'Bob','age' : 22})
    writer.writerow({'id':'10003','name':'jordan','age': 21})

这段代码执行完成后,将会在当前目录下创建(或覆盖)一个名为 data.csv 的文件,内容如下:

id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21

(四)excel写入

from openpyxl import Workbook
import random

'''
数据写入格式
列表嵌套列表 数据按列表的行写入
    第一列表示第一行,第二列表示第二行
    [[],[],[]]
'''
#空白文件
wb = Workbook()
# 空白页 内容插入工作簿中索引为 0 的位置
ws = wb.create_sheet('第一页',index=0)
ws.append(['编号','姓名','年龄'])
for i in range(10):
    id = str(i)
    name = str('li'+ str(i))
    age = random.randint(18,30)
    ws.append([id,name,age])
wb.save('li.xlsx')

(五)爬虫采集入库

import httpx
import csv
res = httpx.get('https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1702977319532&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=python&pageIndex=2&pageSize=10&language=zh-cn&area=cn')

# 将数据变成字典格式
items = res.json()

data = []
# 或者data = list()
item = items.get('Data')['Posts']#列表形式
for i in item:
    title = i.get('RecruitPostName')
    time = i.get('LastUpdateTime')
    data.append([title,time])
print(data)

with open('date.csv','w',encoding='gbk')as csvfile:
    writer = csv.writer(csvfile,delimiter=',')
    writer.writerow(['title','time'])
    writer.writerows(data)
    print('写入成功')

三 关系型数据库

关系型数据库是基于关系模型的数据库,而关系模型是通过二维表来保存的,所以它的存储方式就是行列组成的表,每一列是一个字段每一行是一条记录。表可以看作某个实体的集合,而实体之间存在联系,这就需要表与表之间的关联关系来体现,如主键外键的关联关系。多个表组成一个数据库,也就是关系型数据库。

关系型数据库有多种,如 SQLite、MySQL、Oracle、SQL Server、DB2等.

(一)安装数据库使其正常运行,并安装pymysql第三方库

(二)连接数据库

这里,首先尝试连接一下数据库。假设当前的 MVSQL运行在本地,用户名为 root,密码为 123456,运行端口为 3306,这里利用PyMySQL 先连接 MySQL,然后创建一个新的数据库,名字叫作 spiders,代码如下:

import pymysql
db = pymysql.connect(host='localhost',user='root',password='123456',port=3306)
cursor = db.cursor()
cursor.execute('select version()')
# 使用fetchone获取SQL语句执行结果的第一行数据
data = cursor.fetchone()
print('database version:',data)
cursor.execute('create database if not exists spiders default character set utf8')
cursor.execute('use spiders')
sql = "CREATE TABLE If NOT EXISTS students(id VARCHAR(255)NOT NULL,NAME VARCHAR(255)NOT NULL,age INT NOT NULL,PRIMARY KEY(id))"
cursor.execute(sql)
db.close()

(三)创建数据表

import pymysql
db = pymysql.connect(host='localhost',user='root',password='123456',port=3306)
cursor = db.cursor()
cursor.execute('create database if not exists spiders default character set utf8')
cursor.execute('use spiders')
sql = "CREATE TABLE If NOT EXISTS students(id VARCHAR(255)NOT NULL,NAME VARCHAR(255)NOT NULL,age INT NOT NULL,PRIMARY KEY(id))"
cursor.execute(sql)
db.close()

(四)插入数据

插入、更新和删除操作都是对数据库进行更改的操作,而更改操作都必须为一个事务,所以这些操作的标准写法就是:

具体的参照:mysql第14天之TCL(事务控制语言)-CSDN博客

import pymysql
id = '1'
user = 'lili'
age = 20
# 连接数据库
db = pymysql.connect(host='localhost',user='root',password='123456',port=3306)
cursor = db.cursor()
sql = 'INSERT INTO students VALUES(%s,%s,%s)'

try:
    cursor.execute(sql,(id,user,age))
    # 提交
    db.commit()
except:
    # 回滚
    db.rollback()
db.close()

(五)字典数据插入

import pymysql
data = {
    'id':'20220315',
    'name':'菲菲',
    'age':20}
db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='spiders')
cursor = db.cursor()
keys  = ','.join(data.keys())
values = ','.join(['%s'])*len(data)
sql = 'INSERT INTO students({keys}) VALUES({values})'.format(keys=keys,values=values)
try:
    if cursor.execute(sql,tuple(data.values())):
        print("Successful!")
        db.commit()
except:
    print("Failed")
    db.rollback()
db.close()

四 Elasticsearch搜索引擎存储

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文博索引擎,基RESTful web接口,Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

重要特性:

分布式的实时文件存储,每个字段都被索引并可被搜索

实时分析的分布式搜索引擎

可以扩展到上百台服务器,处理PB级别结构化或非结构化数据

基本概念:

索引(indlices)-----------database数据库

类型(type)----------------Table表

文档(Document)---------Row行

字段(Field)-----------------Columns列

要注意的是:Elastiearch 本身就是分布式的,因此便你只有一个节点,Elasticsearch 认也会对你的教据进行分片和副本操作,当你向集群添加新数据时,数据也会在新加入的节点中进行平衡。

(一)安装服务端

地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值