该文章为整理文档理使其方便个人使用
使用换行符分隔,一般情况下,一行书写一条语句
从第一列开始,前面不能有任何空格
以 # 开始的语句是注释语句,可以从任意位置开始书写,养成良好的注释习惯
所有的语法符号,比如冒号、单引号、双引号、小括号等都必须在英文状态下输入
代码的缩进很重要。缩进是代码逻辑关系的重要方式,在使用选择、循环或者编写函数的时候,务必注意代码的缩进。一般情况下,缩进一个"TAB"(4个字节)。
标识符必须以字母或者下划线_开头,后跟字母、数字或者下划线的任意序列。
标识符区分大小写。num、Num、NUM是完全不同的三个名称。
命名时可以采用"驼峰式"命名法,就是当变量名或者函数名时由一个获多个单词连接在一起时,第一个单词以小写字母开始,第二个单词及以后每个单词的首字母都采用大写字母,如myFirstName 、myLastName。
给变量命名的时候尽量避免以单个下划线或者两个下划线开头的标识符,因为在Python语言的解释器中,她们有特殊含义,是内建标识符使用的符号,一般与类的相关特性有关,有的是类属性,有的是类的私有成员,有的是类的构造函数等。
不能定义Python中内置的关键词。
数字类型:整形 int、浮点型 float、复数 complex、布尔型 bool
序列类型:字符串str、列表list、元组tuple
集合类型:集合set
映射类型:字典dict
可变的有:列表list、集合set、字典dict 其余都不可变。
另外python中没有java中的char数据类型。
int类型不限制大小,只受限于计算机内存。
float受到17位有效数字的限制。浮点数运算存在不确定性。
Eg: 4.2+2.1 == 6.3 False
数值运算操作符:
+:加 -:减 *:乘 /:除
//:整除
%:取余
**:乘方 例:pow(x,y) ==等同==> x**y
常见内置运算函数:
abs() 绝对值
divmod(x,y) 输出(x//y, x%y)
round(x) 四舍五入
max(x1,x2,x3…) 最大值
min(x1,x2,x3…) 最小值
复数的计算可以引用:import cmath
dir(cmath)
:查看所有cmath中定义的函数
逻辑运算符:and => &&、or => ||、not => !
优先级:not>and>or
字符串定义方式有四种
单引号:' '
双引号:" "
三单引号:''' '''
三双引号:""" """
后两者可用于跨行。
字符串的索引: str[序号]
"H e l l o"
正向序号: 0 1 2 3 4
反向序号:-5 -4 -3 -2 -1
通过下标访问单个元素。正向下标从0开始,反向下标从-1开始。
如访问'e' ==> str[1] 或者 str[-4]
字符串的切片,获取多个元素。
str[起始下标:终点下标:步长],
其中[起始下标:终点下标]是一个左闭右开的区间。
Eg: str = '123 456 789'
s[:] #正向获取所有元素
s[::-1] #反向获取所有元素
s[6:-1] #'6 78',获取不到最后一个元素
s[2:9:2] #'3467'
字符串的处理操作
+:字符串拼接 #'AB'+'12' ——> 'AB12'
*:字符串复制 #'ab'*3 ——> 'ababab'
in: 判断是否字串 #'H' in 'Hello' ——> True
len(): 字符串长度 #len('ab') ——> 2
内置的方法
s.index() 获取索引号
#s='Hello' s.index('e') =====1
s.count() 返回出现次数
#s.count('l') =====2
字符串分割: s.split()、s. rsplit()
从字符串的左侧或者右侧开始按照制定的分隔符进行分割,返回列表
字符分割:s.partition()、s.rpartition()
以指定字符串为分隔符将原字符串分隔为3个部分,
即分隔符前、分隔符、分隔符后的字符串。
如果分隔符不存在,返回原字符串和两个空字符串。
#s = 'bird, fish, monkey, fish, rabbit'
#s.partition('fish') --> ['bird', 'fish', 'monkey, fish, rabbit']
#s.rpartition('fish') -->['bird, fish, monkey', 'fish', 'rabbit']
列表元素拼接: '连接符'.join(str)
#li = ['apple', 'banana', 'pear']
#':'.join(li) ===== 'apple: banana: pear'
大小写转换:
s.lower():大写转小写
s.upper():小写转大写
s.capitalize():首字母大写
s.title():每个单词的首字母大写
s.swapcase():大小写互换
字符串替换:s.replace('原', '替换')
删除空白字符和指定字符
s.strip():删除两端空白或者指定字符
# s = ' abc ' s.strip()
s.rstrip():删除右侧
#s = '===abc===' s.rstrip('=')
s.lstrip(): 删除左侧
#s = '===abc===' s.lstrip('=')
字符串排版
s.center(字符串长度,'填充字符(可省略)')
s.ljust():居左对齐 #s = 'Hello' s.ljust(9,'==') ' Hello '
s.rjust():居右对齐
s.zfill():左侧以0填充
字符串的格式化:
str.format() 通过{}和":"来代替之前的"%"
(1)默认顺序或指定顺序:
Eg:print("我是{}班{}号学生{}".format('191班级',10,'某某'))
print("我是{1}班{2}号学生{0}".format('某某','大数据191',10))
(2)对字符串的格式化:
{}中输入 ":" , ":" 后分别设置<填充字符><对齐方式><宽度>
<填充字符> * = -等等,默认为空格
<对齐方式> ^(代表居中)、<(代表左对齐)、>(代表右对齐)
<宽度> 一个整数
Eg:print("{:*^20}".format("MIKE"))====='********MIKE********'
(3)对实数的设置
Eg: print("{:.2f}".format(3.1415926)) #保留两位小数
print("{:=^30.4f}".format(3.1415926))'============3.1416============'
#宽度30,居中对齐,=填充,保留4位小数
print("{:.5d}".format(24)) ' 24' #宽度5,右对齐,空格填充,整数。
列表:可变、有序;特性:可变对象、可变长度、异构、任意嵌套
创建:[] list() 元素以逗号间隔。
索引:从0开始 listname[索引]
切片:listname[开始索引:结束索引:步长] ,区间属于左闭右开
listname[2:10:3]
增加:
listname.append(元素) 在末尾增加新的一个元素
listname.extend(序列) 在末尾增加多个元素
listname.insert(索引位置,元素) 在索引位置处添加元素
删除:
del listname[索引]
listname.pop(index=-1) 默认删除最后一个
listname.remove(元素)
排序:
listname.sort(reverse = False)
# 元素按照大小正向或反向排序
listname.reverse()
# 元素反向输出,注意区别
sorted(listname, reverse= False/True)
# 元素正向或反向排序,区别在于sorted生成副本,不修改原listname。
Eg: listname = [1,2,5,8,3]
print(listname.sort(reverse = True)
print(listname.reverse())
sorted(listname,reverse = True)
print(listname)
遍历:
(1)利用range():
for i in range[]:
listname[i]
(2)直接遍历元素
for item in listname:
清空列表:listname.clear()
del listname
复制列表:
newlist =listname
# 指向同一个列表,同时修改同时改变。列表多了一个名字而已,属于浅拷贝
copylist = listname.copy()
# 复制一个新的副本,对副本操作,不会改变原始列表
copylist = listname[:]
# 切片复制出来,然后赋值给新的列表
五、元组(元素不可修改)
元组:不可变、有序;特性:可变长度、异构、任意嵌套
创建:() tuple() 元素以逗号间隔。
索引:从0开始 tuplename[索引]
切片:tuplename[开始索引:结束索引:步长] ,区间属于左闭右开
tuplename[2:10:3]
可操作:
数据读取/切片 索引/切片
删除整个元组 del tuplename
长度、最大值、最小值、求和 len() max() min() sum()
返回索引 tuplename.index(value)
统计次数 tuplename.count(value)
遍历 for I in tuplename
排序 sorted(tuplename)返回列表,sort()不能用
转换列表 list(tuplename)
元组充当列表元素
案例: list1 = [('张三',90),('李四', 80)]
List1[0] = ('张三',90)
List1[0][1] = 90
# 如果要修改90为85,无法直接用list1[0][1],
# 而需要重新赋值list1[0]= ('张三',85)
六、字典
字典属于映射类型,它是通过键实现元素存取,具有无序、可变长度、异构、嵌套和可变类型容器等特点。
创建字典
(1) 直接创建:{键1:值1,键2:值2…….}
d = {}
d = dict()
d = {'a':1,'b':2,'c':3}
(2) 使用内置函数dict()创建,意在实现将一组双元素序列转换为字典类型。
li = [('a',1),('b',2)]
d= dict(li)
[注意]:
访问字典
字典名[键]
字典名[键][索引值]
dict = {'张三':[60,70],'李四':[70,80]}
dict['张三'] dict['张三'][1]
[注意]:
- 如果键值不存在,会报错。字典支持键到值的单向访问,不支持值到键的访问。
- get()方法获取条目的值:
d.get('张三') [60,70]
d.get('王五', '未知') == '未知'
d.get('王五') ==== 无返回
通过get()方法获取指定键的值时,如果字典中没有这个键,则返回给的默认值,
如未定义默认值,该语句执行,但不返回任何信息。
字典的操作:增删改
增加: 直接赋值 d[键] = 值
修改: 直接修改 d[键] = 值
删除: 1. del d[键]
2. d.pop(键,默认值) 指定删除
3. d.popitem() 随机删除
4. clear() 清空
5. del d 删除整个字典
[注意]:
字典的遍历
遍历key:
d.keys()
for k in d.keys():
print(k)
遍历value:
d. values()
for v in d.values()
print(v)
遍历item:
d.items()
for item in d.items()
print(item)
for k ,v in d.items()
print(item)
排序
字典不支持sort()方法,支持sorted()方法。
sorted()方法可以将字典的键排序并以列表的形式返回。
d = {'张三':60,'李四':70}
d.sort()
sorted(d)
字典的合并
(1) d1 与 d2: d1.update(d2)
(2) d = d1+d2: d = dict(list(d1)+list(d2))
针对双元素类型
七、集合
集合时一种集合类型,被用来存放一组无序且会不相同的元素。
组成集合的元素必须是不可变类型。元素也不能重复。
1. 集合的创建
* 直接创建 {元素1,元素2…….}
* 用set()创建,重复的元素只能保留一个
s = set('Hello world!')
s = set(1231)
s = set([1,2,4,2,5])
* 创建空集合 s = set()
2. 集合的操作
1.添加元素 s.add(item) 其中item是不可变类型
s.update(items) 将items中的元素拆分去重后
加入集合,此时items是可变类型 S = {1,2,3}
s.add((2,3,4))
s.update({2,3,4})
2.删除元素 s.remove(item) item不存在会报错
s.discard(item) item不存在,不报错
s.pop() 随机删除一个元素并返回
s.clear() 清空 S= {1,2,3,4}
s.remove(5) 报错
s.discard(5) 不报错
3.成员判断 Item in s
S ={1,2,3,4} 3 in s
3. 集合的数学
A={1,2,3,4,5} B={4,5,6,7,8}
1.交集 A&B
* 方法: A.intersection(B) {4,5}
2.并集 A|B
* 方法: A.union(B) {1,2,3,4,5,6,7,8}
3.差集 A-B
* 方法: A.difference(B) {1,2,3}
4.对称差 A^B
* 方法:A.symmetric_difference(B) {1,2,3,6,7,8}
例题:IEEE和TIOBE是两大热门编程语言排行榜。截止2018年12月,IEEE排名前五的编程语言是:Python 、C++、 C、 Java 、C# ;TIOBE排名前五的编程语言是:Java 、 C 、Python 、 C++ 、VB.NET。求出:
(1)上榜的所有语言。
(2)在两个榜单中同时排名前五的语言。
(3)只在IEEE排名前五的语言。
(4)只在一个榜单排名前五的语言。
解:
IEEE={"Python","C++","C","Java","C#"}
TIOBE={"Java","C","Python","C++","BV。NET"}
one=IEEE.union(TIOBE)
print(one)
two=IEEE.intersection(TIOBE)
print(two)
three=IEEE.difference(TIOBE)
print(three)
four=IEEE.symmetric_difference(TIOBE)
print(four)
计算语句结构如下:
流程控制结构一般分为三类:顺序结构、选择结构、循环结构。
单向选择分支、双向选择分支、多向条件分支、条件嵌套
1. 单向分支:
if 表达式:
语句块
2. 双向分支:
if 表达式:
语句块1
else:
语句块2
[注意]:双分支的简洁表达形式
语句1 if 条件表达式 else 语句2
Eg: x=int(input("x= "))
print(x) if x >= 0 else print(-x)
3. 多向分支:
if 表达式1:
语句块1
elif 表达式2:
语句块2
elif 表达式3:
语句块3
......
else:
语句块n
4. 条件嵌套
if 表达式1:
if 表达式2:
语句块2
else 表达式3:
语句块3
else:
语句块4
[注意一]:
for语句:
for语句用一个循环控制器(Python语言中称为迭代器)
来描述语句块的重读执行方式。
语法:
for 变量 in 迭代器:
语句块
break #跳出循环
continue #略过余下循环语句
else:
语句块
[注意]:
while语句:
语法:
while 循环条件:
语句块1
break #跳出循环
continue #略过余下循环语句
else:
语句块2
[注意]: for和while的区别:当不知道循环次数,但知道循环条件时,一般使用while语句。
左闭右开的数列。
--直接当序列,或者转换为list或者tuple等容器类型
语法:
range(n) 返回[0,n)的数列
range(m,n) 返回[m,n)
range(m,n,d) 返回[m,n),步长为d
Eg:
list(range(10))
list(range(5,10))
list(range(1,10,2))
list(range(10,1,-2))
range(10)
tuple(range(10))
函数:表示从自变量到因变量之间的一种映射和对应关系。也是把输入经过一定的变化和处理最后得到预定的输出。从外部看,函数就像一个黑盒子,不需要了解其内部原理,只需要了解其接口获使用方法。
Python中函数可以分为四种类型:
(1) 内置函数。如 abs() len()
(2) 标准库函数。 Import math math.pi
(3) 第三方库函数。 Import numpy 、matplotlib\pandas\turtle\datetime
(4) 用户自定的函数。
定义:
def 函数名([参数列表]):
函数体
[注意]:
2.调用:函数名([实参列表])
[注意]:
(1):实参列表必须与函数定义的形参列表一一对应。
(2):函数有三种将实际参数传递给形式参数:按位置传递参数、按名称传递参数和按默认值传递参数。
(3):函数如有没有返回值,则可以在表达式中继续使用。如果函数没有返回值,则可以单独作为表达式语句使用。
Eg: def max(a,b): #定义最大值函数,其中a,b是形参
if a>b:
return a
else:
return b
Max(12,45) #调用函数,传入实参
```python
[课堂案例]:
[1]:编写函数,求1+2+。。。。。+100的和。(定义+调用)
[2]:编写函数,求任意个连续整数的和。(定义+调用+参数)
[3]:编写函数,求(1+3+。。。+20)+(11+12+。。。+100)
的和。(定义+调用+参数+返回值)
[课堂练习1]:
[1]:找出2-100中所有的素数。
[2]:找出2-100中所有的孪生素数。孪生素数是指相差2的素数对。如3和5,5和7等。
[3]:将4-20中所有的偶数分解成两个素数的和。例如6=3+3、8=3+5等。
默认值参数
在声明函数时,如果希望函数的一些参数是可选的,则可以在声明函数时为这些参数指定参数值。调用函数时,如果没有传入相应的实参,则函数使用指定的默认参数值。默认值参数必须卸载形参列表的右边,因为默认是按照位置传递实际参数值的。
定义:
def babble(words, times = 1):
print((words+ ' ')* times
调用:
babble('hello',3):
babble('hello')
名称传递参数
函数调用时,实参默认按照位置顺序传递参数,按照位置传递的参数称为位置参数。函数调用时,也可以通过名称(关键字)指定传入的参数,按照名称指定传入的参数称为名称参数,也称关键字参数。
使用名称传递参数具有三个优点:参数意义明确;传递的参数与顺序无关,如果有多个可选参数,则可以选择指定某个参数值。
可变参数
可使用带星号的参数,如*param1,允许向函数传递可变数量的参数。调用函数时,从该参数之后的所有参数都被收集为一个元组。
定义:def countNum(*c): #利用可变参数输出名单
for i in c:
print("{:^4}".format(i),end = ' ')
return len(c)
调用:num= countNum("李白","杜甫")
可使用带两个星号的参数,如**param2,允许向函数传递可变数量的参数。调用函数时,从该参数之后的所有参数都被收集为一个字典。
定义:def countNum(**d): #利用可变参数求人数和
total = 0
print(d)
for key in d:
total+=d[key]
return total
调用:print(countNum(male=5,female=12))
{'male':5 , "female":12}
17
实参与形参
案例:
def addInterest(money, rate):
money =money * (1+rate)
amount = 1000
rate = 0.05
addInnterest(amount, rate)
print(amount)
原因:实参和形参的作用域不一样,她们是两个单独的变量。形参变量只能接收实参变量的值,而无法访问实参变量。因此,为形参分配新值对包含实参的变量没有影响。解决方法可以return。
返回多个值
Return语句可以返回多个值,返回的是一个元组。
def fun(a,b):
return (a,b,a//b,a%b)
变量的访问权限取决于这个变量是在哪里赋值的。每个变量都有自己的作用域(命名空间),变量的作用域决定了在某些代码段内使用该变量是合法的,哪些地方是不合法的。有两种作用域:局部变量(每次函数调用都会创建一个新的作用域)和全局变量。
def f():
x = 10 #局部变量
return x*x
x = 1000 #全局变量
f()
print(x)
[注意]:如果局部变量和全局变量同名时,注意局部优先。
def f():
x =5 #局部变量
print("f内部:x= ",x)
return x*x
x = 10 #全局变量
print("f()=",f())
print("f外部:x=",x)
如果遇到一定要在函数f()内部访问全局变量x时,可以使用关键字global,声明为全局变量。例如在上面的代码中第二行增加global x,输出结果就不一样了。
[课中练习2]:
编写函数,接收任意多的参数,返回一个元组,其中第一个元素为所有参数的平均值,其他元素为所有参数中大于平均值的实数。
[课中练习3]:
编写函数,提取短语的首字母缩略词。首字母缩略词是由短语中的每个单词去首字母,并且大写组合而成。例如:very important person ==== VIP
1.lambda匿名函数
该函数时一种简便的,在同一行定义函数的方法。实际上生成了一个函数对象,及匿名函数,它广泛用于需要函数对象作为参数获函数比较简单并且只使用一次的场合。
语法:
lambda 参数1, 参数2,…… : <函数语法>
其中函数语句的结果为函数的返回值,且只能是一条语句。
没懂
(1) lambda x,y: x*y
def f(x,y):return x*y
(2) f = lambda x:x<0
def f(x): if x<0 : return x
list = [3,5,-7,4,-1,0,-9]
for I in fliter(f,list):
print(i)
(3) for i in fliter(lambda x : x%3 == 0 and x%10 ==0, range(1,100+1)):
print(i)
在python中,如果一个函数既可以调用另一个函数,也可以调用自己,这个过程叫递归。
例如:
求n! = n*(n-1)*……*1
N = 1 1!=1
N=2 2! = 2*1!
N=3 3! =3*2*1 = 3*2!
def fact(n):
if n ==1:return 1
else : return n *fact(n-1)
for i in range(1,9+1):
print("{}!=".format, fact(i))
每个递归函数必须包括两个主要部分:
[练习4]:用递归方法求斐波拉契数列。
Fn = 1 (N = 1,2)
Fn = fn-1+fn-2 (n>=3)
[练习5]: 现有一个字典存放着学生的学号和成绩。成绩列表里面的3个数据分别是学生的语文、数学和英语成绩:
Dict = {'01':[67,88,45], '02':[97,68,85], '03':[97,98,95], '04':[67,48,45], '05':[82,58,75], '06':[96,49,65]}
完成以下操作:
(1) 编写函数,返回每门成绩均大于等于85的学生的学号;
(2) 编写函数返回每一个学号对应的平均分(sum和len)和总分(sum),结果保留两位小数。
(3) 编写函数返回按总分升序排列的学号列表。
概念:
异常是一个事件,该事件会在程序执行过程中有语法等错误时发生,异常会影响程序的正常执行。
发生异常时,可以通过try语句来实现,一共有四种语句,分别是
try……except
try……except….finally
try……except…..else
try(with)……except
语法:
(1)try……except
try
语句块
except Exception[as reason]:
出现异常后的处理代码
(2)try……except….finally
try
语句块
except Exception[as reason]:
出现异常后的处理代码
finally:
无论如何都会被执行的代码
(3)try……except…..else
try
语句块
except Exception[as reason]:
出现异常后的处理代码
else:
没有异常后被执行的代码
(4)try(with)……except
try
with <语句> as name:
语句块
except Exception[as reason]:
出现异常后的处理代码
观察共同点:
观察区别:
主动抛出异常:
raise Exception(defineexceptname)
Eg :
raise ZeroDivisionError('1除以0')
自定义异常类
class MyError(Exception): #MyError继承自Exception父类
pass #pass代表空语句
raise MyError('自定义的异常') #在函数体内可加上
文件是一组相关数据的集合,组成文件的数据可以是ASCII编码,也可以是二进制编码。
文件一定有文件名,包括两个部分:主文件名和扩展名。主文件名用于指明访问对象,扩展名用户指定访问和处理文件的应用程序。目录是用来组织和管理一组相关文件的。
文件保存的位置称为路径。路径分为绝对路径和相对路径。
文件的打开与关闭
打开 file 对象名= open(文件路径字符串,模式字符)
关闭 file对象名.close()
例子:
wr = open("D:\\test.txt",'w')
wr.write("hello world")
wr.close()
打开模式 文件类型 操作方式 文件不存在 是否覆盖
'r' 文本文件 只可读 报错 -----
'r+' 可读可写 报错 是
'w' 只可写 新建 是
'w+' 可读可写 新建 是
'a' 只可写 新建 追加
'a+' 可读可写 新建 追加
'rb' 二进制文件 只可读 报错 ------
'rb+' 可读可写 报错 是
'wb' 只可写 新建 是
'wb+' 可读可写 新建 是
'ab' 只可写 新建 追加
'ab+' 可读可写 新建 追加
注意:open后,文件就被python占用并被调入内存,其后所有的操作都发生在内存,同时,其他任何程序都不能操作该程序。
读写操作结束后,必须将文件从内存保存回外存,并释放python对文件的占用。
写文件
file 对象.write() 从插入点位置按照顺序原样写入,连续写入的字符串之间不会添加任何分隔符
file 对象.writelines() 以序列的形式接收多个字符串作为参数,一次性写入多个字符串,也是原样写入,不添加任何分隔符
例子:
读文件
file 对象.read() 读出所有内容并作为一个字符串返回
file 对象.readline() 读出当前行内容并作为字符串返回
file 对象.readlines() 以列表形式返回所有内容,每一行对应一个列表元素
例子:
三、CSV文件操作
CSV是带逗号分隔符(也可以是其他简单字符分割)的纯文本形式存储表格数据的文件。
特征:
(1) 纯文本,使用某个字符集,比如ascii、 gb2312、 unicode等;
(2) 由记录组成,一行对应一条记录,每行开头不留空格;
(3) 每条记录可以被逗号、分号、制表符等分割成多个字段;
(4) 每条记录都有同样的字段序列;
(5) 如果文件包含字段名,字段名写在文件第一行;
(6) 不包含特殊字符,文件中均为字符串。
例子:
读取reader对象
例子:import csv
写入writer对象
例子:
注意:
模块:是指一个.py文件,一般包括Python内置模块和来自第三方模块。
常见的内置模块math\cmath等,基础扩展模块:时间相关的datetime\time\calendar(日历)、随机序列randon模块、文件处理模块os、csv、PDF、图像处理模块 easygui、turtle等。
包:是指一系列模块文件所在的目录,且该目录下必须包含_init_.py文件。
库:是指相关功能模块的集合。
总结:
验证二:进入IDLE或者pycharm(新建.py),输入import jieba(库名)不报错即可。
安装语法:pip install 库名 -i 镜像地址
例子:以wordcloud安装为例。
(1)在idle中验证
(2)安装:pip install wordcloud -i http://mirrors.aliyun.com/pypi/simple/
(3)用上面的方法验证一下。
(2)点击右侧"+“号,在搜索框中输入scrapy(库名),显示版本等信息,勾选下方的复选框,并点击"Install package”。
此时,程序右下角会出现安装进度,左上角程序也会出现installing字样。
安装成功后,显示成功。
同时,在解释器下方也能找到安装的scrapy库信息。
如果要卸载,只要点击"-"减号即可。同样的操作。
当然还有离线安装,有兴趣的同学也可以网上搜索一下,尝试完成。
[练习]: 1.根据以上讲解,完成以上第三方库的安装并验证。
2.wordcloud库安装完成后,会默认安装numpy和matplotlib,请大家在pycharm中卸载numpy和matplotlib,然后重新在线安装一次,或者用pip的方法重新安装一次。
(2) 获取时间戳:
时间戳是格林威治时间1970年01月01日00时00分00秒起到现在的总秒数。
将日期转换为时间戳:timetuple(),将时间戳转换为日期:fromtimestamp()
(3) 时间间隔:timedelta()方法
(6) 让程序睡一会: time.sleep()
random模块
> https://www.cnblogs.com/yd1227/archive/2011/03/18/1988015.html
random.random() 生成一个[0,1)的随机浮点数
random.uniform(a,b) 生成指定范围内的随机浮点数
random.randint(a,b) 生成指定范围[a,b]内的整数
random.randrange(a,b,n) 可以在[a,b)范围内,按n递增的集合中随机选择
一个数
random.choice() 指定序列中随机选择一个元素
random.sample() 能指定每次随机元素的个数
random.shuffle() 可以将可变序列中所有元素随机排序
turtle模块
属性:
位置、方向、画笔(颜色、线条宽度等)
指令:
三、turtle画笔控制函数:
turtle.penup():表示抬起画笔,海龟在飞行;可以简写成turtle.pu()
turtle.pendown():表示画笔落下,海龟在爬行;可以简写成turtle.pd()
turttle.pensize(width):表示画笔的宽度,也可以使用turtle.width(width)
turtle.pencolor(color):color为颜色字符串或者 RGB值;
turtle.forward(d):向前行进距离;可以简写为turtle.fd(d),d为整数可以为负数;
turtle.circle(r,extent=NONE):根据半径r绘制extent角度的弧形,r默认在圆心左侧R距离的位置;extent:绘制角度默认360度是整圆;
turtle.seth(angle)
#seth()改变海龟行进方向;
#angle为据对度数;
#seth()只改变呢方向但是不行进;
画笔运动命令—前后移动、左右转动、作画速度等
画笔控制命令----抬起、放下、画笔宽度、画笔颜色、填充颜色等
例子:三角形绘制
尝试画一个五角星。
文本分析是指对文本的表示及其特征项的选取,是文本挖掘、信息检索的一个基本问题。
相关库:中文分词jieba库和词云绘制库wordcloud。
1. jieba库
jieba分词运用
jieba.cut(text)
精确模式,返回一个可迭代的数据类型
jieba.cut(text,True)
全模式,输出文本text中所有可能单词
jieba.cut_for_search(text)
搜索引擎模式,适合搜索引擎建立索引的分词结果
jieba.lcut(text)
精确模式,返回一个列表类型
jieba.lcut(text,True)
全模式,返回一个列表类型
jieba.lcut_for_search(text)
索引擎模式,返回一个列表类型
jieba.add_word(w)
向分词词典中增加新词w
例子1:分词示范
练习:s = '李明硕士毕业于中国科学院计算所',用lcut三种模式查看分词结果。
例子2:自定义分词示范
也可以自己创建一个文本文件,加载新词。
词性标注 :
词性(part-of-speech)是词汇基础的语法范畴,也称词类。
每个词都有词性编码,flag属性。
例如:名词n, 人名nr, 地名ns, 动词v,形容词a,副词d,介词p,代词r
例子:找出歌词中的所有地名
Text = '泰国 新加坡 印度尼西亚咖喱 肉骨茶 印尼九层塔做SPA 放烟花 蒸桑拿Coco Pineapple Mango Mango(椰子,菠萝,芒果)沙巴 芭堤雅 阳光热辣辣香瓜 啤酒花 风景美如画夜市下 海鲜架 泳池趴嘟嘟 嘟嘟 干嘛干嘛呀咖喱 咖喱 轻轻一加咖喱 咖喱辣咖喱 咖喱 香蕉木瓜榴莲臭臭配香茶咖喱 咖喱 摩托皮卡咖喱 咖喱呀咖喱 咖喱 夜市酒吧热情奔放火辣辣咖喱咖喱' (咖喱咖喱歌词)
关键词提取
关键词抽取就是从文本里面把与这篇文档意义最相关的一些词抽取出来,
关键词最能反映出文本主体或者意思的词语。现阶段关键词在文本聚类、
分类、自动摘要等领域有着重要的作用。
例题:利用jieba分词系统中的TF-IDF接口抽取关键词示例。
原始文本:
很多人不知道的是,金庸开始武侠小说的创作,是一次很偶然的机会。1955年,《大公报》下一个晚报有个武侠小说写得很成功的年轻人,和金庸是同事,他名叫梁羽生。那年梁羽生的武侠小说即将完结,而他的创作又到了疲惫期,于是,报纸总编辑邀请金庸将武侠小说继续写下去。虽然此前从未写过小说,但凭借他对武侠小说的了解与喜爱,金庸还是答应接替梁羽生的任务。他把自己名字中的镛字拆开,做了一个笔名,《书剑恩仇录》正式他的第一部武侠作品,作品一炮而红。此书成功之后,金庸又在短短几年内创作了《碧血剑》《雪山飞狐》和《射雕英雄传》等作品,一时间风靡全港,十余年间,他写下15部洋洋大作。
运行结果如下所示。
2. 词云绘制wordcloud库
Wordcloud是python非常优秀的词云展示第三方库。词云以词语为基本单位,是对文本种出现频率较高的"关键词"予以视觉化的展示。它过滤掉了大量的低频低质的文本信息,使得用户只要一眼扫过文本就可以领略文本的主旨。
第一步先安装该第三方库。相关函数及各个参数
```python
font_path 显示字体路径
width\height 输出画布的宽度和高度,默认像素
background_color 背景色
fit_words(frequencies) 根据词频生成词云,其中词频为字典类型
generate(text) 根据文本生成词云
generate_from_frequencies(frequencies[,..]) 根据词频生成词云
generate_from_text(text) 根据文本生成词云
例子:
```
1. 对象的基本概念
Python中的所有事物都是以对象形式存在, 从简单的数值类型,到复杂的代码模块,都是对象。
对象(object) 既表示客观世界问题空间中的某个具体事物,又表示软件系统解空间中的基本元素。
对象 =属性 +方法
对象以id作为标识,既包含数据(属性),也包含代码(方法),是某一类具体事物的特殊实例。
2. 创建对象
对象是类的实例,是程序的基本单元。
要创建一个新的对象,首先必须定义一个类, 用以指明该类型的对象所包含的内容(属性和方法)
同一类(class)的对象具有相同的属性和方法,但属性值和id不同。
比如'a' 、'b'都是字符串对象,属性相同,方法都一样,属性值和id不同。
3. 对象的属性和方法的引用
(1) 对象的名称:赋值语句给予对象以名称,对象可以有多个名称(变量引用),但只有一个id。
例:s1 = 'a'
s2 = 'a' id(a)一样
(2)对象实现了属性和方法的封装,是一种数据抽象机制,提高了软件的重用性、灵活性、扩展性。
(3)引用形式:
<对象名>.<属性名>
例: "abc".upper()
(1+2j).real
(1+2j).imag
4. 面向对象编程
面向对象编程(OOP)是一种程序设计范型,同时也是一种程序开发方法 程序中包含各种独立而又能互相调用的对象。每个对象都能接受、处理数据并将数据传递给其他对象。
传统程序设计,可将程序看作一系列函数或指令的集合。
例题1:定义一个类(力)
例子:
例子:在上述力的类主体中增加以下代码,实现算数运算符的构造函数。
运行结果如下:
其他特殊方法,比如
str(self)是自动转换为字符串,
len(self)返回元素个数,
repr(self)返回一个用来表示对象的字符串等,都能尝试以下。
注意:1.__repr__是用于把一个对象用"官方"的字符串表示出来,终端友好,返回包括一个尖括号括起来的字符串,包含对象类型名称及附加的信息。
2. __str__返回一个非正式的字符串形式(用户友好),如果对象没有提供__str__方法,会使用__repr__来提供返回值。
列表排序:列表方法sort()
对原列表进行排序,改变原列表内容 如果列表中的元素都是数字,默认按升序排序 通过添加参数reverse = True可改为降序排列 如果元素都是字符串,则会按照字母表顺序排列。
内置排序函数:通用函数sorted()
类似sort(),但返回的是排好序的列表副本,原列表内容不变。只有当列表中的所有元素都是同一种类型时, sort()和sorted()才会正常工作。
特殊方法__lt__
定义特殊方法 def lt(self, y)
返回True视为比y"小",排在前;返回False视为比y"大",排在后。只要类定义中定义了特殊方法__lt__,任何自定义类都可以使用x
可扩展的"大小"比较及排序
例子:类Student(姓名name,成绩grade),实现按照成绩由高到低排序。
传统方法演示:
(1)第一步类的定义
(2)第二步类的调用
(3)第三步运行结果
接下来,扩展方法演示(即根据__lt__定义排序,直接检验s[i]
大家还可以尝试重新定义__lt__,让它比较姓名,并运行下效果。
(2) 第二步定义子类
(3) 第三步调用
(4) 运行
子类与父类
如果两个类具有"一般-特殊"的逻辑关系, 那么特殊类就可以作为一般类的"子类",从"父类"继承属性和方法,具体语法如下:
class 子类名(<父类名>):
def <重定义方法>(self,…):
覆盖(Override) :指子类对象可以调用父类方法,除非这个方法在子类中重新定义了。
如果子类同名方法覆盖了父类的方法,仍然还可以调用父类的方法。
子类还可以添加父类中没有的方法和属性。
例如:在子类gasCar中增加初始化方法
关于self
在类定义中,所有方法的首个参数一般都是self。self的作用是在类内部,实例化过程中传入的所有数据都赋给这个变量。
self实际上代表对象实例。
维度:一组数据的组织形式,表示数据之间特定的含义。
一维数据:由对等关系的有序或无序数据构成,采用线性方式组织。
3.1412、3.1402、3.1339、3.1388
对应列表、数组和集合等概念。
注意:Python语言的基本语法中没有数组这个类型,这与C等不一样。
列表:数据类型可以不同
3.1413,‘Pi’, ‘3.1416’, [3.1401,3.1449]
数组:数据类型要相同
3.1412、3.1402、3.1339、3.1388
二维数据:由多个一维数据构成,是一维数据的组合形式。
多维数据:是由一维或者二位数据在新的维度上扩展而成。
高维数据:仅仅利用最基本的二元关系展示数据之间的复杂结构。
例如:键值对
数据维度是数据的组织形式。不同数据维度的Python表示如下:
一维数组:列表和集合类型
二维数组:列表类型
三维数组:列表类型
高维数组:字典或数据表示格式(JSON/XML/YAML)
NumPy是一个开源的Python科学计算基础库。
特征:
Numpy的引用
import numpy as np
引入模块的别名,建议使用以上约定的别名。
疑问:Python中已有了列表类型,为什么还要引入数组对象?
例:计算A2+B2,其中A、B都是一维数组。
分析发现:
(1) 数组对象可以去掉元素间运算所需的循环,使一维向量更像单个数据。
(2)数组对象采用相同的数据类型,设置专门的数组对象,可以提升这类应用的运算速度。
Numpy的数组对象:ndarray (ndarray是存储单一数据类型的多维数组)
Ndarray数组对象的属性
ndarry数组的创建:
第一种:从Python的列表、元组等类型创建;
第二种:使用Numy函数创建ndarray数组。常用函数如下所示:
例子:查看运行结果
ndarray数组的变换:维度与元素类型变换。
例子:注意区别
B=np.resize(a,shape)
数组的索引与切片
(1)一维数组(编号从0开始,从左递增,或-1从右递减):
[a:b:c] a:起始编号 b:终止编号(不含) c:步长
(2)多维数组:
[a, b, c] 每个维度一个索引值,用逗号分开。
例子:
(1) 一维数组
(2) 多维数组
练习:
变换数组的形态
改变数组形状 arr.reshape()
展平数组 arr.ravel()
arr.flatten() 横向展平
arr.flatten(‘F’) 纵向展平
组合数组 np.hstack((arr1,arr2)) 横向组合
np.vstack((arr1,arr2)) 纵向组合
np.concatenate((arr1,arr2),axis = 1) 横向组合
np.concatenate((arr1,arr2),axis = 0) 纵向组合
切割数组 np.hsplit(arr,2) 横向切割
np.vsplit(arr,2) 纵向切割
np.split(arr,2,axis = 1) 横向切割
np.split(arr,2,axis = 0) 纵向切割
例子:
三、Numpy矩阵运算
在numpy中,数组和矩阵有非常重要的区别。
矩阵是ndarray的子类,是继承自数组对象的二维数组对象。
四、Numpy进行统计分析
例子:
(1)二进制文件存储与读取
(2)txt文本存储与读取
第八章 matplotlib数据可视化
一、基础画图流程
Matplotlib首次发表于2007年,参考了matlab,以mat开头,中间的plot表示绘图,
结尾的lib表示一个集合。应用最广的是matplotlib.pyplot模块。
Pyplot的基础语法:
创建画布与创建子图
第一部分主要作用是构建出一张空白的画布,并可以选择是否将整个画布划分为多个部分,方便在同一幅图上绘制多个图形的情况。最简单的绘图可以省略第一部分,而后直接在默认的画布上进行图形绘制。
添加画布内容
第二部分是绘图的主体部分。其中添加标题,坐标轴名称,绘制图形等步骤是并列的,没有先后顺序,可以先绘制图形,也可以先添加各类标签。但是添加图例一定要在绘制图形之后。
保存与展示图形
示例1:一幅图
示例2:多幅图
二、设置rc动态参数
Pyplot可以使用rc配置文件来自定义图新的各种默认属性,被称为rc配置或rc参数。比如可以修改窗口大小、每英寸点数、线条宽度、颜色和央视、坐标轴、文本、字体等。
常用的rc参数
常用线条类型
常用线条标记解释
注意事项:由于默认的pyplot字体并不支持中文字符的显示,因此需要通过设置font.sans-serif参数改变绘图时的字体,使得图形可以正常显示中文。同时,由于更改字体后,会导致坐标轴中的部分字符无法显示,因此需要同时更改axes.unicode_minus参数。
示例:
三、 分析特征之间的关系
散点图(scatter diagram)又称为散点分布图,是以一个特征为横坐标,另一个特征为纵坐标,利用坐标点(散点)的分布形态反映特征间的统计关系的一种图形。
matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, alpha=None, **kwargs)
折线图(line chart)是一种将数据点按照顺序连接起来的图形。可以看作是将散点图,按照x轴坐标顺序连接起来的图形。
matplotlib.pyplot.plot(*args, **kwargs)
案例:绘制2000-2017各产业与行业的国民生产总值散点图。国民生产总值数据总共有三大产业的国民生产总值,以及农业、工业、建筑、批发、交通、餐饮、金融、房地产和其他行业各个季度的增加值。通过散点图分析三大行业的国民生产总值可以发现我国产业结构。通过比较各行业间季度的增加值则可以发现国民经济的主要贡献行业。
绘制2000-2017年各个季度国民生产总值散点图
绘制2000-2017年各个产业各季度国民生产总值散点图
绘制2000-2017年各个季度国民生产总值折线图
绘制折线图时还可以通过颜色、点的形状和类型一次性设置,比如’bs-’:代表绿色正方形实线、‘ro-.’:红色、圆圈、点线。
四、 分析特征内部关系:直方图、饼图、箱线图
直方图
直方图(Histogram)又称质量分布图,是统计报告图的一种,由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据所属类别,纵轴表示数量或者占比。
matplotlib.pyplot.bar(left,height,width = 0.8,bottom = None,hold = None,data = None,** kwargs
饼图
饼图(Pie Graph)是将各项的大小与各项总和的比例显示在一张"饼"中,以"饼"的大小来确定每一项的占比。
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, … )
箱线图
箱线图(boxplot)也称箱须图,其绘制需使用常用的统计量,能提供有关数据位置和分散情况的关键信息,尤其在比较不同特征时,更可表现其分散程度差异。
matplotlib.pyplot.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None,meanline=None, labels=None, … )
示例: 绘制国民生产总值构成分布直方图、饼图、箱线图
「总结」绘制图形的一般步骤:
绘制函数总结
散点图 plt.scatter(x, y, s=None, c=None, marker=None, alpha=None, **kwargs)
折线图 plt.plot(x, y,…)
直方图 plt.bar(left,height,width…)
饼图 plt.pie (x, explode=None, labels=None, colors=None… )
箱线图 plt.boxplot(x, positions=None, widths=None, labels=None, … )
五、Numpy和Matplotlib的综合使用
案例:某班级由30名学生,每名学生都由三门课程,学生的学号和各门功课成绩如图所示(学号、高数、大学英语、Python程序设计)。文件"stu_score.csv",请计算每个学生的三门课程的总分、此班级每门课程的平均分和最高分、最低分,并绘制相应的图形来统计三门课程的成绩分布。
第九章 pandas库的应用
一、pandas库简介
安装
先安装pandas库。建议在cmd中用pip工具安装(即实现python3.6中安装),这样pycharm中选用python3.6,会自动加载该库。
安装完成后,可在idle和pycharm中验证下:import pandas
pandas库的简介
Pandas库是以numpy库为基础构建的,通常用于处理表格型(关系型)的数据集或与时间序列相关的数据集。而numpy库的优势是矩阵运算,主要用于数值计算。
Pandas库有以下一些优点:
(1) pandas 提供了快速高效的 DataFrame 对象,可用于集成索引的数据集操作。
(2) 提供了对各种格式数据的读取和写入工具,包括 CSV 数据、文本文件、Excel、 SQL 数据库和 HDFS 文件格式等。
(3) 提供智能的数据对齐功能和缺失数据处理方式,可以方便地将混乱的数据处理成有序的形式。
(4) 可以很灵活地进行数据集的维度变换和旋转。
(5) 基于 DataFrame 对象的标签,可以对数据集进行灵活的切片、花式索引,或将大数据集分拆为多个小子集。
(6) 当需要修改数据尺度时,允许对数据对象中的数据列进行添加和删除操作。
(7) pandas 提供了强大的分组引擎,可以对分组数据集进行拆分、应用、组合等操作,也可以方便地对数据集进行汇总统计和转换。
(8) pandas提供了对多个数据集进行高效合并和连接的方法。
(9) 分层轴索引提供了在地位数据结构中处理高位数据的直观方式。
(10) 提供了方便的实践序列操作功能,如在某一日期区间内的时间生成、频率转换、时间轴平移等,在做时间域偏移变更时能保证数据的完整性。
Pandas库有两种最重要的数据结构:Series对象和DataFrame对象。
二、pandas的Series对象
Series对象类似一维数组,由数据及对应的索引组成。
Series对象
索引 数据
Index 1 Value 1
Index 2 Value 2
…… ……
Index n Value n
创建与获取
(1)数组方式创建
获取时可以通过.values和.index分别获取数据和索引部分。
(2)使用index参数为对象指定字符串类型的索引
(3)通过字典创建,但注意区别:字典中是无序的,而Series对象是有序的。
常见运算(如标量乘法、数据过滤、应用函数等)
索引与访问
由于Series有两种索引,一种是整数索引,一种是字典中的标签或字符串索引。那么进行Series对象索引时就有两种方式,分别是整数索引和标签索引。两者的区别在于:整数索引同之前讲的数组索引一致,区间是左闭右开,而标签索引是左闭右闭!
(1) 整数索引 (2)标签索引
修改数据
修改数据类似字典,如果对当前对象中不存在的索引赋值,则会把该索引及值作为一个新数据添加进Series对象中。
重要功能:算术运算中的数据对齐。
简单讲就是多个Series对象中的数据依据索引进行匹配后再做算术运算。
以上例子可以看出,相加后得到的是数据的并集,相同索引的数据项进行相加,而没有匹配的两项,则出现了NaN,表示数据缺失。
针对数据缺失,pandas还提供了isnull()和notnull()函数。
三、pandas中的DataFrame对象
DataFrame对象是一个表格型的数结构,由行和列组成。其中列是有序的,列与列之间的数据类型可以互不相同。DataFrame的每一行存在一个行索引(index),每一列同样有一个列索引(columns)。
实际上每一列都是一个Series对象,也可以将DataFrame看成是"共享行索引的多个Series的集合"。结构如下所示。
Series 1( columns) Series 2 Series 3
索引0
索引1
……
索引n
还可以通过以下属性查看基本信息。比如形状、行索引、列索引、数据信息,及摘要信息等。
(2) 对象索引
一般DataFrame会自动创建数字索引0,1,2….像上面显示的。如果希望自定义索引,则在创建对象时,就需要增加索引参数。
注意:索引是不允许修改的,如果直接对索引赋值会报错。但pandas允许用户使用set_index()方法将某列设置为新索引,也可以使用reindex()方法改变数据行的顺序,生成一个匹配新索引的新对象。
(3) 数据选择(数字索引+字符串索引两种)
a) 选择行(index:数字、标签)
df[0:1] #获取第一行
df[1:3] #获取第1,2行
df[‘北京’:‘广州’] #获取第1-3行
df.head() #获取默认前5行
df.head(3) #获取前三行
df.tail(1) #获取最后一行
b) 选择列(columns)
df[‘GDP’] #获取gdp列
c) 选择区域
使用格式 功能
loc[i] 选取行索引为i的行
loc[i1:i2] 选取行索引为[i1,i2]的行
loc[i1:i2,c1:c2] 选取行索引为[i1,i2]、列索引[c1,c2]的矩形区域
at[i,c] 选取行索引为i,列索引为c的单个元素
iloc[i] 选取第i行
iloc[i1:i2] 选取第[i1,i2)行
iloc[i1:i2,c1:c2] 选取 [i1,i2)、 [c1,c2)的矩形区域
iat[i,c] 选取第i行、第c列的单个元素
Eg:
df.loc[‘北京’]
df.loc[‘北京’:‘广州’]
df.loc[‘北京’:‘广州’,‘GDP’:‘人口’]
df.iloc[1]
df.iloc[1:4]
df.iloc[1:4,0:]
df.at[‘深圳’,‘人口’]
df.iat[2,1]
(4) 文件的导入和导出
df = pd.read_csv(‘C:/Users/dzxxg/Desktop/stu_score.csv’, header = 0)
#header=0表示第一行作为标题行,如果没有标题行,则取None
df = pd.read_excel(‘data.xlsx’)
df.to_excel(‘result.xlsx’,sheet_name=‘sheet’)
df.to_csv(‘result2.csv’)
df.to_html(‘result3.html’)
2. DataFrame对象的数据操作
(1) 筛选:指定筛选或者用loc设置筛选
(2) 排序
方法一:依据索引列排序,使用df.sort_index();
方法二:依据指定列的数值进行排序,使用sort_values(by = 列名)
(3) 分组:拆分—应用----合并
举例子:以下是三个经济大省前两名城市的GDP数据进行依次分组操作,统计其平均值。
自行运行结果,并查看。
(4) 合并
a) append()方法:可以将其他数据对象沿着索引方向(列对齐)追加到当前对象的末尾,并返回一个新对象。
Eg:
Result = df1.append(df2) #合并两个对象
Result = df1.append([df2,df3]) #合并三个对象
b) merge()方法:如果存在相同含义的列,那就意味着表之间存在关联关系,比如一对一关联、一对多关联、多对多关联。合并的时候,将有关联依据的那些列称之为逐渐key.
方法:result = pd.merge(left, right, on = ‘key1’)
图 两表基于主键key合并
但合并时有可能有多个key,如下。这种情况会出现不匹配的行会丢失。
result = pd.merge(left, right, on = [‘key1’, ‘key2’])
图 基于key1,key2的两表内连接
因此可用merge()函数的how参数来指定连接方式。
result = pd.merge(left, right, how = ‘outer’, on = [‘key1’, ‘key2’])
图 基于key1,key2的两表外连接
result = pd.merge(left, right, how = ‘left’, on = [‘key1’, ‘key2’])
图 基于key1,key2的两表左连接
总结,当出现多个key,可指定连接方式
参数值 连接方式 功能描述
inner 内连接(默认) 根据交集进行合并
outer 外连接 并集
left 左连接 只根据左数据表的主键进行合并
right 右连接 只根据右数据表的主键进行合并
(5) 画图
第十章 网络爬虫
一、 概念
一次访问步骤:
第一步:浏览器输入网址,即发起一个网络请求,称之为Request。
第二步:互联网上的设备会分析这个地址,找到对应的web服务器。
第三步:如果网址真实存在并允许访问,则服务器会将所有数据返回给用户,称之为响应,response。
第四步:用户收到这些数据,浏览器会将数据按照预先设置好的格式整合起来展现给用户。
过程类似点点外卖的过程,其中餐馆就是Web服务器,外卖平台就是互联网。
其中,输入的网址称为"统一资源定位符"(URL)。
组成结构: 网络协议://服务器主机:端口/文件路径?发送数据
http://lib.njtech.edu.cn/list.php?fid=9
http代表超文本传输协议,最常用;
服务器主机是在相关机构正式注册过的,端口默认都是80,可以不用输入
文件路径代表了用户请求访问的文件名及该文件在服务器上的存储路径
用户发送到网页文件的数据,可能是一个用户名,也可能是一个查询关键字等。
<>围起来的就是标签,一般成对出现。
从开始标签到结束标签之间所有的脚本称之为一个元素,比如"这里是第一段"就是元素的内容。
标签拥有属性,属性描述来标签的各种信息和特征。属性总是出现在开始标签中,以键值对的形式展开,比如name=‘p1’。
将上面的例子修改如下:
Html文档的标签结构
上述案例中一共用了8个标签,其中6个是嵌套在body内的,这种嵌套关系如果用图表形式展现出来,就是一个树状结构。下面一个案例描述树状结构。
查看html文档源码
下面以豆瓣上《射雕英雄传》的书评网页为例,介绍如何查看一个网页源码。
https://book.douban.com/subject/1044547/
方法一:谷歌浏览器右键"查看网页源码"即可。
方法二:针对大型网页,可选中感兴趣的内容,右键,选择"检查",可以很快定位到目标数据所在的那部分标签代码。
二、 request库的使用(常用的网页请求库包括urllib\urllib2\requests\selenium等)
首先通过pip install request安装第三方库。
Eg:
因为用浏览器来访问,每一次都会发送一些请求数据给服务器,其中一部分称之为请求头部(headers),包含了请求方式、主机名、浏览器类型及版本、cookies等,最常用的是其中的User-Agent,包含了用户的浏览器类型、版本以及操作系统等信息。
(1) 怎么查看一次浏览器访问请求,产生的user-agent信息?
打开百度首页----浏览器右侧三个小点,选中"更多工具"—“开发者工具”----选中"network"标签----选择下方"all"。
此时页面没有信息,接着刷新以下百度首页,能看到all下方框中出现了数据信息。如下图。
打开"name"—勾选第一项www.baidu.com-----右侧选择"hearders"—找到"user-agents"。
(2)以上我们看到浏览器每次访问都会产生这个请求,如果要在程序中模拟浏览器请求,可以在上述get()方法前,伪造一个header头部信息。
该user-agent以键值对的形式,将上图中找到的user-agent对应的values值拷贝下来即可。
运行的结果如下:
三、 Response对象
通过get是一次request过程,requests库会把用户请求的数据封装为一个request对象并发送到服务器,服务器返回一个响应,该响应的所有信息会封装在一个Response对象中给用户,例如上述案例中的r。
Response对象常见的属性如下,对照上一代码运行的结果:
属性名称 属性说明
Status_code 服务器响应状态码。200代码请求成功,4XX 5XX代表出错
Encoding 服务器响应内容的编码方式
Text 以字符串格式显示响应内容
content 以字节(二进制)格式显示响应内容
headers 以字典形式存储的服务器响应头部信息
其中,text和content都表示响应内容,具体是网页的全部内容。区别:text是字符串形式显示,content是二进制形式展示。如果请求的是普通网页,则通常是text,,如果请求的是图片、视频等,则需要content。
(1) raise_for_status()方法
当连续采集多个网页时容易出错,为避免一个或几个意外问题而导致程序终止,response对象提供了raise_for_status()方法。这个方法主要用于当请求访问某个网页出现异常时,允许程序及时捕捉到该异常并且跳过它,转而执行下一个网页的采集。
案例:尝试采集豆瓣网上关于三联书店出版的《天龙八部》的短评。将前10页的内容爬取出来。
分析:url: https://book.douban.com/subject/1255625/comments
https://book.douban.com/subject/1255625/comments/?start=20&limit=20&status=P&sort=new_score
https://book.douban.com/subject/1255625/comments/?start=40&limit=20&status=P&sort=new_score
发现每一页的url基本一致,区别就在于start后面的参数。采集前10页,可以通过range函数实现,采集到后写入文件保存。为了防止异常,用try…except实现。
结果如下:
四、 BeautifulSoup库的使用
前提:安装第三方BeautifulSoup库:pip install BeautifulSoup4
四种对象
Tag 对应html文档中的各种标签,有两个常用属性:name\attrs
Beautifulsoup 文档的整体,可以看作html文档树的根或者一个顶层节点,文档中所有的标签及内容都是它的后代节点
NavigableString 可以便利的字符串对象,用于
Comment
五、 综合案例(bs+jieba+wordcloud)
以之前豆瓣获取的例子进一步爬取前10页所有的评论,生成一个词云。