已写章节
第一章 网络爬虫入门
第二章 基本库的使用
第三章 解析库的使用
第四章 数据存储
第五章 动态网页的抓取
文章目录
第四章 数据存储
用解析库提取出我们想要的数据之后,接下来就是存储数据了。保存的形式有很多,可以直接保存为文本文件,如: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库。
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连接的驱动有PyMySQL和mysql-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爬虫爬取到的数据进行存储的方法了,感谢你的阅读。