爬虫数据存储(11. 文件存储)

el/2024/5/23 1:59:17

文件存储

  • 内容概括
    • 11.1 write_file 写入文件
      • open函数和使用方法
      • 实操案例:
    • 11.2 read_write_lines文件读写行
      • 操作方法:
      • 实操案例:
    • 11.3 fileput_demo另一种文件操作方法
      • 操作方法:
      • 实操案例:
    • 11.4 read_search_xml读取XML文件
      • 操作方法:
      • 实操案例:
    • 11.5 dict to xml 字典转xml文件方法
      • 操作方法:
      • 实操案例;
    • 11.6 xml to dict xml文件转字典类型
      • 操作方法:
      • 实操案例:
    • 11.7 json to dict JSON字符串转字典
      • 操作方法:
      • 实操案例:
    • 11.8 json to class JSON字符串转换成CLASS类
      • 操作使用:
      • 实操案例:
    • 11.9 class to json CLASS类转JSON字符串
      • 操作方法:
      • 操作实例:
    • 11.10 classlist to json 对象列表和JSON字符串转换
      • 操作方法:
      • 实操案例:
    • 11.11 json to xml JSON字符串转XML文件
      • 操作方法:
      • 实操案例:
    • 11.12 write_csv 写入CSV文件
      • 操作方法:
      • 实操案例:
    • 11.13 read_csv 读取CSV文件
      • 操作方法:
      • 实操案例:
    • 11.14 实战案例:抓取豆瓣音乐排行榜写入CSV文件
      • 操作方法:
      • 实操案例:

内容概括

保存文件有多种形式,主要包括XML文件、CSV文件、JSON文件
主要内容:
1、操作文件的基础方式
2、使用Fileput对象读取文件
3、读写XML文件
4、读写JSON文件
5、XML数据、JSON数据和Python对象之间的相互转换
6、读写CSV文件

11.1 write_file 写入文件

open函数和使用方法

open函数用于打开文件,第1个参数指明文件路径(绝对相对都可以),第2个参数指明文件操作模式

 文件模式                 描述r                 读模式(默认)w                 写模式                              x                 排他的写模式(只能用户自己写)   a                 追加模式   b                 二进制模式(可添加到其他模式中使用)   t                 文本模式(默认值,可添加到其他模式中使用)   +                 读写模式(必须与其他文件模式一起使用)  
# wirte(string):向文件写入内容,该方法返回写入文件的字节数
# read[n]:读取文件的内容,n是一个整数,表示从文件指针指定位置读取n个字节,如不指定,该方法会读取从当前往后的所有字节
# seek(n):重新设置指针,也就是改变文件的当前位置(偏移量)
# close():关闭文件     

实操案例:

# 一些模式打开test1.txt文件
f = open('./files/test1.txt','w')
# 向test1.txt写入"i love",运行结果:7
print(f.write('I love '))
# 向test1.txt写入"python",运行结果:6
print(f.write('python'))
f.close()# 以读的模式打开test1.txt
f = open('./files/test1.txt','r')
# 从test1.txt文件中读取7个字节的数据,运行结果I love
print(f.read(7))
# 从当前位置开始读取6个字节的数据,运行结果python
print(f.read(6))
f.close()try:# 如果test2.txt文件不存在,会抛出异常f = open('./files/test2.txt','r+')
except Exception as e:print(e)
# 用追加可读写模式打开test2.txt文件
f = open('./files/test2.txt','a+')
# 向test2.txt文件写入hello
print(f.write('hello'))
f.close()f = open('./files/test2.txt','a+')
# 读取test2.txt文件,由于目前文件指针已经在文件的结尾,所以什么都不会读出来
print(f.read())
# 将文件指针设置到指针开始的位置
f.seek(0)
# 读取全部文件内容,hello
print(f.read())
f.close()try:# 用可读写的方式打开test2.txt文件,将文件内容会清空f = open('./files/test2.txt','w+')# 读取文件的全部内容,什么都没读出来print(f.read())# 向文件写入“How are you?”f.write('How are you?')# 重置文件指针到文件的开始位置f.seek(0)# 读取文件的全部内容,运行结果How are you?print(f.read())
finally:f.close()

11.2 read_write_lines文件读写行

操作方法:

通过readline方法、readlines方法、writelines方法对urls.txt文件进行读写操作

  1. readline读取文件中一行的数据
  2. readlines读取文件中所有行的数据
  3. writelines写入文件多行数据

实操案例:

import os
f = open('./files/urls.txt','r+')
url = ''
while True:# 从urls.txt读一行文本url = f.readline()# 将最后的行结束符去掉url = url.rstrip()# 当读上来的是空串就结束循环if url == '':breakelse:print(url)
print('_____________________________________')
f.seek(0)
# 读urls中所有的行
print(f.readlines())
# 向urls.txt文件中添加一个新行
f.write('https://jiketiku.com' + os.linesep)
f.close()# 使用'a+'模式再次打开urls.txt文件
f = open('./files/urls.txt','a+')
# 定义一个要写入的urls.txt列表
urlList = ['https://geekori.com' + os.linesep, 'https://www.google.com' + os.linesep]
# 将urlList写入urls.txt文件
f.writelines(urlList)
# 关闭urls.txt文件
f.close()

11.3 fileput_demo另一种文件操作方法

操作方法:

  1. 使用fileinput.input方法读取urls.txt文件,通过for循环获取每一行值
  2. 同时调用fileinpout.filename方法
  3. fileinput.lineno方法分别获取正在读取的文件名和当前的行号

实操案例:

import fileinput
# 使用input方法打开urls.txt文件
fileobj = fileinput.input('./files/urls.txt')
# 输出fileobj类型
print(type(fileobj))
# 读取urls.txt文件第1行
print(fileobj.readline().rstrip())
# 通过for循环输出urls.txt文件的其他行
for line in fileobj:line = line.rstrip()# 如果file不等于空串,输出当前行号和内容if line != '':print(fileobj.lineno(),':',line)else:print(fileobj.filename())

11.4 read_search_xml读取XML文件

操作方法:

读取XMl文件需要导入xml.etree.ElementTree,并通过该模块的parse函数读取XML文件

实操案例:

products.xml文件

<!-- products.xml -->
<root><products><product uuid='1234'><id>10000</id><name>iPhone9</name><price>9999</price></product><product uuid='4321'><id>20000</id><name>特斯拉</name><price>800000</price></product><product uuid='5678'><id>30000</id><name>Mac Pro</name><price>40000</price></product></products>
</root>
from xml.etree.ElementTree import parse
# 开始分析products.xml文件,files/products.xml是要读取的XML文件的名字
doc = parse('files/products.xml')
# 通过Xpath搜索子节点集合,然后对这个子节点集合进行迭代
for item in doc.iterfind('products/product'):# 读取product节点的id子节点的值id = item.findtext('id')# 读取product节点的name子节点的值name = item.findtext('name')# 读取product节点的price子节点的值price = item.findtext('price')# 读取product节点的uuid子节点的值print('uuid=',item.get('uuid'))print('id=',id)print('name=',name)print('price=',price)print('__________________________________________________')

11.5 dict to xml 字典转xml文件方法

操作方法:

  1. 将一个字典类型的变量转换为XMl字符串
  2. 然后使用parseString函数解析整个XML字符串
  3. 并用带缩进格式的形式将XMl字符串写入persons.xml文件

实操案例;

import dicttoxml
from xml.dom.minidom import parseString
import os
# 定义一个字典
d = [20,'names',{'name':'Bill','age':30,'salary':2000},{'name':'王军','age':34,'salary':3000},{'name':'John','age':25,'salary':2500}]
# 将字典转换为XML格式(bytes形式)
bxml = dicttoxml.dicttoxml(d, custom_root = 'persons')
# 将bytes形式的XML数据按utf-8编码格式解码成XMl字符串
xml = bxml.decode('utf-8')
print(xml)
# 解析XML字符串
dom = parseString(xml)
# 生成带缩进格式的XML字符串
prettyxml = dom.toprettyxml(indent='    ')
# 创建files目录
os.makedirs('files',exist_ok=True)
# 以只写和utf-8编码格式的方式打开persons.xml文件
f = open('./files/persons.xml','w',encoding='utf-8')
# 将格式化的XML字符写入persons.xml文件
f.write(prettyxml)
f.close()

生产的persons.xml文件:

<?xml version="1.0" ?>
<persons><item type="int">20</item><item type="str">names</item><item type="dict"><name type="str">Bill</name><age type="int">30</age><salary type="int">2000</salary></item><item type="dict"><name type="str">王军</name><age type="int">34</age><salary type="int">3000</salary></item><item type="dict"><name type="str">John</name><age type="int">25</age><salary type="int">2500</salary></item>
</persons>

11.6 xml to dict xml文件转字典类型

操作方法:

  1. 从products.xml文件中读取一个XMl字符串
  2. 并使用xmltodict模块的parse模块来解析XML字符串
  3. 如果格式正确,parse函数可以返回字典对象

实操案例:

import xmltodict
# 打开products.xml
f = open('files/products.xml','rt',encoding="utf-8")
xml = f.read()
# 分析XMl字符串,并转化为字典
d = xmltodict.parse(xml)
print(d)
print('_________________________________________________')
f.close()# 使用pprint模块可读性更好
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(d)

11.7 json to dict JSON字符串转字典

操作方法:

  1. 将data的字典转换为JSON字符串
  2. 然后将JSON字符串s通过eval函数转换为字典
  3. 最后从products.json文件中读取SJON字符串,并使用loads函数和eval函数两种方法将JSON字符串转换为字典

实操案例:

products.json文件内容:

[{"name":"iPhone9","price":9999,"count":3000},{"name":"特斯拉","price":800000,"count":122}
]
import json
data = {'name':'Bill','company':'Microsoft','age':34
}
# 将字典转换为JSON字符串
jsonStr = json.dumps(data)
print(type(jsonStr))
print(jsonStr)
# 将JSON字符串转换为字典
data = json.loads(jsonStr)
print(type(data))
print(data)# 定义一个JSON字符串
s = '''
{'name' : 'Bill','company' : 'Microsoft','age' : 34
}
'''
# 使用eval函数将JSON字符串转换为字典
data = eval(s)
print(type(data))
print(data)
# 输出字典中key为company的值
print(data['company'])
# 打开products.json文件中的所有内容
f = open('./files/products.json','r',encoding='utf-8')
jsonStr = f.read()
# 使用eval函数将JSON字符串转换为字典
json1 = eval(jsonStr)
# 使用loads函数将JSON字符串转换为字典
json2 = json.loads(jsonStr)
print(json1)
print(json2)
print(json2[0]['name'])
f.close()

11.8 json to class JSON字符串转换成CLASS类

操作使用:

  1. 指定类:loads函数会自动创建指定类的实例,并将由JSON字符串转换成的字典通过类的构造方法传入类实例
  2. 指定回调函数:loads函数会调用回调函数返回类实例,并将有JSON字符串转换成的字典传入回调函数,必须有一个参数可以接收字典

实操案例:

从product.json文件读取JSON字符串,然后分别通过指定类(Product)和指定回调函数(json2Product)的方式将JSON字符串转换为Product对象

  1. product.json文件内容:
{"name":"iPhone9",
"price":9999,
"count":3000}
  1. json2class.PY文件内容:
import json
class Product:# d参数式要传入的字典def __init__(self, d):self.__dict__ = d
# 打开product.json文件
f = open('files/product.json','r')
# 从product.json文件中读取JSON字符串
jsonStr = f.read()
my1 = json.loads(jsonStr, object_hook=Product)
# 下面3行代码输出Product对象中相应属性的值
print(type(my1))
print('name=',my1.name)
print('price=',my1.price)
print('count',my1.count)
print('________________________________________________________________')# 定义用于将字典转换为Product对象的函数
def json2Product(d):return Product(d)
# 通过指定类回调函数的方式将JSON字符串转换为Product对象
my2 = json.loads(jsonStr, object_hook=json2Product)
# 下面3行代码输出Product对象中相应属性的值
print(type(my2))
print('name=',my2.name)
print('price=',my2.price)
print('count',my2.count)
f.close()

11.9 class to json CLASS类转JSON字符串

操作方法:

  1. dumps函数不仅可以将字典转换为JSON字符串,还可以将类实例转换为JSON字符串
  2. dumps函数需要通过default关键字参数指定一个回调函数,在转换的过程中,dumps函数会向这个回调函数传入类实例

操作实例:

创建一个类和构造函数,将其实例化,再调用dumps方法将对象转换成JSON字符串

import json
class Product:# 通过类的构造方法初始化3个属性def __init__(self,name,price,count):self.name = nameself.price = priceself.count = count# 用于将Product类的实例转换为字典的函数
def product2Dict(obj):return {'name':obj.name,'price':obj.price,'count':obj.count}
# 创建Product类的实例
product = Product('特斯拉',10000000,20)
# 将Product类的实例转换为JSON字符串
jsonStr = json.dumps(product,default=product2Dict,ensure_ascii=False)
print(type(jsonStr))
print(jsonStr)

11.10 classlist to json 对象列表和JSON字符串转换

操作方法:

  1. 从products.json文件读取JSON字符串
  2. 并通过loads函数将其转换为Product对象列表,
  3. 然后再通过dumps函数将Product对象列表转换为JSON字符串

实操案例:

products.json文件与前面的一样

import json
class Product:def __init__(self,d):self.__dict__ = df = open('files/products.json','r',encoding='utf-8')
jsonStr = f.read()
# 将JSON字符串转换为Product对象列表
products = json.loads(jsonStr,object_hook=Product)
# 输出Product对象列表中所有Product对象的相关属性值
for product in products:print(type(product))print('name=', product.name)print('price=', product.price)print('count=', product.count)
f.close()
# 定义将Product对象转换为字典的函数
def product2Dict(product):return {'name':product.name,'price':product.price,'count':product.count}
# 将Product对象列表转换为JSOn字符串
jsonStr = json.dumps(products, default=product2Dict,ensure_ascii=False)
print(jsonStr)

11.11 json to xml JSON字符串转XML文件

操作方法:

  1. 从products.json文件中读取json字符串
  2. 将json字符串转换成字典类型
  3. 将字典类型转换成XML文件

实操案例:

import json
import dicttoxml
f = open('files/products.json','r',encoding='utf-8')
jsonStr = f.read()
# 将JSON字符串转换为字典
d = json.loads(jsonStr)
print(d)
# 将字典转换为XML字符串
xmlStr = dicttoxml.dicttoxml(d).decode('utf-8')
print(xmlStr)
f.close()

11.12 write_csv 写入CSV文件

操作方法:

读写方法和读写文件类似,使用open方法打开csv文件,操作符用 w 写模式

实操案例:

import csv
# 打开files/data.csv文件,如果不存在,会重新创建一个data.csv
with open('files/data.csv','w',encoding='utf-8') as f:writer = csv.writer(f)# 写入数据writer.writerow(['产品ID','产品名称','生产企业','价格'])writer.writerow(['0001','iPhone9','Apple',9999])writer.writerow(['0002','特斯拉','特斯拉',12345])writer.writerow(['0003','荣耀手机','华为',3456])# 修改字段分隔符
with open('files/data1.csv', 'w', encoding='utf-8') as f:writer = csv.writer(f, delimiter=';')writer.writerow(['产品ID', '产品名称', '生产企业', '价格'])writer.writerow(['0001', 'iPhone9', 'Apple', 9999])writer.writerow(['0002', '特斯拉', '特斯拉', 12345])writer.writerow(['0003', '荣耀手机', '华为', 3456])# 一次性写入多行
with open('files/data2.csv','w',encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(['产品ID','产品名称','生产企业','价格'])writer.writerows([['0001','iPhone9','Apple',9999],['0002', '特斯拉', '特斯拉', 12345],['0003', '荣耀手机', '华为', 3456]])# 写入字典形式的数据
with open('files/data3.csv','w',encoding='utf-8') as f:fieldnames = ['产品ID','产品名称','生产企业','价格']writer = csv.DictWriter(f,fieldnames=fieldnames)writer.writeheader()writer.writerow({'产品ID': '0001', '产品名称': 'iPhone9', '生产企业': 'Apple', '价格': 9999})writer.writerow({'产品ID': '0002', '产品名称': '特斯拉', '生产企业': '特斯拉', '价格': 12345})writer.writerow({'产品ID': '0003', '产品名称': '荣耀手机', '生产企业': '华为', '价格': 3456})# 追加数据
with open('files/data.csv','a',encoding='utf-8') as f:fieldnames = ['产品ID','产品名称','生产企业','价格']writer = csv.DictWriter(f,fieldnames=fieldnames)writer.writerow({'产品ID': '0004', '产品名称': '量子战衣', '生产企业': '斯塔克工业', '价格': 99999999999})

11.13 read_csv 读取CSV文件

操作方法:

读写方法和读写文件类似,使用open方法打开csv文件,操作符用 r 写模式

实操案例:

读取11.12案例中的data.csv文件,对其进行操作

import csv
# 打开要读取的CSV文件
with open('files/data.csv','r',encoding='utf-8') as f:# 创建reader对象reader = csv.reader(f)# 获取每一行的数据for row in reader:print(row)
# 导入pandas模块
import pandas as pd
# 读取data.csv文件的数据
df = pd.read_csv('files/data.csv')
print(df)

11.14 实战案例:抓取豆瓣音乐排行榜写入CSV文件

操作方法:

  1. 使用requests网络库请求页面
  2. 使用Beautiful Soup解析库分析内容
  3. 解析出需要的内容
  4. 将内容写入CSV文件

实操案例:

import requests
from bs4 import BeautifulSoup
import re
import csv
import timeheaders = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}def get_url_music(url):html = requests.get(url,headers=headers)soup = BeautifulSoup(html.text, 'lxml')aTags = soup.find_all("a",attrs={"class": "nbg"})for aTag in aTags:get_music_info(aTag['href'])def save_csv(filename,info):with open(filename, 'a', encoding='utf-8') as f:fieldnames = ['name', 'author', 'style', 'time','publisher','score']writer = csv.DictWriter(f, fieldnames=fieldnames)writer.writerow(info)def get_music_info(url):html = requests.get(url,headers=headers)soup = BeautifulSoup(html.text, 'lxml')name = soup.find (attrs={'id':'wrapper'}).h1.span.textauthor = soup.find(attrs={'id':'info'}).find('a').textstyles = re.findall('<span class="pl">流派:</span>&nbsp;(.*?)<br />', html.text, re.S)if len(styles) == 0:style = '未知'else:style = styles[0].strip()time = re.findall('发行时间:</span>&nbsp;(.*?)<br />', html.text, re.S)[0].strip()publishers = re.findall('<span class="pl">出版者:</span>&nbsp;(.*?)<br />', html.text, re.S)if len(publishers) == 0:publisher = '未知'else:publisher = publishers[0].strip()score = soup.find(class_='ll rating_num').textinfo = {'name': name,'author': author,'style': style,'time': time,'publisher': publisher,'score': score}print(info)save_csv(filename,info)if __name__ == '__main__':urls = ['https://music.douban.com/top250?start={}'.format(str(i)) for i in range(0,250,25)]filename = 'music.csv'with open(filename, 'w', encoding='utf-8') as f:fieldnames = ['name', 'author', 'style', 'time', 'publisher', 'score']writer = csv.DictWriter(f, fieldnames=fieldnames)writer.writeheader()for url in urls:get_url_music(url)time.sleep(1)

结果截图:
在这里插入图片描述


http://www.ngui.cc/el/5281660.html

相关文章

爬虫数据存储(12. 数据库存储)

Mysql数据操作方法 pymysql常用方法和参数打开数据库创建Person表插入数据查询记录调用上述方法 pymysql常用方法和参数 connect方法&#xff1a;连接数据库&#xff0c;根据连接的数据库类型不同&#xff0c;该函数参数也不同&#xff0c;赶回Connection对象cursor方法&#…

爬虫高级应用(13. 抓取异步数据)

抓取异步数据 主要内容&#xff1a;关于异步传输AJAX什么是AJAX&#xff1f;AJAX基本原理 AJAX服务端请求数据案例实战案例&#xff1a;抓取某东图书评价 主要内容&#xff1a; 什么是异步数据加载AJAX的基本概念如何获取异步数据使用的URL抓取异步数据项目实战&#xff1a;分…

数据结构 第3章 栈和队列

第三章 栈和队列 数据结构—栈思维导图强化练习 数据结构—队列思维导图强化练习 栈和队列的应用思维导图强化练习 特殊矩阵的压缩存储思维导图强化练习 数据结构—栈 思维导图 强化练习 3.1.4 8.向一个栈顶指针为top的链栈&#xff08;不带头结点&#xff09;中插入一个x结点…

爬虫高级应用(14. 可见即可爬Selenium)

本章主要内容 1、安装Selenium和WebDriver 2、Selenium的基本使用方法 3、查找节点 4、节点交互 5、管理Cookie 6、执行JavaScript代码 7、改变节点属性值Selenium的主要功能&#xff1a; 1、打开浏览器 2、获取浏览器页面的特定内容 3、控制浏览器页面上的空间&#xff0c;如…

基于javacc设计Cb编译器《自制编译器》

目录 1.引言2.cbc编译器的环境配置3.代码分析3.1 词法分析3.1.1正则表达式的扫描器3.1.2 TOKEN命令 4.JavaCC制作解析器4.1 JavaCC的语法描述4.2 JavaCC的EBNF表示法 5.语法分析6.抽象语法树6.1 抽象语法树的构成 7.语义分析7.1变量引用的消解7.2类型名称的消解7.3 类型定义检查…

Python每日笔记合集

目录 >> Python每日笔记—目录 << >> Python每日笔记—Day01 数据类型 << >> Python每日笔记—Day02 运算符 << >> Python每日笔记—Day03 循环字符串 << >> Python每日笔记—Day04 字符串补充 << >&…

软件测试 | 知识理论大纲

什么是软件测试 在规定的条件下,对程序进行操作,从而发现错误,对软件质量进行评估的过程。 软件测试的目的 以最少的人力、物力、时间找到软件的缺陷,并修改从而规避商业风险。 软件测试的定义 使用人工和自动手段来运行和测试某个系统的过程,目的在于检验是否满足了…

为什么要使用href=”javascript:void(0);”

href”javascript:void(0);” 这个的含义是&#xff0c;让超链接去执行一个js函数&#xff0c;而不是去跳转到一个地址&#xff0c; 而void(0)表示一个空的方法&#xff0c;也就是不执行js函数。 为什么要使用href”javascript:void(0);” javascript:是伪协议&#xff0c;表示…

记录用vue-seamless-scroll实现列表无缝滚动

1.安装&#xff1a;npm install vue-seamless-scroll --save 2.导入 import vueSeamlessScroll from vue-seamless-scroll // 无缝滚动组件 components: {vueSeamlessScroll},3.配置初始值 computed: {// 监听属性 类似于data概念defaultOption () {return {step: 0.4, // 数值…

记录解决echarts文字显示不清晰问题

最近在用echarts时&#xff0c;遇见文字及图例失真、不清晰问题&#xff0c;特此记录 // 方法一&#xff1a; this.chart this.$echarts.init(document.getElementById(supplierContentChart), null, {renderer: svg}) // 采用svg渲染&#xff0c;比canvans清晰度高// 方法二…