一.文件操作
1.打开文件,关闭文件
f = open('test.txt',"w") #打开文件,w模式(写模式),文件不存在就新建
f.write("hello world,I'm here!") #将字符串写入文件中
f.close() #关闭文件
hello world,I'm here! #test.txt文件里的内容
2.read读取文件
#read方法,读取指定的字符,开始时定位在字符的头部,每执行一次向后移动指定字符数
f = open("test.txt","r")
content = f.read(5) #读取文件里的5个字符
print(content)
content = f.read(5) #接着读取文件里的5个字符
print(content)
f.close()
hello
worl
3.readlines读取文件
(1)当文件里含一行内容时
f = open("test.txt","r")
content = f.readlines() #一次性读取全部文件为列表,每行一个字符串元素
print(content)
f.close()
["hello world,I'm here!"]
(2)当文件里含多行内容时
f = open("test.txt","r")
content = f.readlines() #一次性读取全部文件为列表,每行一个字符串元素
i = 1
for temp in content:
print("%d:%s"%(i,temp),end="")
i += 1
f.close()
1:hello world,I'm here!
2:hello world,I'm here!
3:hello world,I'm here!
4:hello world,I'm here!
5:hello world,I'm here!
4.readline读取文件
f = open("test.txt","r")
content = f.readline()
print("1:%s"%content,end="")
content = f.readline()
print("2:%s"%content)
f.close()
1:hello world,I'm here!--1
2:hello world,I'm here!--2 #readline是执行一次输出一行内容
5.文件的相关操作
(1)文件重命名
#文件重命名
import os
os.rename("test.txt","test1.txt")
将原文件的"test.txt"重命名为"test1.txt"
(2)删除文件
#删除文件
import os
os.remove("test.txt")
将名为"test.txt"的文件删除
(3)创建文件夹
#创建文件夹
import os
os.mkdir("test2.txt")
创建一个名为"test2.txt"的文件夹
(4)获取当前目录
#获取当前目录
import os
os.getcwd()
(5)改变默认目录
#改变默认目录
import os
os.chdir("../")
(6)获取目录列表
#获取目录列表
import os
os.listdir("./")
(7)删除文件夹
#删除文件夹
import os
os.rmdir("test.txt")
二.异常处理
(1)出现异常
print("-------test---1-------")
f = open("123.txt","r") #用只读模式打开了一个不存在的文件,报错
print("-------test---2-------") #这句代码不会被执行
(2)捕获异常的方法:try方法
#捕获异常
try:
print("-------test---1-------")
f = open("123.txt", "r")
print("-------test---2-------")
except IOError: #文件没找到,属于IO异常(输入输出异常)
pass #捕获异常后,执行的代码
结果:-------test---1------- #因没找到名为123.txt的文件,所以第二句print不会被执行
(3)捕获异常需注意异常类型一致
try:
print(num)
#except IOError: #异常类型想要被捕获,需要一致
except NameError:
print("产生错误了")
结果:产生错误了 #IO和Name异常类型不同
(4)异常类型不止一种时
try:
print("-------test---1-------")
f = open("test.txt", "r")
print("-------test---2-------")
print(num)
except (NameError,IOError): #将可能产生的所有异常类型,都放到下面的小括号中
print("产生错误了")
结果:-------test---1-------
-------test---2-------
产生错误了 #将可能产生的所有异常类型,都放到下面的小括号中
(5)获取错误描述(需要具体错误信息)
#获取错误描述
try:
print("-------test---1-------")
f = open("123.txt", "r")
print("-------test---2-------")
print(num)
except (NameError,IOError)as result: #将可能产生的所有异常类型,都放到下面的小括号中
print("产生错误了")
print(result)
结果:-------test---1-------
产生错误了
[Errno 2] No such file or directory: '123.txt' #比如此错误为没找到123.txt的文件
(6)捕获所有异常
#捕获所有异常
try:
print("-------test---1-------")
f = open("test.txt", "r")
print("-------test---2-------")
print(num)
except Exception as result: #Exception可以承接任何异常
print("产生错误了")
print(result)
结果:-------test---1-------
-------test---2-------
产生错误了
name 'num' is not defined #使用Exception可知道所有的异常类型
(7)try finally方法
import time
try:
f = open("test.txt","r")
try:
while True:
content = f.readline()
if len(content)==0:
break
time.sleep(2)
print(content)
finally:
f.close()
print("文件关闭")
except Exception as result:
print("发生异常")
结果:
hello world,I'm here!--1
hello world,I'm here!--2
hello world,I'm here!
hello world,I'm here!
hello world,I'm here!
文件关闭 #因程序中引入时间且时间设定为2,所以每隔2毫秒输出文件中的一行内容
三.Python爬虫(豆瓣电影TOP 250)
准备工作——获取数据——解析内容——保存数据
1.准备工作
(1)URL分析:页面包括250条电影数据,分10页,每页25条;每页的URL的不同之处-最后的数值=(页数-1)*25
(2)借助Fn+F12来分析网页,在Elements下找到需要的数据位置
(3)编码规范:可使用函数实现单一功能或相关联功能的代码段,函数代码以def关键词开头,后接空格、函数标识符名称、圆括号()、冒号;可加入main函数用于测试程序,格式如下:if_name_== "_main_":
def main(a):
print("hello",a)
main(2)
if __name__ =="__main__": #当程序执行时
#调用函数
main(1)
结果: hello 2 hello 1
(4)引入模块 #re和urllib是自带的,不需要另外下载
import bs4 #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.request,urllib.error #制定URL,获取网页数据
import xlwt #进行excel操作
import sqlite3 #进行SQlite数据库操作
2.获取数据
(1)获取页面数据:对每一个页面,调用askURL函数获取页面内容
(2)定义一个获取页面的函数askURL,传入一个url参数,表示网址
(3)urllib2.Request生成请求,urllib2.urlopen发送请求获取响应,read获取页面内容
(4)在访问页面时经常会出现错误,为了程序正常运行,加入异常捕获try...except...语句
3.解析内容
(1)解析页面内容:使用BeautifulSoup定位特定的标签位置
(2)使用正则表达式找到具体的内容
4.保存数据
利用Python库xlwt将抽取的数据datalist写入Excel表格
豆瓣电影Top250:程序如下
def main():
baseurl = "https://movie.douban.com/top250?start="
#1.爬取网页
datalist = getData(baseurl)
savepath = "豆瓣电影Top250.xls"
#3.保存数据
saveData(datalist,savepath)
#askURL("https://movie.douban.com/top250?start=")
#影片详情链接的规则
findLink = re.compile(r'<a href="(.*?)">') #创建正则表达式对象,表示规则(字符串的模式)
#影片图片
findImgSrc = re.compile(r'<img.*src="(.*?)"',re.S) #re.S让换行符包含在字符中
#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
#影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#找到评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')
#找到概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#找到影片的相关内容
findBd = re.compile(r'<p class="">(.*)</p>',re.S)
#爬取网页
def getData(baseurl):
datalist = []
for i in range(0,10): #调用获取页面信息的函数,10次
url = baseurl + str(i*25)
html = askURL(url) #保存获取到的网页源码
#2.逐一解析数据
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): #查找符合要求的字符串,形成列表
#print(item) #测试:查看电影item全部信息
data = [] #保存一部电影的所有信息
item = str(item)
#print(item)
#break
#影片详情的链接
link = re.findall(findLink,item)[0] #re库用来通过正则表达式查找指定的字符串
data.append(link) #添加链接
imgSrc = re.findall(findImgSrc,item)[0]
data.append(imgSrc) #添加图片
titles = re.findall(findTitle,item) #片名可能只有一个中文名,没有外国文
if(len(titles)==2):
ctitle = titles[0] #添加中文名
data.append(ctitle)
otitle = titles[1].replace("/","") #去掉无关的符号
data.append(otitle) #添加外国名
else:
data.append(titles[0])
data.append('') #外国名字留空
rating = re.findall(findRating,item)[0]
data.append(rating) #添加评分
judgeNum = re.findall(findJudge,item)[0]
data.append(judgeNum) #添加评价人数
inq = re.findall(findInq,item)
if len(inq)!=0:
inq = inq[0].replace(".","") #去掉句号
data.append(inq) #添加概述
else:
data.append("") #留空
bd = re.findall(findBd,item)[0]
bd = re.sub('<br(\s+)?/>(\s+)?',"",bd) #去掉<br/>
bd = re.sub('/',"",bd) #替换/
data.append(bd.strip()) #去掉前后的空格
datalist.append(data) #把处理好的一部电影信息放入datalist
return datalist
#得到指定一个URL的网页内容
def askURL(url):
head = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39"}
#模拟浏览器头部信息,向豆瓣浏览器发送消息
request = urllib.request.Request(url,headers=head) #用户代理,表示告诉豆瓣服务器,我们是什么类型的机器·浏览器(本质是告诉浏览器,我们可以接受什么水平的内容
html =""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
#print(html)
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
return html
#保存数据
def saveData(datalist,savepath):
print("save...")
book = xlwt.Workbook(encoding="utf-8",style_compression=0)
sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True)
col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
for i in range(0,8):
sheet.write(0,i,col[i]) #列名
for i in range(0,250):
print("第%d条"%(i+1))
data = datalist[i]
for j in range(0,8):
sheet.write(i+1,j,data[j]) #数据
book.save(savepath) #保存
if __name__ == "__main__":
main()
print("爬取完毕!")
四.Urllib库的补充
(1)获取一个get请求
import urllib.request
#获取一个get请求
response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf-8')) #对获取到的网页源码进行utf-8解码
(2)获取一个post请求
import urllib.request
#获取一个post请求
#模拟浏览器发出请求,要用post的格式来封装信息,将data转换为二进制的字节进行封装
import urllib.parse
data = bytes(urllib.parse.urlencode({"hello":"world"}),encoding='utf-8')
response = urllib.request.urlopen("http://httpbin.org/post",data = data)
print(response.read().decode('utf-8'))
(3)超时处理
import urllib.request
try:
response = urllib.request.urlopen("http://httpbin.org/get",timeout=0.01)
print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
print("time out!")
(4)得到属性
import urllib.request
response = urllib.request.urlopen("http://www.baidu.com")
#print(response.status) #status表示状态码
print(response.getheader("Server")) #可以拿到里面的属性
(5)httpbin.org网址的用法
#url = "http://www.douban.com"
url = "http://httpbin.org/post"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39"
}
data = bytes(urllib.parse.urlencode({'name':'eric'}),encoding="utf-8")
req = urllib.request.Request(url=url,data=data,headers=headers,method="POST")
response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
(6)
url = "http://www.douban.com"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39"
}
req = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
五.Bs4库的补充
(1)Tag
#1.Tag 标签及其内容:拿到它所找到的第一个内容
from bs4 import BeautifulSoup
file = open("./temp.html","rb")
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser")
print(type(bs.p))
print(bs.p)
(2)NavigableString
#2.NavigableString 标签里的内容(字符串)
from bs4 import BeautifulSoup
file = open("./temp.html","rb")
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser")
print(bs.p.string)
print(bs.span.string)
print(type(bs.span.string))
print(bs.a.attrs) #可以拿到标签里的所有的属性
print(type(bs))
(3)BeautifulSoup
#3.BeautifulSoup 表示整个文档
from bs4 import BeautifulSoup
file = open("./temp.html","rb")
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser")
print(bs.name)
print(bs)
print(bs.span.string)
(4)Comment
##Comment 是一个特殊的NavigableString,输出的内容不包含注释符号
(5)文档的遍历
#文档的遍历
from bs4 import BeautifulSoup
file = open("./temp.html","rb")
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser")
print(bs.head.contents)
(6)文档的搜索
#1.find_all()
#字符串过滤:会查找与字符串完全匹配的内容
t_list = bs.find_all("a")
print(t_list)
#正则表达式搜索
import re
#正则表达式搜索:使用search()方法来匹配内容
t_list = bs.find_all(re.compile("a"))
print(t_list)
#方法
#方法:传入一个函数(方法),根据函数的要求来搜索(了解)
def class_is_exists(tag):
return tag.has_attr("class")
t_list = bs.find_all(class_is_exists)
print(t_list)
或者
def class_is_exists(tag):
return tag.has_attr("class")
t_list = bs.find_all(class_is_exists)
for item in t_list:
print(item)
#2.kwargs
#t_list = bs.find_all(class_=True)
t_list = bs.find_all(class_="inq")
for item in t_list:
print(item)
#3.text参数
#t_list = bs.find_all(text="肖申克的救赎")
t_list = bs.find_all(text = ["肖申克的救赎","2573211人评价","希望让人自由。"])
#import re
#t_list = bs.find_all(text=re.compile("\d")) #应用正则表达式来查找包含特定文本的内容(标签里的字符串)
for item in t_list:
print(item)
#4.limit参数
t_list = bs.find_all("span",limit=3)
for item in t_list:
print(item)
(7)css选择器
t_list =bs.select('span') #通过标签来查找
t_list =bs.select('.title') #通过类名来查找
t_list =bs.select('#u1') #通过id来查找
t_list =bs.select('a[class=""]') #通过属性来查找
t_list =bs.select('a[href="https://movie.douban.com/subject/1292052/"]')#通过属性来查找
t_list =bs.select("div > a") #通过子标签来查找
for item in t_list:
print(item)
t_list =bs.select(".mnav ~ .bri") #通过子标签来查找
print(t_list[0].get_text())
for item in t_list:
print(item)
六.xlwt库的补充
import xlwt
workbook = xlwt.Workbook(encoding="utf-8") #创建workbook对象
worksheet = workbook.add_sheet('sheet1') #创建工作表
worksheet.write(0,0,'hello') #写入数据,第一行参数“行”,第二个参数“列”,第三个参数是“内容”
workbook.save('student.xls') #保存数据表
workbook = xlwt.Workbook(encoding="utf-8") #创建workbook对象
worksheet = workbook.add_sheet('sheet1') #创建工作表
for i in range(0,9):
for j in range(0,i+1):
worksheet.write(i,j,"%d * %d = %d"%(i+1,j+1,(i+1)*(j+1)))
workbook.save('student.xls') #保存数据表
七.re库的补充
(1)创建模式对象
#正则表达式:字符串模式(判断字符串是否符合一定的标准)
import re
#创建模式对象
pat = re.compile("AA")#此处的AA是正则表达式,用来验证其他的字符串
#m = pat.search("CBA")#search字符串被校验的内容
#m = pat.search("ABCAA")
m = pat.search("AABCAADDCCAAA") #search方法,进行比对查找
print(m)
结果:<re.Match object; span=(0, 2), match='AA'>
(2)没有模式对象
#没有模式对象
import re
m = re.search("asd","Aasd") #前面的字符串是规则(模板),后面的字符串是被校验的对象
print(m)
print(re.findall("a","ASDaDFGAa")) #前面字符串是规则(正则表达式),后面字符串是被校验的字符串
print(re.findall("[A-Z]","ASDaDFGAa")) #找到大写字母
print(re.findall("[A-Z]+","ASDaDFGAa")) #找到大写字母
结果:<re.Match object; span=(1, 4), match='asd'>
['a', 'a']
['A', 'S', 'D', 'D', 'F', 'G', 'A']
['ASD', 'DFGA']
(3)sub替换
#sub
print(re.sub("a","A","abcdcasd"))#找到a用A替换,在第三个字符串中查找
结果:AbcdcAsd
(4)建议在正则表达式中,被比较的字符串前面加上r,不用担心转义字符的问题
#建议在正则表达式中,被比较的字符串前面加上r,不用担心转义字符的问题
a = r"\aabd-\'"
print(a)
结果:\aabd-\'
(5)Re库主要功能函数
re.search() 在一个字符串中搜索匹配正则表达式的第一个位置,返回match()对象
re.match() 从一个字符串的开始位置起匹配正则表达式,返回match()对象
re.findall() 搜索字符串,以列表类型返回全部能匹配的子串
re.sub() 在一个字符串中替换所有匹配正则表达式的子式,返回替换后的字符串
(6)正则表达式的常用操作符
. 表示任何单个字符
[ ] 字符集,对单个字符给出取值范围
[^ ] 非字符集,对单个字符给出排除范围
* 前一个字符0次或无限次扩展
+ 前一个字符1次或无限次扩展
? 前一个字符0次或1次扩展
| 左右表达式任意一个
{m} 扩展前一个字符m次
{m,n} 扩展前一个字符m至n次(含n)
^ 匹配字符串开头
$ 匹配字符串结尾
( ) 分组标记,内部只能使用|操作符
\d 数字,等价于[0-9]
\w 单词字符,等价于[A-Za-z0-9]