Python爬虫基础包括HTTP协议、HTML、CSS和JavaScript语言基础、requests库的使用、Beautiful Soup库的使用、xpath和正则表达式的使用等。此外,还应该了解反爬虫机制和爬虫的一些常见问题及解决方法。
上一篇文章讲解了有关条件判断语句、循环语句、元组、字典等相关知识,本节将围绕代码异常处理以及捕获来实践。
10、异常处理
10.1 异常简介
print '-----test--1---'
open('123.txt','r')
print '-----test--2---'
打开一个不存在的文件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语句,那么就会输出其他信息
总结:
把可能出现问题的代码,放在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 | 除(或取模)零 (所有数据类型) |
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 获取异常的信息描述
10.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从句仍然被执行,把文件关闭。
11、Python知识
除法
除 /
整除 //
求余 %
商和余数的元组 divmod
移位操作
左移(<<)
a<<n,则a' =a*(2^n),左移 n 位相当于原操作数乘以 2^n,原操作数不发生变化。
>>> 3<<1 # 向右移动一位,相当于是乘以2
6
>>> -3<<2 # 向右移动一位,相当于是乘以4
-12
右移(>>)
a>>n,则a' =a//(2^n),左移 n 位相当于原操作数整除 2^n,原操作数不发生变化。
>>> 2>>1 # 移动一位,相当于是2//2
1
>>> 2>>2 # 相当于先左移一位得到1,结果1再除以2等于0
0
>>> 2>>3 # 相当于2//8
0
>>> -8>>2 # 移动2位,相当于-8//4
-2
>>> -8>>3 # 移动3位,相当于是用结果-2再除以2
-1
>>> -8>>4 # 移动4位,相当于是用结果-1再除以2
-1
如果操作数是正数,那么对之不停进行右移操作,最终结果一定可以得到 0;如果操作数是负数,对之不停进行右移操作,最终结果一定可以得到 -1。
匿名函数lambda
匿名函数 lambda 是指一类无需定义标识符(函数名)的函数或子程序。
lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。
语法:
lambda [arg1,arg2,.....argn]:expression
冒号前是参数,可以有多个,用逗号隔开,冒号右边的为表达式(只能为一个)。其实lambda返回值是一个函数的地址,也就是函数对象。
lambda arg: print("hello,world",arg)
lambda表达式限制只能包含一行代码,但是其实可以利用元组或列表强行让其包含多行。(但是这么做会严重影响可读性,除非万不得已不要使用)
lambda :(
print("hello"),
print("world"),
)
切片
t=[1,2,3,4,5]
print(t[1:]) 取第二个到最后一个元素
结果:[2 3 4 5]
print(t[:]) 取所有元素
结果:[1 2 3 4 5]
print(t[1:3]) 取t[1]-t[2]
结果:[ 2 3 ]
print(t[:-1]) 除了最后一个取全部
结果:[ 1 2 3 4 ]
print(t[::-1]) 取从后向前(相反)的元素
结果:[ 5 4 3 2 1 ]
print(t[2::-1]) 取从下标为2的元素翻转读取
结果:[ 3 2 1 ]
字符串方法
join(iterable)
获取可迭代对象(iterable)中的所有项目,并将它们连接为一个字符串。
实例1:
myTuple = ("Bill", "Steve", "Elon")
x = "#".join(myTuple)
print(x)
'''
输出:
Bill#Steve#Elon
'''
实例2:
myDict = {"name": "Bill", "country": "USA"}
mySeparator = "TEST"
x = mySeparator.join(myDict)
print(x)
'''
输出:
nameTESTcountry
'''
注释:在使用字典作为迭代器时,返回的值是键,而不是值。
split(separator, max)
将字符串拆分为列表,您可以指定分隔符,默认分隔符是任何空白字符。若指定 max,列表将包含指定数量加一的元素。
实例1:
txt = "welcome to China"
x = txt.split()
print(x)
'''
输出:
['welcome', 'to', 'China']
'''
实例2:
txt = "apple#banana#cherry#orange"
# 将 max 参数设置为 1,将返回包含 2 个元素的列表!
x = txt.split("#", 1)
print(x)
'''
输出:
['apple', 'banana#cherry#orange']
'''
内置函数
enumerate()
用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
实例1:
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three
实例2:
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 下标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
exec()
exec 执行储存在字符串或文件中的 Python 语句,相比于 eval,exec可以执行更复杂的 Python 代码。
# 单行语句字符串
>>>exec('print("Hello World")')
Hello World
# 多行语句字符串
>>> exec ("""for i in range(5):
... print ("iter time: %d" % i)
... """)
iter time: 0
iter time: 1
iter time: 2
iter time: 3
iter time: 4