目录
在python中,我们可以使用with语句来定义和控制代码块执行前的准备动作及执行后的收尾动作,语法为with open('d:\\test\\a.txt','w') as f:,将打开后的文件对象赋值给f,再进行之后的操作。
一般使用open函数打开文件,语法为open(filename, mode='r' , buffering=-1, …),filename表示文件名或路径,一般使用'd:\\infile.txt'、r'd:\outfile.txt'和'record.txt'这三种形式作为参数;mode表示为打开方式,具体功能如下:
mode | 功能 |
---|---|
r | 以读模式打开 |
w | 以写模式打开(清空原内容) |
r | 以写模式打开,若文件已存在则失败 |
a | 以追加模式打开(从EOF开始,必要时创建新文件) |
r+ | 以读写模式打开 |
w+ | 以读写模式打开(清空原内容) |
a+ | 以读和追加模式打开 |
rb | 以二进制读模式打开 |
wb | 以二进制写模式打开(参见w) |
ab | 以二进制追加模式打开(参见a) |
rb+ | 以二进制读写模式打开(参见r+) |
wb+ | 以二进制读写模式打开(参见w+) |
ab+ | 以二进制读写模式打开(参见a+) |
buffering也为可选参数,默认值为-1(0代表不缓冲,1 或大于1的值表示缓冲一行或指定缓冲区大小)。
open的返回值是一个文件对象(设为f),此时,可用一些文件相关函数来操作这个对象,如f.read(), f.write(), f.readline(), f.readlines(), f.writelines(),f.close(),f.seek()等等。
主要使用f.write()和 f.writelines()函数,f.write()写入一个字符串,f.writelines()写入一系列字符串,代码实现如下:
with open(r'd:\test\a.txt', 'w') as f:
f.write('Hellow World!\n')
f.writelines(['Hellow World!\n', 'Hellow\n', 'World\n'])
f.close()
运行结果
图 1 运行结果
主要使用f.read()、 f.readline()和f.readlines()函数,f.read()写入一个字符串,带参数说明从文件中至多读出size字节数据,返回一个字符串,不带参数就是读文件直到文件结束,返回一个字符串;f.readlines()读出所有的字符串,返回一个列表;f.readline()读出一行字符串,返回一个字符串,代码实现如下:
with open('d:\\test\\a.txt') as f:
p1 = f.read(8)
f.seek(0) #功能和用法的讲解在本小节末尾
p2 = f.read()
f.close()
print(p1)
print(p2)
#输出结果如下所示
#Hellow W
#Hellow World!Hellow World!
#Hellow
#World
图 2 b.txt 内容
with open('d:\\test\\b.txt') as f:
p1 = f.readlines()
f.seek(0)
p2 = f.readline()
f.close()
print(p1, type(p1))
print(p2, type(p2))
#运行结果如下
#[' A\n', ' ABC\n', ' ABCDC\n', ' ABCDEDC\n', 'ABCDEFEDC\n'] <class 'list'>
# A #文件里带有一个换行符
# <class 'str'>
file_name = 'd:\\test\\b.txt' #使用异常处理机制来判断文件有多少行
try:
with open(file_name) as f:
date = f.readlines()
except FileExistsError:
print(file_name + 'does not exist')
lens = len(date)
print('b.txt' + ' has ' + str(lens) + ' line')
#输出结果如下:
# b.txt has 5 line
除此之外,还可以同时处理多个文件,代码如下所示:
def countLines(fname):
try:
with open(fname) as f:
date = f.readlines()
except FileExistsError:
print(fname + ' does not exist')
lens = len(date)
print(fname + ' has ' + str(lens) + ' line')
files = ['d:\\test\\a.txt', 'd:\\test\\b.txt', 'd:\\test\\c.txt']
for fname in files:
countLines(fname)
#运行结果为
# d:\test\a.txt has 3 line
# d:\test\b.txt has 5 line
# d:\test\c.txt has 5 line
还可以统计一个目录下所有txt文件的行数,代码如下所示:
import os
import shutil
def countLines(fname):
try:
with open(fname) as f:
date = f.readlines()
except FileExistsError:
print(fname + ' does not exist')
lens = len(date)
print(fname + ' has' + str(lens) + ' line')
path = 'd:\\test'
for fname in os.listdir(path):
if fname.endswith('.txt'):
file_path = os.path.join(path, fname)
countLines(file_path)
#运行结果为
# d:\test\a.txt has 3 line
# d:\test\b.txt has 5 line
# d:\test\c.txt has 5 line
注:判断文件是否可读,可用f.readable()来判断
对于文件操作,往往需要对文件同时进行读和写,具体实现代码如下:
with open('d:\\test\\b.txt') as f1:
cName = f1.readlines()
f.close()
for i in range(0,len(cName)):
cName[i] = str(i+1) + ' ' +cName[i]
with open('d:\\test\\c.txt','w') as f2:
f2.writelines(cName)
f.close()
图 3 运行结果(c.txt文件)
除了读写函数之外,文件操作里面还有一个特别重要的函数f.seek()函数,语法如下:f.seek(offset , whence=0),主要功能就是在文件中移动文件指针,从 whence(0表示文件头部,1表示 当前位置,2表示文件尾部)偏移offset个字节,whence参数可选,默认值为0,已在前面代码中使用过,此处就不再叙述了。
本文目前只介绍一下简单的网络数据获取方式,更深入一点的在日后进行补充。
实现抓取网页内容有许多种方法,目前只介绍使用Requests第三方库来进行抓取(首先要查看爬虫协议),可直接在命令提示符下输入pip install requests 来获取,或者使用Anaconda来导入第三方库,在此就不介绍具体方法,实现代码如下:
import requests
r = requests.get("https://www.baidu.com/")
print(r.status_code)
r.encoding = 'utf-8'
print(r.text)
获取到的代码如下所示:
运行结果如图所示:
图 4 代码运行结果
对网页进行爬取之后,有时候要进行代码的解析,来获得我们所需要的信息,本文主要使用Beautifu Soup第三方库来解析代码,具体代码实现如下所示:
import requests
from bs4 import BeautifulSoup
import re
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/78.0.3904.108 Safari/537.36'}
# 有些网站抓取时需要增加headers属性,将自己的浏览器信息告诉服务器
r = requests.get('https://book.douban.com/subject/1084336/comments/', headers=headers)
soup = BeautifulSoup(r.text, 'lxml')
pattern = soup.find_all('span', 'short')
for item in pattern:
print(item.string)
pattern_s = re.compile('<span class="user-stars allstar(.*?) rating"')
p = re.findall(pattern_s, r.text)
s = 0
for star in p:
s += int(star)
print(s) # 统计评分总数
print(p) # 查看每个评分数
运行代码如下所示:
图 5 代码运行结果