因为本篇文章很长,建议去我的个人博客看这篇文章(带有目录更方便):https://jwt1399.top/posts/34992.html
一、基础知识准备
Python基础语法还是很简单的,我通过一个个简单的小段代码来进行学习,所需掌握的知识点都包含在这段段代码中,每段代码都有相应详细注释,如果你有其他语言的基础那么Python基础就是轻轻松松的事。
1 条件判断语句
score = 60
if score >=90 and score <=100:
print("本次考试等级为A")
elif score >=70 and score <90: #elif == else if
print("本次考试等级为B")
else:
print("本次考试等级为C") #output: 本次考试等级为B
2 循环语句
2.1 for循环
for i in range(5): #输出5个数 [0 1 2 3 4]
print(i)
for i in range(0,10,3):#从[0,10),以3为间距输出 #output: [0 3 6 9]
print(i)
for i in range(-10,-100,-30):#从[-10,-100),以-30为间距 #output: [-10 -40 -70]
print(i)
name="chengdu"
for x in name:
print(x) #output: [c h e n g d u]
a = ["a", "b", "c"]
for i in range(len(a)):
print(i, a[i]) #output: [0 a 1 b 2 c]
2.2 while循环
i=0
while i<3:
print("这是第%d次循环:"%(i+1))
print("i=%d"%i)
i+=1
'''#output:
这是第1次循环:
i=0
这是第2次循环:
i=1
这是第3次循环:
i=2
'''
count = 0
while count<3:
print(count,"小于3")
count +=1
else:
print(count,"大于或等于3")
'''#output:
0 小于3
1 小于3
2 小于3
3 大于或等于3
'''
3 字符串
str="chengdu"
print(str) #chengdu
print(str[0]) #c
print(str[0:5]) #[0,5) cheng
print(str[1:7:2]) #[起始位置:结束位置:步进值] hnd
print(str[5:]) #显示5以后的 du
print(str[:5]) #显示5以前的 cheng
print(str+",hello") #字符串连接 chengdu,hello
print(str*3) #打印3次 chengduchengduchengdu
print("hello\nchengdu") #\n换行 hello chengdu
print(r"hello\nchengdu") #前面加"r",表示显示原始字符串,不进行转义hello\nchengdu
print("-"*30) #打印30个“-”
4 列表-List
列表中的每个元素都分配一个数字 - 它的位置或索引,第一个索引是0,第二个索引是1,依此类推。
4.1 列表定义
namelist = ["小张","小王","小李"]
testlist = [1,"测试","str"] #列表中可以存储混合类型
testlist = [["a","b"],["c","d"],["e","f","g"]] #列表嵌套
4.2 列表元素输出
namelist = ["小张","小王","小李"]
#输出指定元素
print(namelist[1]) #output: 小王
#遍历输出
for name in namelist:
print(name)
'''output
小张
小王
小李
'''
#使用枚举函数enenumerate(),同时拿到列表下标和元素类容
for i,name in enumerate(namelist):
print(i,name)
'''output
0 小张
1 小王
2 小李
'''
4.3 列表元素切片
如下所示:L=['Google', 'Python', 'Taobao']
Python | 表达式 结果 | 描述 |
---|---|---|
L[2] | 'Taobao' | 读取第三个元素 |
L[-1] | 'Taobao' | 读取最后一个元素 |
L[1:] | ['Python', 'Taobao'] | 输出从第二个元素开始后的所有元素 |
L[:-1] | ['Google', 'Python'] | 输出从第一个到倒数第一个的所有元素 |
L[-2:] | ['Python', 'Taobao'] | 输出从倒数第二个到末尾的所有元素 |
4.4 列表元素追加
#append
a = [1,2]
b = [3,4]
a.append(b) #将b列表当做一个元素加入到a中
print(a) #output: [1, 2, [3, 4]]
#extend
a = [1,2]
b = [3,4]
a.extend(b) #将b列表中的诶个元素,逐一追加到a中
print(a) #output: [1, 2, 3, 4]
#insert
a=[1,2,4]
a.insert(2,3) ##在下标为2的位置插入3 #指定下标位置插入元素(第一个表示下标,第二个表示元素)
print(a) #output: [1, 2, 3, 4]
4.5 列表元素删除
#del
a = ["小张","小王","小李"]
del a[2] #删除指定下标元素
print(a) #output: ['小张', '小王']
#pop
a = ["小张","小王","小李"]
a.pop() #弹出末尾元素
print(a) #output: ['小张', '小王']
#remove
a = ["小张","小王","小李"]
a.remove("小李") #直接删除指定内容的元素
print(a) #output: ['小张', '小李']
4.6 列表元素修改
a = ["小张","小王","小李"]
a[2] = "小红" #修改指定下标元素内容
print(a) #output: ['小张', '小王', '小红']
4.7 列表元素查找
#in / not in
a = ["小张","小王","小李"]
findName = input("请输入你要查找的学生姓名:")
if findName in a:
print("找到")
else:
print("未找到")
#index
a = ["小张","小王","小李"]
print(a.index("小王",0,2)) #可以查找指定下标范围的元素,并返回找到对应数据的下标 #output: 1
print(a.index("小李",0,2)) #范围区间:左开右闭[0,2) # ValueError: '小李' is not in list
#count
print(a.count("小王")) #查找某个元素出现的次数 #output: 1
4.8 列表元素反转和排序
a = [1,4,2,3]
a.reverse() #将列表所有元素反转
print(a) #output: [3, 2, 4, 1]
a.sort() #升序
print(a) #output: [1, 2, 3, 4]
a.sort(reverse=True) #降序
print(a) #output: [1, 2, 3, 4]
5 前段知识综合练习
Topic: 将8个老师随机分配到3个办公室
import random
offices = [[],[],[]] #3个教室
teachers = ["A","B","C","D","E","F","G","H"] #8个老师
for teacher in teachers: #遍历teachers放入office中
index = random.randint(0,2) #产生随机数0,1,2
offices[index].append(teacher) #将teachers追加到office中
i=1 #office1
for office in offices: #输出每个office人数和对应的老师
print("office%d的人数为:%d"%(i,len(office)))
i += 1 #遍历offices
for name in office:
print("%s"%name,end="\t") #打印每个office老师的名字
print("\n") #打印完一个office换行
print("-"*20) #打印完一个office输出20个-
6 元组-Tuple
元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
6.1 元组定义
tup1=() #空元组
tup2=(5) #<class 'int'> 不是元组
tup2=(5,) #<class 'tuple'>
tup3 = ('Google', 'Python', 1997, 2000)
6.2 元组元素切片
tup=(1,2,3)
print(tup[0]) #第一个元素 #output: 1
print(tup[-1]) #最后一个元素 #output: 3
print(tup[0:2]) #左闭右开[0,2) #output: (1, 2)
6.3 元组元素增加(连接)
tup1 = (12,34,56)
tup2 = ("ab","cd","ef")
tup3 = tup1+tup2
print(tup3) #(12, 34, 56, 'ab', 'cd', 'ef')
6.4 元组元素删除
tup1 = (12,34,56)
#del tup1[0] #不允许删除单个元素
del tup1 #删除了整个元组变量
6.5 元组元素不能修改
tup1 = (12,34,56)
tup1[0] = 72 #报错 不能修改
7 字典-dict
字典使用键值对(key=>value)存储;键必须是唯一的,但值则不必。
7.1 字典定义
dict = {key1 : value1, key2 : value2 }
info = {"name":"简简","age":18}
7.2 字典访问
info = {"name":"简简","age":18}
print(info["name"])
print(info["age"])
#访问不存在键
print(info["sex"]) #直接访问不存在的键,会报错
print(info.get("sex")) #使用get()方法,访问不存在的键,默认返回:none
print(info.get("sex","没有")) #没有找到的时候,返回自定义值 #output: 没有
7.3 字典键值增加
info = {"name":"简简","age":18}
info["sex"]="man" #新增sex
print(info) #output: {'name': '简简', 'age': 18, 'sex': 'man'}
7.4 字典键值删除
#del
info = {"name":"简简","age":18}
del info["name"] #删除name键值对
print(info) #output: {'age': 18}
del info #删除整个字典
print(info) #output: NameError: name 'info' is not defined
#clear
info = {"name":"简简","age":18}
info.clear() #清空字典内键值对
print(info) #output: {}
7.5 字典键值修改
info = {"name":"简简","age":18}
info["age"]=20
print(info)
7.6 字典键值查找
info = {"name":"简简","age":18}
print(info.keys()) #得到所有的键 #output: dict_keys(['name', 'age'])
print(info.values()) #得到所有的值 #output: dict_values(['简简', 18])
print(info.items()) #得到所有的键值对 #output: dict_items([('name', '简简'), ('age', 18)])
#遍历所有的键
for key in info.keys():
print(key) #output: name age
#遍历所有的值
for value in info.values():
print(value) #output: 简简 18
#遍历所有的键值对
for key,value in info.items():
print("(key=%s,value=%s)"%(key,value))
#output: (key=name,value=简简) (key=age,value=18)
8 函数
8.1 函数定义和使用
def printinfo(a,b): #函数定义
c =a + b
print(c)
printinfo(1,2) #函数的使用
8.2 带返回值的函数
def info(a,b):
c =a + b
return c #返回值
print(info(1,2))
8.3 返回多个值的函数
def divid(a,b):
shang = a//b
yushu = a%b
return shang,yushu #多个返回值用逗号隔开
sh,yu = divid(5,2) #需要用多个值来保存返回内容
print("商:%d 余数:%d"%(sh,yu))
9 文件操作
9.1 打开文件(open)
用法:对象=open(文件名,访问模式)
f = open('test.txt', 'w')
模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
9.2 关闭文件(close)
用法:对象.close()
f.close()
9.3 写数据(write)
用法:对象.write()
f=open("test.txt","w") # 打开文件,w(写模式)-文件不存在就在当前路径给你新建一个
f.write("hello,world") # write将字符写入文件
f.close()
9.4 读数据(read)
用法:对象.read()
f=open("test.txt","r") #打开文件,r(读模式)
content=f.read(5) #read读取5个字符
print(content)
f.close()
9.5 读一行数据(readline)
用法:对象.readline()
f = open('test.txt', 'r')
content = f.readline()
print("1:%s"%content)#读取一行
content = f.readline()
print("2:%s"%content)#再读下一行
f.close()
9.6 读多行数据(readlines)
用法:对象.readlines()
f=open("test.txt","r") #打开文件,r(读模式)
content=f.readlines() #readlines读取整个文件,以列表形式输出
print(content) #输出形式为列表 #output: ['hello,world\n', 'hello,world']
#对列表进行处理,按序号一行一行输出
i=1
for temp in content:
print("%d:%s" % (i, temp))
i += 1 #output: 1:hello,world 2:hello,world
f.close()
9.7 OS模块
- 使用该模块必须先导入模块:
import os
os模块中的函数:
序号 | 函数名称 | 描述 | 格式 |
---|---|---|---|
1 | getcwd() | 获取当前的工作目录 | 格式:os.getcwd() 返回值:路径字符串 |
2 | chdir() | 修改当前工作目录 | 格式:os.chdir() 返回值:None |
3 | listdir() | 获取指定文件夹中的 所有文件和文件夹组成的列表 | 格式:os.listdir(目录路径) 返回值:目录中内容名称的列表 |
4 | mkdir() | 创建一个目录/文件夹 | 格式:os.mkdir(目录路径) 返回值:None |
5 | makedirs() | 递归创建文件夹 | 格式:os.makedirs(路径) |
6 | rmdir() | 移除一个目录(必须是空目录) | 格式:os.rmdir(目录路径) 返回值:None |
7 | removedirs() | 递归删除文件夹 | 格式:os.removedirs(目录路径) 返回值:None 注意最底层目录必须为空 |
8 | rename() | 修改文件和文件夹的名称 | 格式:os.rename(源文件或文件夹,目标文件或文件夹) 返回值:None |
9 | stat() | 获取文件的相关 信息 | 格式:os.stat(文件路径) 返回值:包含文件信息的元组 |
10 | system() | 执行系统命令 | 格式:os.system() 返回值:整型 慎用! 玩意来个rm -rf 你就爽了! |
11 | getenv() | 获取系统环境变量 | 格式:os.getenv(获取的环境变量名称) 返回值:字符串 |
12 | putenv() | 设置系统环境变量 | 格式:os.putenv('环境变量名称',值) 返回值:无 注意:无法正常的getenv检测到。 |
13 | exit() | 推出当前执行命令,直接关闭当前操作 | 格式:exit() 返回值:无 |
10 异常处理
10.1 异常简介
print '-----test--1---'
open('123.txt','r')
print '-----test--2---'
image-20200323100011079
打开一个不存在的文件123.txt,当找不到123.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:123.txt (没有123.txt这样的文件或目录)
10.2 捕获异常
try:
print('-----test--1---')
open('123.txt','r')
print('-----test--2---')
except IOError:
pass
此程序看不到任何错误,因为用except 捕获到了IOError异常,并添加了处理的方法
pass 表示实现了相应的实现,但什么也不做;如果把pass改为print语句,那么就会输出其他信息
总结:
image-20200323100335376把可能出现问题的代码,放在try中
把处理异常的代码,放在except中
try:
print num
except IOError:
print('产生错误了')
上例程序,已经使用except来捕获异常,但是还会看到错误的信息提示
except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,所以except没有生效
try:
print num
except NameError:
print('产生错误了')
Python的一些內建异常:
异常 | 描述 |
---|---|
Exception | 常规错误的基类 |
AttributeError | 对象没有这个属性 |
IOError | 输入/输出操作失败 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象 (没有属性) |
SyntaxError | Python 语法错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
更多可以参考:http://blog.csdn.net/gavin_john/article/details/50738323
10.3 捕获多个异常
#coding=utf-8
try:
print('-----test--1---')
open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
print('-----test--2---')
print(num)# 如果num变量没有定义,那么会产生 NameError 异常
except (IOError,NameError):
#如果想通过一次except捕获到多个异常可以用一个元组的形式
10.4 获取异常的信息描述
image-20200323102016442 image-20200323102023020.png10.5 try...finally...
在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。 比如文件关闭,释放锁,把数据库连接返还给连接池等
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
#如果在读取文件的过程中,产生了异常,那么就会捕获到
#比如 按下了 ctrl+c
pass
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")
test.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。
二、Python爬虫
下面的学习方式是以爬取豆瓣top250 网页进行开展的
基本流程: 爬取网页--->解析数据--->保存数据
爬取网页
首先要学习requests库或者urllib库的使用,不然你无法看懂下面代码
学习requests库,请看我另外一篇文章,里面对requests库进行了详细的讲解Python模块-Requests学习
爬取豆瓣top250第一页数据
#-*- coding =utf-8 -*-
import requests
def askUrl(url):
head = { #模拟浏览器头部信息,向豆瓣服务器发送消息
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36 Edg/81.0.416.34"
# 用户代理:告诉豆瓣服务器,我们是什么类型的浏览器(本质上是告诉浏览器我们可以接收什么水平的文件内容)
}
html="" #用来接收数据
r = requests.get(url, headers = head) #get方式发送请求
html = r.text #接收数据
print(html)
return html
if __name__ == "__main__": # main函数用于测试程序
askUrl("https://movie.douban.com/top250?start=") #调用函数
可以看到成功的爬取到豆瓣top250第一页的数据
image-20200327113957848爬取豆瓣top250所有的10页数据数据
#-*- coding =utf-8 -*-
import requests
#爬取一个页面
def askUrl(url):
head = { #模拟浏览器头部信息,向豆瓣服务器发送消息
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36 Edg/81.0.416.34"
# 用户代理:告诉豆瓣服务器,我们是什么类型的浏览器(本质上是告诉浏览器我们可以接收什么水平的文件内容)
}
#html=""
r = requests.get(url, headers = head)
html = r.text
print(html)
# 爬取所有页面
def getData(baseurl):
for i in range(0, 10):
url = baseurl + str(i * 25)
html = askUrl(url)
if __name__ == "__main__": # main函数用于测试程序
baseurl = "https://movie.douban.com/top250?start="
getData(baseurl)
可以看到排名250的梦之安魂曲也被成功爬取到
image-20200327115150029
网友评论