对爬虫爬取到的数据进行存储


已写章节

第一章 网络爬虫入门
第二章 基本库的使用
第三章 解析库的使用
第四章 数据存储
第五章 动态网页的抓取


第四章 数据存储


用解析库提取出我们想要的数据之后,接下来就是存储数据了。保存的形式有很多,可以直接保存为文本文件,如:TXT,JSON,CSV等。也可以存储到数据库中,如关系型数据库MySQL,非关系型数据库MongoDB等。


4.1 文件存储


4.1.1 TXT文件存储

import requests
from lxml import etree
from fake_useragent import UserAgent

# 将解析后的数据存储为TXT文件
headers = {
    'user-Agent': UserAgent().chrome
}
response = requests.get('https://www.baidu.com/', headers=headers)
html = etree.HTML(response.text, etree.HTMLParser())
#爬取百度热榜
news = html.xpath('//*[@id="hotsearch-content-wrapper"]/li/a/span[2]/text()')
print(news)
with open('baiduHotNews.txt', 'w', encoding='utf-8') as file_object:
    for i in news:
        file_object.write(i+'\n')

运行后当前文件夹中将新建一个名为baiduHotNews.txt的文本文件,我的文件中的内容为:

女记者称遭家暴 丈夫:她也家暴我
3人冒充老干妈员工骗腾讯被公诉
就地过年是否允许亲友聚会?
印度山洪暴发 或致100多人死亡
石家庄藁城区调整为中风险
专门针对冷链的消毒剂来了

上面只是一个简单的例子,如果遇到更复杂的将爬取到的数据存储到TXT文件中,就需要大家复习Python中的文件读取的相关知识了!


4.1.2 JSON文件的存储


JSON(JavaScript Object Notation),它是JavaScript对象标记,它通过对象和数据的组合来表示数据,构造简洁,但是结构化程度非常高,是一种轻量级的数据交换格式。

Python3中使用json模块来对JSON数据进行编码和解码,对应于下面两个函数:

  • json.dumps():对数据进行编码
  • json.loads():对数据进行解码

使用json.dumps()方法将字典编码为JSON

import json

# 使用json.dumps()方法将字典编码为JSON
dic_data = {
    'id': '12345',
    'name': 'Tom',
    'age': 12
}
json_data = json.dumps(dic_data)
print(type(json_data))
print(json_data)

运行结果:

<class 'str'>
{"id": "12345", "name": "Tom", "age": 12}

使用json.loads()方法将json解码为字典

import json

# 使用json.loads()方法将JSON解码为字典
json_data = '{ "id":"12345","name":"Tom","age":12}'
dic_data = json.loads(json_data)
print(type(dic_data))
print(dic_data)

运行结果:

<class 'dict'>
{'id': '12345', 'name': 'Tom', 'age': 12}


4.1.3 CSV文件的存储


CSV(Comma-Separated Values,逗号分隔符)是存储表格数据常用的文件格式。Microsoft Excel、WPS表格等许多应用都支持CSV。说白了,csv文件就是Excel表格。


下面是一个CSV文件的例子:

fruit,price

apple,3.0

banana,3.5

每一行都用一个换行符分隔,列与列之间通常用逗号分隔。


Python中有一个很好用的库,它可以读写csv文件,它是csv库。

csv库文档



4.1.3.1 CSV文件的写入

先让我们看一个小例子:

import csv

# 一个写入csv文件的小例子
with open('file0.csv', 'a') as file_object:    # 以附加写模式打开文件file0.csv,并创建文件对象
    writer = csv.writer(file_object)            # 初始化写入对象
    writer.writerow(['fruit', 'date', 'price'])   # 写入一行数据
    writer.writerow(['apple', '2021-02-08', '3.5'])
    writer.writerow(['banana', '2021-07-07', '4.0'])
    writer.writerow(['strawberry', '2021-04-01', '10.0'])

'a'指的是附加写模式,如果打开的文件不存在,则会自动创建该文件,运行完之后,将在当前python程序所在目录中生成一个file0.csv文件,其中的内容为:

fruit,date,price

apple,2021-02-08,3.5

banana,2021-07-07,4.0

strawberry,2021-04-01,10.0

file0.csv文件也可以用Excel打开。



更改列与列之间的分隔符

使用delimiter参数更改列与列之间的分隔符:

import csv

# 使用delimiter参数控制列与列之间的分隔符
with open('file1.csv', 'a') as file_object:    # 以附加写模式打开文件file0.csv,并创建文件对象
    writer = csv.writer(file_object, delimiter='|')            # 初始化写入对象
    writer.writerow(['fruit', 'date', 'price'])   # 写入一行数据
    writer.writerow(['apple', '2021-02-08', '3.5'])
    writer.writerow(['banana', '2021-07-07', '4.0'])
    writer.writerow(['strawberry', '2021-04-01', '10.0'])

file1.csv中的内容为:

fruit|date|price

apple|2021-02-08|3.5

banana|2021-07-07|4.0

strawberry|2021-04-01|10.0

可以看到,列与列之间的分隔符被该成了|



一次写入多行

writerow()方法一次只能写入一行,使用writerows()方法能一次写入多行,但writerows()方法接收的是二维列表:

import csv

# 使用writerows()方法一次将多行数据写入CSV文件
with open('file2.csv', 'a') as file_object:
    writer = csv.writer(file_object)
    writer.writerow(['fruit', 'date', 'price'])
    writer.writerows([['apple', '2021-02-08', '3.5'],
                      ['banana', '2021-07-07', '4.0'],
                      ['strawberry', '2021-04-01', '10.0'], ])

file2.csv中的内容为:

fruit,date,price

apple,2021-02-08,3.5

banana,2021-07-07,4.0

strawberry,2021-04-01,10.0

将字典写入csv文件中

import csv

# 将字典信息写入csv文件
with open('file3.csv', 'a') as file_object:
    fieldnames = ['fruit', 'date', 'price']
    writer = csv.DictWriter(file_object, fieldnames=fieldnames)  # 初始化一个字典写入对象
    writer.writeheader()     # 写入头信息
    writer.writerow({'fruit': 'apple', 'date': '2021-02-08', 'price': '3.5'})  # 写入字典信息
    writer.writerow({'fruit': 'banana', 'date': '2021-07-07', 'price': '4.0'})
    writer.writerow({'fruit': 'strawberry', 'date': '2021-04-01', 'price': '10.0'})


指定写入的字符编码

如果将中文写入文件中,可能会出现乱码,就需要给open()方法中指定编码格式:

import csv

# 写入CSV文件并指定编码方式
with open('file4.csv', 'a', encoding='utf-8') as file_object:
    fieldnames = ['fruit', 'date', 'price']
    writer = csv.DictWriter(file_object, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'fruit': 'banana', 'date': '2021-02-08', 'price': '3.5'})


4.1.3.2 CSV文件的读取

以上面的file4.csv文件为读取的对象,读取其中的内容:

import csv

# 读取csv文件中的数据的简单小例子
with open('file4.csv', 'r') as file_object:
    read = csv.reader(file_object)
    for i in read:
        if i:
            print(i)

运行结果:

['fruit', 'date', 'price']
['banana', '2021-02-08', '3.5']

另外一种比较简单读取csv文件中的数据的方法是使用pandas中的read_csv()方法来读取:

使用pandas库之前需要安装pandas库,可以使用豆瓣源加快下载速度,

将pip的下载源改为豆瓣,以提高下载速度:

pip install pandas -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

import pandas as pd

# 使用pandas.read_csv()方法读取CSV文件
data = pd.read_csv('file4.csv')
print(data)

运行结果:

    fruit        date  price
0  banana  2021-02-08    3.5


4.2 关系型数据库存储

关系型数据库是基于关系模型的数据库,而关系模型是通过二维表来保持的,所以它的存储方式就是行列组成的表,每一列就是一个字段,每一行就是一条记录。

常见的关系型数据库有Mysql、SQLite、Oracle、SQL Server、DB2等。



4.2.1 将数据存储在Mysql中



4.2.1.1 准备工作
  • 需要安装MySQL

  • Python和MySQL数据库相连,需要使用驱动,Python中常用于和MySQL连接的驱动有PyMySQLmysql-connector ,它们两个很相似,学会其中的一个就可以了,我们以PyMySQL为例。

    在cmd中使用如下的命令来安装pymysql:

    pip install pymysql



4.2.1.2 使用PyMySQL实现和mysql的交互

  • 连接数据库并测试是否连接成功

    import pymysql
    
    conn = pymysql.connect(  # 构造连接
        host='localhost',
        user='root',
        password='123456',  //记得更改为你的用户名、密码、端口号
        port=3306,
    )
    //测试是否连接成功
    my_cursor = conn.cursor()   # 构造油标
    my_cursor.execute('select version()')   # 使用油标执行sql指令
    data = my_cursor.fetchone()   # 获取执行后的结果
    print('Database Version', data)  # 打印结果
    my_cursor.close()   # 释放占用资源
    conn.close()
    

  • 创建数据库、创建表

    import pymysql
    
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='123456',  //记得更改为你的用户名、密码、端口号
        port=3306,
    )
    my_cursor = conn.cursor()
    my_cursor.execute('create database test_db;')
    my_cursor.execute('use test_db')
    my_cursor.execute("create table if not exists tb1("
                       "id int,"
                       "name varchar(20),"
                       "age int,"
                       "primary key (id)"
                     ") ENGINE=INNODB CHARSET='utf8mb4' COLLATE='utf8mb4_unicode_ci';"
                     )
    

    上面的代码将新建一个名为test_db的数据库,并在这个数据库下新建一个名为tb1的表,表中有三个字段,分别是id,name,age,下面的例子都将在这个基础上实践。


  • 向表中插入数据

    import pymysql
    
    conn = pymysql.connect(
        host='localhost',
        user='root',
        passwd='123456',
        port=3306,
        db='test_db',
        charset='utf8mb4',
    )
    try:
        with conn.cursor() as my_cursor:
            sql_insert = 'insert into tb1 values(%s, %s, %s)'
            # 一次插入一行数据
            row_affected = my_cursor.execute(sql_insert, (1, 'Tom', 19))
            print('插入一行数据后影响的行数:', row_affected)
    
            # 一次插入多行数据
            rows_affected = my_cursor.executemany(sql_insert, [(2, 'Emma', 20), (3, 'Mary', 19)])
            print('插入多行数据后影响的行数:', rows_affected)
    
            conn.commit()  # 数据发生变化要记得提交到数据库中
    except:
        conn.rollback()  # 如果有异常就回滚
        conn.close()
    

    注意:executemany()方法接收的是一个列表,且列表中的每一个元素必须是元组!


  • 更改数据

    import pymysql
    
    conn = pymysql.connect(
        host='localhost',
        user='root',
        passwd='123456',
        port=3306,
        db='test_db',
        charset='utf8mb4',
    )
    try:
        with conn.cursor() as my_cursor:
            sql_update = "UPDATE tb1 SET age=%s WHERE id=%s;"
            my_cursor.execute(sql_update, (60, 1))
            conn.commit()
    except:
        print('error')
        conn.rollback()
        conn.close()
    

  • 查询数据

    import pymysql
    
    conn = pymysql.connect(
        host='localhost',
        user='root',
        passwd='123456',
        port=3306,
        db='test_db',
        charset='utf8mb4',
    )
    try:
        with conn.cursor() as my_cursor:
            sql_select = 'select * from tb1;'
    
            my_cursor.execute(sql_select)
            print('查询结果的条数:', my_cursor.rowcount)
            print('-'*100)
    
            first_one = my_cursor.fetchone()
            print(first_one)
            print('-' * 100)
    
            all = my_cursor.fetchall()
            for i in all:
                print(i)
    
    except:
        print('error')
        conn.rollback()
        conn.close()
    

  • 删除数据

    import pymysql
    
    conn = pymysql.connect(
        host='localhost',
        user='root',
        passwd='123456',
        port=3306,
        db='test_db',
        charset='utf8mb4',
    )
    try:
        with conn.cursor() as my_cursor:
            sql_delete = 'delete from tb1 where id=%s;'
            del_rows = my_cursor.execute(sql_delete, (1, ))
            conn.commit()
            print('删除的记录条数为:', del_rows)
    except:
        print('error')
        conn.rollback()
        conn.close()
    

注意:对数据库中的数据进行改变的操作都要用conn.commit()将更改提交到数据库中,否则你使用Python对数据库的操作都是无效的。


要使用Python来操作MySQL数据库,Python代码大多相同,关键是要会MySQL。


上面就是几种常见的将Python爬虫爬取到的数据进行存储的方法了,感谢你的阅读。

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值