信用网站一体化建设方案,什么是网络营销的新特点,做影视网站需要的软件,国旗做网站按钮违法吗爬虫专栏#xff1a;http://t.csdnimg.cn/WfCSx
文件存储形式多种多样#xff0c;比如可以保存成 TXT 纯文本形式#xff0c;也可以保存为 JSON 格式、CSV 格式等#xff0c;本节就来了解一下文本文件的存储方式。
TXT 文本存储
将数据保存到 TXT 文本的操作非常简单http://t.csdnimg.cn/WfCSx
文件存储形式多种多样比如可以保存成 TXT 纯文本形式也可以保存为 JSON 格式、CSV 格式等本节就来了解一下文本文件的存储方式。
TXT 文本存储
将数据保存到 TXT 文本的操作非常简单而且 TXT 文本几乎兼容任何平台但是这有个缺点那就是不利于检索。所以如果对检索和数据结构要求不高追求方便第一的话可以采用 TXT 文本存储。本节中我们就来看下如何利用 Python 保存 TXT 文本文件。
1. 本节目标
本节中我们要保存知乎上 “发现” 页面的 “热门话题” 部分将其问题和答案统一保存成文本形式。
2. 基本实例
首先可以用 requests 将网页源代码获取下来然后使用 pyquery 解析库解析接下来将提取的标题、回答者、回答保存到文本代码如下
import requests
from pyquery import PyQuery as pq
url https://www.zhihu.com/explore
headers {User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
}
html requests.get(url, headersheaders).text
doc pq(html)
items doc(.explore-tab .feed-item).items()
for item in items:question item.find(h2).text()author item.find(.author-link-line).text()answer pq(item.find(.content).html()).text()file open(explore.txt, a, encodingutf-8)file.write(\n.join([question, author, answer]))file.write(\n * 50 \n)file.close()
这里主要是为了演示文件保存的方式因此 requests 异常处理部分在此省去。首先用 requests 提取知乎的 “发现” 页面然后将热门话题的问题、回答者、答案全文提取出来然后利用 Python 提供的 open 方法打开一个文本文件获取一个文件操作对象这里赋值为 file接着利用 file 对象的 write 方法将提取的内容写入文件最后调用 close 方法将其关闭这样抓取的内容即可成功写入文本中了。
运行程序可以发现在本地生成了一个 explore.txt 文件其内容如图所示。 这样热门问答的内容就被保存成文本形式了。
这里 open 方法的第一个参数即要保存的目标文件名称第二个参数为 a代表以追加方式写入到文本。另外我们还指定了文件的编码为 utf-8。最后写入完成后还需要调用 close 方法来关闭文件对象。
3. 打开方式
在刚才的实例中open 方法的第二个参数设置成了 a这样在每次写入文本时不会清空源文件而是在文件末尾写入新的内容这是一种文件打开方式。关于文件的打开方式其实还有其他几种这里简要介绍一下。 r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb以二进制只读方式打开一个文件。文件指针将会放在文件的开头。 r以读写方式打开一个文件。文件指针将会放在文件的开头。 rb以二进制读写方式打开一个文件。文件指针将会放在文件的开头。 w以写入方式打开一个文件。如果该文件已存在则将其覆盖。如果该文件不存在则创建新文件。 wb以二进制写入方式打开一个文件。如果该文件已存在则将其覆盖。如果该文件不存在则创建新文件。 w以读写方式打开一个文件。如果该文件已存在则将其覆盖。如果该文件不存在则创建新文件。 wb以二进制读写格式打开一个文件。如果该文件已存在则将其覆盖。如果该文件不存在则创建新文件。 a以追加方式打开一个文件。如果该文件已存在文件指针将会放在文件结尾。也就是说新的内容将会被写入到已有内容之后。如果该文件不存在则创建新文件来写入。 ab以二进制追加方式打开一个文件。如果该文件已存在则文件指针将会放在文件结尾。也就是说新的内容将会被写入到已有内容之后。如果该文件不存在则创建新文件来写入。 a以读写方式打开一个文件。如果该文件已存在文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在则创建新文件来读写。 ab以二进制追加方式打开一个文件。如果该文件已存在则文件指针将会放在文件结尾。如果该文件不存在则创建新文件用于读写。
4. 简化写法
另外文件写入还有一种简写方法那就是使用 with as 语法。在 with 控制块结束时文件会自动关闭所以就不需要再调用 close 方法了。这种保存方式可以简写如下
with open(explore.txt, a, encodingutf-8) as file:file.write(\n.join([question, author, answer]))file.write(\n * 50 \n)
如果想保存时将原文清空那么可以将第二个参数改写为 w代码如下
with open(explore.txt, w, encodingutf-8) as file:file.write(\n.join([question, author, answer]))file.write(\n * 50 \n)
上面便是利用 Python 将结果保存为 TXT 文件的方法这种方法简单易用操作高效是一种最基本的保存数据的方法。
JSON 文件存储
JSON全称为 JavaScript Object Notation, 也就是 JavaScript 对象标记它通过对象和数组的组合来表示数据构造简洁但是结构化程度非常高是一种轻量级的数据交换格式。本节中我们就来了解如何利用 Python 保存数据到 JSON 文件。
1. 对象和数组
在 JavaScript 语言中一切都是对象。因此任何支持的类型都可以通过 JSON 来表示例如字符串、数字、对象、数组等但是对象和数组是比较特殊且常用的两种类型下面简要介绍一下它们。
对象它在 JavaScript 中是使用花括号 {} 包裹起来的内容数据结构为 {key1value1, key2value2, ...} 的键值对结构。在面向对象的语言中key 为对象的属性value 为对应的值。键名可以使用整数和字符串来表示。值的类型可以是任意类型。
数组数组在 JavaScript 中是方括号 [] 包裹起来的内容数据结构为 [java, javascript, vb, ...] 的索引结构。在 JavaScript 中数组是一种比较特殊的数据类型它也可以像对象那样使用键值对但还是索引用得多。同样值的类型可以是任意类型。
所以一个 JSON 对象可以写为如下形式
[{name: Bob,gender: male,birthday: 1992-10-18
}, {name: Selina,gender: female,birthday: 1995-10-18
}]
由中括号包围的就相当于列表类型列表中的每个元素可以是任意类型这个示例中它是字典类型由大括号包围。
JSON 可以由以上两种形式自由组合而成可以无限次嵌套结构清晰是数据交换的极佳方式。
2. 读取 JSON
Python 为我们提供了简单易用的 JSON 库来实现 JSON 文件的读写操作我们可以调用 JSON 库的 loads 方法将 JSON 文本字符串转为 JSON 对象可以通过 dumps() 方法将 JSON 对象转为文本字符串。
例如这里有一段 JSON 形式的字符串它是 str 类型我们用 Python 将其转换为可操作的数据结构如列表或字典
import json
str
[{name: Bob,gender: male,birthday: 1992-10-18
}, {name: Selina,gender: female,birthday: 1995-10-18
}]print(type(str))
data json.loads(str)
print(data)
print(type(data))
运行结果如下
classstr
[{name: Bob, gender: male, birthday: 1992-10-18}, {name: Selina, gender: female, birthday: 1995-10-18}]
class list
这里使用 loads 方法将字符串转为 JSON 对象。由于最外层是中括号所以最终的类型是列表类型。
这样一来我们就可以用索引来获取对应的内容了。例如如果想取第一个元素里的 name 属性就可以使用如下方式
data[0][name]
data[0].get(name)
得到的结果都是
Bob
通过中括号加 0 索引可以得到第一个字典元素然后再调用其键名即可得到相应的键值。获取键值时有两种方式一种是中括号加键名另一种是通过 get 方法传入键名。这里推荐使用 get 方法这样如果键名不存在则不会报错会返回 None。另外get 方法还可以传入第二个参数即默认值示例如下
data[0].get(age)
data[0].get(age, 25)
运行结果如下
None
25
这里我们尝试获取年龄 age其实在原字典中该键名不存在此时默认会返回 None。如果传入第二个参数即默认值那么在不存在的情况下返回该默认值。
值得注意的是JSON 的数据需要用双引号来包围不能使用单引号。例如若使用如下形式表示则会出现错误
import json
str
[{name: Bob,gender: male,birthday: 1992-10-18
}]data json.loads(str)
运行结果如下
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 8)
这里会出现 JSON 解析错误的提示。这是因为这里数据用单引号来包围请千万注意 JSON 字符串的表示需要用双引号否则 loads 方法会解析失败。
如果从 JSON 文本中读取内容例如这里有一个 data.json 文本文件其内容是刚才定义的 JSON 字符串我们可以先将文本文件内容读出然后再利用 loads 方法转化
import json
with open(data.json, r) as file:str file.read()data json.loads(str)print(data)
运行结果如下
[{name: Bob, gender: male, birthday: 1992-10-18}, {name: Selina, gender: female, birthday: 1995-10-18}]
3. 输出 JSON
另外我们还可以调用 dumps 方法将 JSON 对象转化为字符串。例如将上例中的列表重新写入文本
import json
data [{name: Bob,gender: male,birthday: 1992-10-18
}]
with open(data.json, w) as file:file.write(json.dumps(data))
利用 dumps 方法我们可以将 JSON 对象转为字符串然后再调用文件的 write 方法写入文本结果如图所示。 另外如果想保存 JSON 的格式可以再加一个参数 indent代表缩进字符个数。示例如下
with open(data.json, w) as file:file.write(json.dumps(data, indent2))
此时写入结果如图所示。 这样得到的内容会自动带缩进格式会更加清晰。
另外如果 JSON 中包含中文字符会怎么样呢例如我们将之前的 JSON 的部分值改为中文再用之前的方法写入到文本
import json
data [{name: 王伟 ,gender: 男 ,birthday: 1992-10-18
}]
with open(data.json, w) as file:file.write(json.dumps(data, indent2))
写入结果如图所示。 可以看到中文字符都变成了 Unicode 字符这并不是我们想要的结果。
为了输出中文还需要指定参数 ensure_ascii 为 False另外还要规定文件输出的编码
with open(data.json, w, encodingutf-8) as file:file.write(json.dumps(data, indent2, ensure_asciiFalse))
写入结果如图所示。 可以发现这样就可以输出 JSON 为中文了。
本节中我们了解了用 Python 进行 JSON 文件读写的方法后面做数据解析时经常会用到建议熟练掌握。
CSV 文件存储
CSV全称为 Comma-Separated Values中文可以叫作逗号分隔值或字符分隔值其文件以纯文本形式存储表格数据。该文件是一个字符序列可以由任意数目的记录组成记录间以某种换行符分隔。每条记录由字段组成字段间的分隔符是其他字符或字符串最常见的是逗号或制表符。不过所有记录都有完全相同的字段序列相当于一个结构化表的纯文本形式。它比 Excel 文件更加简洁XLS 文本是电子表格它包含了文本、数值、公式和格式等内容而 CSV 中不包含这些内容就是特定字符分隔的纯文本结构简单清晰。所以有时候用 CSV 来保存数据是比较方便的。本节中我们来讲解 Python 读取和写入 CSV 文件的过程。
1. 写入
这里先看一个最简单的例子
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])
首先打开 data.csv 文件然后指定打开的模式为 w即写入获得文件句柄随后调用 csv 库的 writer 方法初始化写入对象传入该句柄然后调用 writerow 方法传入每行的数据即可完成写入。
运行结束后会生成一个名为 data.csv 的文件此时数据就成功写入了。直接以文本形式打开的话其内容如下
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
可以看到写入的文本默认以逗号分隔调用一次 writerow 方法即可写入一行数据。用 Excel 打开的结果如图所示。 如果想修改列与列之间的分隔符可以传入 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])
这里在初始化写入对象时传入 delimiter 为空格此时输出结果的每一列就是以空格分隔了内容如下
id name age
10001 Mike 20
10002 Bob 22
10003 Jordan 21
另外我们也可以调用 writerows 方法同时写入多行此时参数就需要为二维列表例如
import csv
with open(data.csv, w) as csvfile:writer csv.writer(csvfile)writer.writerow([id, name, age])writer.writerows([[10001, Mike, 20], [10002, Bob, 22], [10003, Jordan, 21]])
输出效果是相同的内容如下
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
但是一般情况下爬虫爬取的都是结构化数据我们一般会用字典来表示。在 csv 库中也提供了字典的写入方式示例如下
import csv
with open(data.csv, w) as csvfile:fieldnames [id, name, age]writer csv.DictWriter(csvfile, fieldnamesfieldnames)writer.writeheader()writer.writerow({id: 10001, name: Mike, age: 20})writer.writerow({id: 10002, name: Bob, age: 22})writer.writerow({id: 10003, name: Jordan, age: 21})
这里先定义 3 个字段用 fieldnames 表示然后将其传给 DictWriter 来初始化一个字典写入对象接着可以调用 writeheader 方法先写入头信息然后再调用 writerow 方法传入相应字典即可。最终写入的结果是完全相同的内容如下
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
这样就可以完成字典到 CSV 文件的写入了。
另外如果想追加写入的话可以修改文件的打开模式即将 open 函数的第二个参数改成 a代码如下
import csv
with open(data.csv, a) as csvfile: fieldnames [id, name, age] writer csv.DictWriter(csvfile, fieldnamesfieldnames) writer.writerow({id: 10004, name: Durant, age: 22})
这样在上面的基础上再执行这段代码文件内容便会变成
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
10004,Durant,22
可见数据被追加写入到文件中。
如果要写入中文内容的话可能会遇到字符编码的问题此时需要给 open 参数指定编码格式。比如这里再写入一行包含中文的数据代码需要改写如下
import csv
with open(data.csv, a) as csvfile:fieldnames [id, name, age]writer csv.DictWriter(csvfile, fieldnamesfieldnames)writer.writerow({id: 10004, name: Durant, age: 22})
这里需要给 open 函数指定编码否则可能发生编码错误。
另外如果接触过 pandas 等库的话可以调用 DataFrame 对象的 to_csv 方法来将数据写入 CSV 文件中。
2. 读取
我们同样可以使用 csv 库来读取 CSV 文件。例如将刚才写入的文件内容读取出来相关代码如下
import csv
with open(data.csv, r, encodingutf-8) as csvfile: reader csv.reader(csvfile) for row in reader: print(row)
运行结果如下
[id, name, age]
[10001, Mike, 20]
[10002, Bob, 22]
[10003, Jordan, 21]
[10004, Durant, 22]
[10005, 王伟 , 22]
这里我们构造的是 Reader 对象通过遍历输出了每行的内容每一行都是一个列表形式。注意如果 CSV 文件中包含中文的话还需要指定文件编码。
另外如果接触过 pandas 的话可以利用 read_csv 方法将数据从 CSV 中读取出来例如
import pandas as pd
df pd.read_csv(data.csv)
print(df)
运行结果如下 id name age
0 10001 Mike 20
1 10002 Bob 22
2 10003 Jordan 21
3 10004 Durant 22
4 10005 王伟 22
在做数据分析的时候此种方法用得比较多也是一种比较方便地读取 CSV 文件的方法。