一、python基础
1、注释
1 2 3 4 5 6 7 8 9
|
""" 多行注释 """
''' 多行注释 '''
|
2、变量以及数据类型
在python中,不需要定义变量的类型,系统会自动根据变量的值来确定变量的类型
【List(列表)———Java中的数组】【Tuple(元组)———】
2.1、变量定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| a = 123 b = 12.8
c = False d = True
e = "今天天气真好" f = '今天天气不好'
g = [1, "字符串2", 3, '字符串4']
h = (1, "字符串2", 3, '字符串4')
i = {'age': 18, 'name': '张三'}
|
2.2、查看变量的数据类型
使用type
来查看变量的数据类型
3、类型转换
函数 |
说明 |
int(x) |
将x转换为一个整数 |
float(x) |
将x转换为一个浮点数 |
str(x) |
将对象 x 转换为字符串 |
bool(x) |
将对象x转换成为布尔值 |
1 2 3 4 5 6 7
| print(bool('')) print(bool("")) print(bool(0)) print(bool({})) print(bool([])) print(bool(()))
|
4、运算符
4.1、算数运算符
下面以a=10 ,b=20为例进行计算
运算符 |
描述 |
实例 |
+ |
加 |
两个对象相加 a + b 输出结果 30 |
- |
减 |
得到负数或是一个数减去另一个数 a - b 输出结果 -10 |
* |
乘 |
两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 |
/ |
除 |
b / a 输出结果 2 |
// |
取整数 |
返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
% |
取余 |
返回除法的余数 b % a 输出结果 0 |
** |
指数 |
a**b 为10的20次方 |
() |
小括号 |
提高运算优先级,比如: (1+2) * 3 |
==注意:混合运算时,优先级顺序为: * 高于 / % // 高于 + - ,为了避免歧义,建议使用 () 来处理运 算符优先级。 并且,不同类型的数字在进行混合运算时,整数将会转换成浮点数进行运算。在字符串中使用+
是字符串拼接==
4.2、赋值运算符
运算符 |
描述 |
实例 |
= |
赋值运算符 |
把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3,结果num的值为7 |
1 2 3 4
| a = 10 b = c = 2
d, e, f = 1, 2, 3
|
4.3、复合赋值运算符
运算符 |
描述 |
实例 |
+= |
加法赋值运算符 |
c += a 等效于 c = c + a |
-= |
减法赋值运算符 |
c -= a 等效于 c = c - a |
*= |
乘法赋值运算符 |
c = a 等效于 c = c a |
/= |
除法赋值运算符 |
c /= a 等效于 c = c / a |
//= |
取整除赋值运算符 |
c //= a 等效于 c = c // a |
%= |
取模赋值运算符 |
c %= a 等效于 c = c % a |
**= |
幂赋值运算符 |
c = a 等效于 c = c ** a |
4.4、比较运算符
运算符 |
描述 |
实例 |
== |
等于:比较对象是否相等 |
(a == b) 返回 False |
!= |
不等于:比较两个对象是否不相等 |
(a != b) 返回 true |
> |
大于:返回x是否大于y |
(a > b) 返回 False |
>= |
大于等于:返回x是否大于等于y |
(a >= b) 返回 False |
< |
小于:返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特 殊的变量True和False等价 |
(a < b) 返回 true |
<= |
小于等于:返回x是否小于等于y |
(a <= b) 返回 true |
4.5、逻辑运算符
运算符 |
逻辑表达式 |
描述 |
实例 |
and |
x and y |
只要有一个运算数是False,结果就是False; 只有所有的运算数都为True时,结果才是True 做取值运算时,取第一个为False的值,如果所有的值 都为True,取最后一个值 |
True and True and False—> 结果为False True and True and True—> 结果为True |
or |
x or y |
只要有一个运算数是True,结果就是True; 只有所有的运算数都为False时,结果才是False 做取值运算时,取第一个为True的值,如果所有的值都 为False,取最后一个值 |
False or False or True—>结 果为True False or False or False—>结 果为False |
not |
not x |
布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 |
not True —> False |
性能优化
1 2 3 4 5 6 7
| a = 11
a > 10 and print('会输出')
a == 11 or print('不会输出')
|
5、输入和输出
5.1、输出
普通输出
1 2 3 4
| print('aaaa')
a = "这是拼接后的字符串" print("字符串1" + a)
|
格式化输出
1 2 3 4 5
| age = 10 print("我今年%d岁" % age)
name = "红浪漫晶哥" print("我的姓名是%s, 年龄是%d" % (name, age))
|
5.2、输入
1 2
| password = input('请输入密码:') print('输入的密码为:%s' % password)
|
6、流程控制语句
6.1、if
格式
示例
1 2 3
| a = 10 if a > 5: print('条件成立,输出了')
|
6.2、if-else
格式
1 2 3 4
| if 要判断的条件: 条件成立时,执行的操作 else: 条件不成立时,候执行的操作
|
示例
1 2 3 4 5
| a = 10 if a > 0: print("条件成立") else: print("条件不成立")
|
6.3、elif
格式
1 2 3 4 5 6 7
| a = 10 if 判断的条件: 条件成立时,执行的操作 elif 判断的条件: 条件成立时,执行的操作 else: 条件成立时,执行的操作
|
示例
1 2 3 4 5 6 7
| a = 10 if a > 0: print("a>0") elif a < -10: print('a<-10') else: print('其他条件')
|
6.4、for
格式
1 2
| for 临时变量 in 列表或者字符串等可迭代对象: 循环满足条件时执行的代码
|
示例
1 2 3 4 5 6 7
| for s in "hello": print(s)
items = [1, 2, 3, 4] for item in items: print(item)
|
6.5、range
range可以生成一个列表用于循环,它可以传递三个参数,分别表示 起始、结束和步长
示例
1 2 3
| for item in range(1, 10, 3): print(item)
|
7、数据类型高级
7.1、字符串高级
- len:获取字符串的长度
- find:查找指定内容在字符串中是否存在,不存在返回-1,存在返回第一次出现的位置
- startswith endswith:判断以谁开头/结尾,返回bool值
- count:返回指定内容在字符串中出现的次数
- replace:替换内容,两个参数,第一个,替换前的值,第二个,替换后的值
- split:切割字符串,会将切割后的结果返回为列表
- upper lower:upper(小写全部变为大写,大写不变),lower(大写变为小写,小写不变)
- strip:去除字符串的前后空格,中间的空格不会去除
- join:字符串拼接,和正常的拼接不一样 ,测试一下就知道了
7.2、列表高级
7.2.1、列表添加
- append 在末尾添加元素 ,会修改原来的数组
- insert 在指定位置插入元素 ,会修改原来的数组
- extend 合并两个列表 ,会修改原来的数组
示例
1 2 3 4 5 6 7 8 9 10
| a = [1, 2, 3] a.append(4) print(a)
a.insert(11, 11) print(a)
b = [22, 33] a.extend(b) print(a)
|
7.2.2、列表修改
找到指定元素的下标重新赋值
示例
1 2 3
| a = [1, 2, 3] a[1] = 231313 print(a)
|
7.2.3、列表查询
- in(存在),如果存在那么结果为true,否则为false
- not in(不存在),如果不存在那么结果为true,否则false
格式
1
| print(判断的值 in / not in 列表)
|
示例
1 2 3
| a = [1, 2, 3] print(1 in a) print(11 in a)
|
7.2.4、列表删除
- del:根据下标进行删除
- pop:删除最后一个元素
- remove:根据元素的值进行删除
1 2 3 4 5 6 7 8 9 10 11
| a = [1, 2, 3, 4] del a[1] print(a)
a = [1, 2, 3, 4] a.pop() print(a)
a = [1, 2, 3, 4] a.remove(1) print(a)
|
7.3、元组高级
==Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。==
==当元组中只有一个元素的时候,必须在最后一个元素后面添加一个,==
7.3.1、元组查询
1 2
| a = (1, 2, 3, 4) print(a[1])
|
7.4、切片
切片就是截取,截取部分字符串,获取元组或列表中的部分数据,字符串,列表,元组都支持切片
格式
1 2
| 切片的语法:[起始:结束:步长],也可以简化使用 [起始:结束] 注意:选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔
|
示例
1 2 3 4 5 6 7
| s = 'Hello World!' print(s) print(s[4]) print(s[3:7]) print(s[5:]) print(s[:5]) print(s[1:5:2])
|
7.5、字典高级
7.5.1、字典查询
除了使用key查找数据,还可以使用get来获取数据
1 2 3 4 5 6 7
| person = {'name': '韩信', 'age': 18, 'gender': '男'}
print(person.get('name')) print(person.get('error'))
print(person['gender']) print(person['error'])
|
7.5.2、字典修改
1 2 3
| person = {'name': '韩信', 'age': 18, 'gender': '男'} person['name'] = '法外狂徒张三' print(person.get('name'))
|
7.5.3、字典添加
1 2 3
| person = {'name': '韩信', 'age': 18} person['gender'] = '男' print(person.get('gender'))
|
7.5.4、字典删除
- del :删除指定的元素 / 删除整个字典
- clear():清空整个字典
del和clear删除字典的区别为:del删除整个字典,如果删除之后还调用,会报未定义错误。clear则是将字典中的元素全部删除,但是字典还是存在的
1 2 3 4 5 6 7 8 9 10
| person = {'name': '韩信', 'age': 18}
del person['age'] print(person)
person.clear() print(person)
del person print(person)
|
7.5.5、字典遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| person = {'name': '韩信', 'age': 18}
""" 遍历 key 输出: name age """ for item in person.keys(): print(item)
""" 遍历 value 输出: 韩信 18 """ for item in person.values(): print(item)
""" 遍历键值对:(key,value) 输出: ('name', '韩信') ('age', 18) """ for item in person.items(): print(item)
|
8、函数
8.1、函数定义
格式
示例
1 2 3
| def personInfo(): print('name:' + '法外狂徒张三') print('age:' + '18')
|
8.2、函数调用
1 2 3 4 5 6
| def personInfo(): print('name:' + '法外狂徒张三') print('age:' + '18')
personInfo()
|
8.3、函数参数
函数的参数可以给默认值,当没有值传入的时候,会自动使用默认值,,如果没有默认值,则在调用的时候必须传值,也可以在调用函数的时候给指定的参数传值
固定参数
1 2 3 4 5 6 7 8 9 10 11
| def personInfo(gender, name='李白', age=20): print('gender:%s' % gender) print('name:%s' % name) print('age:%d' % age)
personInfo('男', '韩信')
personInfo(gender='女', name='杨玉环')
|
可变参数
python中会将最后没有变量接收的参数会使用元组统一接收
1 2 3 4 5 6 7
| def personInfo(name, *aaa): print(name) print(aaa) print(type(aaa))
personInfo('韩信', 1, 2, 3, 45, 5)
|
8.4、函数返回值
1 2 3 4 5
| def personInfo(age): return age + 1
print(personInfo(1))
|
8.5、局部变量
1 2 3 4 5 6
| def personInfo(age): b = 2 return age + b
print(personInfo(1))
|
8.6、全局变量
1 2 3 4 5 6 7 8 9
| a = 1
def personInfo(age): b = 2 return age + b + a
print(personInfo(1))
|
10、文件
10.1、文件的打开与关闭
10.1.1、打开文件/创建文件
格式
1 2 3 4 5 6 7
| open(文件路径,模式) ''' 模式: w:可写 r:可读 '''
|
示例
1 2
| open(file='test1.txt', mode='r', encoding='utf-8')
|
文件路径
- 绝对路径:指的是绝对位置,完整地描述了目标的所在地,所有目录层级关系是一目了然的。 、
- 例如:
E:\python
,从电脑的盘符开始,表示的就是一个绝对路径。
- 相对路径:是从当前文件所在的文件夹开始的路径。
test.txt
,是在当前文件夹查找 test.txt 文件
./test.txt
,也是在当前文件夹里查找 test.txt 文件, ./
表示的是当前文件夹。
../test.txt
,从当前文件夹的上一级文件夹里查找 test.txt
文件。 ../
表示的是上一级文件夹
demo/test.txt
,在当前文件夹里查找 demo
这个文件夹,并在这个文件夹里查找 test.txt
文件。
访问模式
访问模式 |
说明 |
r |
以只读方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,则报错。这是默认模式 |
w |
打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将 会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ |
打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模 式。如果该文件不存在,创建新文件用于读写。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头 |
wb |
以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新 文件 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是 说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ |
以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文 件。 |
ab+ |
以二进制格式打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。如果该文 件不存在,创建新文件用于读写。 |
10.2、文件的读写
写数据(write)
如果文件不存在,那么创建;如果存在那么就先清空,然后写入数据
1 2 3 4
| f = open(file='test1.txt', mode='w', encoding='utf-8') f.write("乱码了吗") f.close()
|
读数据(read)
1 2 3 4
| f = open(file='test1.txt', mode='r', encoding='utf-8') result = f.read(5) print(result) f.close()
|
读数据(readlines)
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行为列表的 一个元素。换行也会读取
1 2 3 4 5
| f = open(file='test1.txt', mode='r', encoding='utf-8') result = f.readlines() print(result) f.close()
|
10.3、序列化和反序列化
通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(例如列表、字典、元组等),就无 法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里。
设计一套协议,按照某种规则,把内存中的数据转换为字节序列,保存到文件,这就是序列化,反之,从文件的字 节序列恢复到内存中,就是反序列化
对象—-》字节序列 === 序列化
字节序列—》对象 ===反序列化
Python中提供了JSON这个模块用来实现数据的序列化和反序列化
JSON模块
JSON(JavaScriptObjectNotation, JS对象简谱)是一种轻量级的数据交换标准。JSON的本质是字符串。
使用JSON实现序列化
JSON提供了dump和dumps方法,将一个对象进行序列化。
dumps
方法的作用是把对象转换成为字符串,它本身不具备将数据写入到文件的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import json file = open('names.txt', 'w') names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
result = json.dumps(names)
print(type(result))
file.write(result) file.close()
|
dump
方法可以在将对象转换成为字符串的同时,指定一个文件对象,把转换后的字符串写入到这个文件里
1 2 3 4 5 6 7 8
| import json
file = open('names.txt', 'w') names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
json.dump(names, file) file.close()
|
使用JSON实现反序列化
使用loads和load方法,可以将一个JSON字符串反序列化成为一个Python对象。
loads
方法需要一个字符串参数,用来将一个字符串加载成为Python对象。
1 2 3 4 5
| import json
result = json.loads('["zhangsan", "lisi", "wangwu", "jerry", "henry", "merry", "chris"]') print(type(result))
|
load方法可以传入一个文件对象,用来将一个文件对象里的数据加载成为Python对象。
1 2 3 4 5 6 7 8 9
| import json
file = open('names.txt', 'r')
result = json.load(file) print(result) file.close()
|
11、异常
格式
1 2 3 4
| try: 可能会出现异常的代码块 except 异常的类型: 出现异常以后的处理语句
|
示例
1 2 3 4
| try: a = 10 / 0 except ZeroDivisionError: print("程序出异常了")
|
二、爬虫技术
1、urllib
1.1、urllib库使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| urllib.request.urlopen() 模拟浏览器向服务器发送请求 response 服务器返回的数据 response的数据类型是HttpResponse 字节‐‐>字符串 解码decode 字符串‐‐>字节 编码encode read() 字节形式读取二进制 扩展:rede(5)返回前几个字节 readline() 读取一行 readlines() 一行一行读取 直至结束 getcode() 获取状态码 geturl() 获取url getheaders() 获取headers urllib.request.urlretrieve() 请求网页 请求图片 请求视频
|
一个类型和六个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import urllib.request
url = "http://www.baidu.com"
response = urllib.request.urlopen(url)
|
网页、图片、视频下载
1 2 3 4 5 6 7 8 9 10 11 12 13
| import urllib.request
|
1.2、请求对象定制
UA介绍:User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统 及版本、CPU 类型、浏览器及版本。浏览器内核、浏览器渲染引擎、浏览器语言、浏览器插件等
URL组成
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import urllib.request
url = 'https://www.baidu.com'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
|
1.3、编解码
1 2 3 4 5 6 7 8 9 10
| '''编码集的演变‐‐‐ 由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号, 这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。 但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突, 所以,中国制定了GB2312编码,用来把中文编进去。 你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc‐kr里, 各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。 因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。 Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。 现代操作系统和大多数编程语言都直接支持Unicode。'''
|
1.3.1、Get请求参数编码
使用quoto、urlencode
将参数设置为Unicode编码,否则会报错
quoto、urlencode
的区别为:quoto需要一个一个拼接,urlencode可以将一个字典中的参数一次性拼接
get请求方式:urllib.parse.quote()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import urllib.request import urllib.parse
url = 'https://www.baidu.com/s?wd='
url = url + urllib.parse.quote('周杰伦')
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' } request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
|
get请求方式:urllib.parse.urlencode()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import urllib.request import urllib.parse
url = 'https://www.baidu.com/s?'
data = { 'wd': '周杰伦', 'aaa': None } data = urllib.parse.urlencode(data)
url = url + data
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' } request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
|
1.3.2、Post请求
post请求方式
百度翻译简单翻译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import urllib.request import urllib.parse import json
url = 'https://fanyi.baidu.com/sug'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
keyword = input('输入要查询的单词:') data = { 'kw': keyword }
data = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(json.loads(content))
|
百度翻译详细翻译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import urllib.request import urllib.parse import json
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36', 'Cookie': 'BIDUPSID=112CB6BA1DD43128CF60D2C21C3891FA; PSTM=1630486205; BAIDUID=112CB6BA1DD43128A6786F0F3F6C98E3:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; __yjs_duid=1_e631d45aca5951ce99da01dbce8657761630487228976; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_PREFER_SWITCH=1; SOUND_SPD_SWITCH=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1630487229,1630489993,1630644060; delPer=0; PSINO=7; H_PS_PSSID=34434_34496_31660_33848_34524_34092_34107_26350_34426_34319_34473; BA_HECTOR=8k21a424248ka504cq1gj3atu0r; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1630647380; ab_sr=1.0.1_MDRkZDYwZjI4MzQzYjYyNTU5YTYwYTBmNWNkNTYwY2EwZTM1MWVmZDc5NTIwMmZhN2UxMWFmNDI5NzZmZWFjMDBkNDRiZTE2MTIxNjdhZDBhYWU2NDE1NGQ2M2FlN2ZhNThmYTQ2ODIyOGMzMDY0MWE2ZWQ2MjFmZjBlZWJkMmRjMzE3ZDhmMDYwNTFhODEyNzA5YWFjY2FiNjU4OGY2ZA==; __yjs_st=2_YmE3ZWYzYjZhODc4NTYxOWU4ZWQ2OTg2NTdmMzVjYmJkYjlkMmQ3YmZhYzliYWExMTI0NDAyNGY3NWEyMmU4MTk0OWQ2ODRmMDJmYzE0NGExN2RhYTg2ZjA3MTk2MjZmYjBiMjE2MTdjNWE0NzNmZGJjMjVlODYwMTkwYjZjZjJmMjAyOTBkOTdiZmVkOGNjNWI3MzZmOTdmZGNhNTM5MjA5ZGFiN2E1ZTRiYzM3ZDYwNzk1MTZmOWQ0MTdmMjhiZWFlNjg5MDE5ZGI5MGIwNjA3ZTI0NTcyMTA2MWJkMDY0NWM0ZjI1MmFmNWMzOGY5NTExMWQxZjZiNDkyYzcyN2RlZjFiNjI1ODMzOWMwOGIxNWUxODVmNzVjYjA3NTcxXzdfNGFhOWMxZjc=' }
keyword = input('输入要查询的单词:') data = { 'from': 'en', 'to': 'zh', 'query': 'appl', 'transtype': 'realtime', 'simple_means_flag': '3', 'sign': '466982.246551', 'token': '96365d8cce65e1a98a1638ee4563dc36', 'domain': 'common', }
data = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url, data=data, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(json.loads(content))
|
1.3.3、get请求和post请求的区别
1 2
| 1:get请求方式的参数必须编码,参数是拼接到url后面,编码之后不需要调用encode方法 2:post请求方式的参数必须编码,参数是放在请求对象定制的方法中,编码之后需要调用encode方法
|
1.4、Ajax的get请求
爬取豆瓣电影
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import urllib.request import urllib.parse import json
def getContent(request): return urllib.request.urlopen(request).read().decode('utf-8')
def createRequest(page): data = { 'type': 'movie', 'tag': '热门', 'sort': 'recommend', 'page_limit': page['pageSize'], 'page_start': page['pageNo'], } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36', } data = urllib.parse.urlencode(data) url = 'https://movie.douban.com/j/search_subjects?' + data return urllib.request.Request(url=url, headers=headers)
def getData(page): file = open(file='豆瓣电影.json', mode='a', encoding='utf-8') file.writelines(getContent(createRequest(page)))
if __name__ == '__main__': pageNo = int(input('查询多少页:')) pageSize = int(input('每一页查询的数量:'))
for i in range(1, pageNo + 1): page = {'pageNo': 20,'pageSize': 20} getData(page)
|
1.5、Ajax的post请求
爬取肯德基门店地区信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import urllib.parse import urllib.request
def getContent(request): return urllib.request.urlopen(request).read().decode('utf-8')
def createRequest(page): data = { 'cname': '长沙', 'pid': '', 'pageSize': str(page['pageSize']), 'pageIndex': str(page['pageNo']), } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36', } data = urllib.parse.urlencode(data).encode('utf-8') url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname' return urllib.request.Request(url=url, data=data, headers=headers)
def writeFile(page): content = getContent(createRequest(page)) file = open(file='肯德基地址信息' + str(page['pageNo']) + '.json', mode='w', encoding='utf-8') file.writelines(content) file.close()
if __name__ == '__main__': for i in range(1, 3): page = { 'pageNo': i, 'pageSize': 100 } writeFile(page)
|
1.6、爬虫异常
1 2 3 4 5 6 7 8 9
| import urllib.error
try: print('无报错') except urllib.error.HTTPError: print('系统正在升级。。。。') except urllib.error.URLError: print('系统正在升级。。。。')
|
1.7、cookie登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import urllib.request
url = 'https://weibo.com/6487700506/info'
headers = { 'cookie': 'login_sid_t=2c4ccf71ca2a85cf641b07cb4fc1864a; cross_origin_proto=SSL; WBStorage=2ceabba76d81138d|undefined; _s_tentry=-; Apache=7315577089267.8955.1630663188885; SINAGLOBAL=7315577089267.8955.1630663188885; ULV=1630663188889:1:1:1:7315577089267.8955.1630663188885:; WBtopGlobal_register_version=2021090318; crossidccode=CODE-yf-1Mm60G-45S8lz-yJQsRuxArt0NwDz8b1822; SSOLoginState=1630663288; SUB=_2A25MNYIoDeRhGeBK41UW8C7JyzqIHXVv2S5grDV8PUJbkNAKLWvVkW1NR25u8iN5ciVJT-Z-RIv8CaS6M2q1bbrR; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WhviuqORfY9IB4HpigCERW.5NHD95QcShnNS057SK5cWs4DqcjMi--NiK.Xi-2Ri--ciKnRi-zNSoBRS0M7eh-7Sntt; wvr=6; UOR=,,graph.qq.com; wb_view_log_6487700506=2048*12801.25; webim_unReadCount=%7B%22time%22%3A1630663744090%2C%22dm_pub_total%22%3A0%2C%22chat_group_client%22%3A0%2C%22chat_group_notice%22%3A0%2C%22allcountNum%22%3A40%2C%22msgbox%22%3A0%7D', 'referer': 'https://account.weibo.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
request = urllib.request.Request(url=url, headers=headers)
content = urllib.request.urlopen(request).read().decode('utf-8')
file = open(file='微博账户信息.html', mode='w', encoding='utf-8') file.write(content) file.close()
|
1.8、Handler处理器
- 为什么要学习handler?
- urllib.request.urlopen(url)
- urllib.request.Request(url,headers,data)
- Handler
- 定制更高级的请求头(随着业务逻辑的复杂 请求对象的定制已经满足不了我们的需求(动态cookie和代理不能使用请求对象的定制))
handler的基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import urllib.request url = 'http://www.baidu.com'
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' } request = urllib.request.Request(url=url, headers=headers)
handler = urllib.request.HTTPHandler()
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
|
1.9、代理服务器
- 1.代理的常用功能?
- 1.突破自身IP访问限制,访问国外站点。
- 2.访问一些单位或团体内部资源
- 扩展:某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务 器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
- 3.提高访问速度
- 扩展:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲 区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。
- 4.隐藏真实IP
- 扩展:上网者也可以通过这种方法隐藏自己的IP,免受攻击。
- 2.代码配置代理
- 创建Reuqest对象
- 创建ProxyHandler对象 用handler对象
- 创建opener对象
- 使用opener.open函数发送请求
1.9.1、单个代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import urllib.request
url = 'http://www.baidu.com/s?wd=ip'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
request = urllib.request.Request(url=url, headers=headers)
proxies = { 'http': '175.7.199.110:3256' }
handler = urllib.request.ProxyHandler(proxies=proxies) opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('代理测试.html', 'w', encoding='utf-8')as fp: fp.write(content)
|
1.9.2、代理池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import urllib.request import random
url = 'http://www.baidu.com/s?wd=ip'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
request = urllib.request.Request(url=url, headers=headers)
proxiesPool = [ {'http': '123.171.42.178:3256'}, {'http': '163.125.30.152:8118'}, {'http': '117.94.222.28:3256'}, {'http': '111.72.25.154:3256'}, ]
handler = urllib.request.ProxyHandler(proxies=random.choice(proxiesPool)) opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('代理测试.html', 'w', encoding='utf-8')as fp: fp.write(content)
|
2、解析
2.1、xpath
1 2 3 4 5 6 7 8 9
| 1.安装lxml库 pip install lxml -i https://pypi.douban.com/simple 2.导入lxml.etree from lxml import etree 3.etree.parse() 解析本地文件 html_tree = etree.parse('XX.html') 4.etree.HTML() 服务器响应文件 html_tree = etree.HTML(response.read().decode('utf‐8') 4.html_tree.xpath(xpath路径)
|
2.1.1、xpath安装
- 在谷歌商店中安装
xpath
插件
- 安装lxml到python的Scripts的文件夹中【pip install lxml】
2.1.2、xpath基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| xpath基本语法: 1.路径查询 //:查找所有子孙节点,不考虑层级关系 / :找直接子节点 2.谓词查询 //div[@id] //div[@id="maincontent"] 3.属性查询,class,value,自定义属性 //@class //@value 4.模糊查询 //div[contains(@id, "he")] //div[starts‐with(@id, "he")] 5.内容查询 //div/h1/text() 6.逻辑运算 //div[@id="head" and @class="s_down"] //div[@id="head"] | //div[@id="bottom"]
|
解析本地文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| from lxml import etree
tree = etree.parse('1、xpath的基本使用.html')
lis = tree.xpath('//body/ul/li')
liHasId = tree.xpath('//ul/li[@id]/text()') print(liHasId)
liIdIsLi1 = tree.xpath('//ul/li[@id="li1"]/text()') print(liIdIsLi1)
liClassValue = tree.xpath('//ul/li[@id="li1"]/@class') print(liClassValue)
liCon = tree.xpath('//ul/li[contains(@id,"l")]/text()') print(liCon)
idStartWith = tree.xpath('//ul/li[starts-with(@id,"a")]/text()') print(idStartWith)
liByIdAndClass = tree.xpath('//ul/li[@id="li1" and @class="classValue"]/text()') print(liByIdAndClass)
liByIdOrClass = tree.xpath('//ul/li[@id="li1"]/text() | //ul/li[@id="li2"]/text()') print(liByIdOrClass)
|
解析服务器响应的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
import urllib.request from lxml import etree
url = 'https://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' }
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
tree = etree.HTML(content)
result = tree.xpath('//input[@id="su"]/@value')[0] print(result)
|
2.1.3、xpath基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| import urllib.request from lxml import etree
def createRequest(pageNo): url = "" if pageNo == 1: url = 'https://sc.chinaz.com/tupian/meinvtupian.html' elif pageNo > 1: url = 'https://sc.chinaz.com/tupian/meinvtupian_' + str(pageNo) + '.html' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' } return urllib.request.Request(url=url, headers=headers)
def getContent(request): response = urllib.request.urlopen(request) content = response.read().decode('utf-8') return content
def dowImage(content): tree = etree.HTML(content) titles = tree.xpath('//div[@id="container"]//a/img/@alt') srcs = tree.xpath('//div[@id="container"]//a/img/@src2') items = [] for i in range(0, len(titles)): items.append({'title': titles[i], 'src': "https" + srcs[i]}) for item in items: print(item)
if __name__ == '__main__': pageNo = int(input('起始页:')) endPage = int(input('结束页:')) for page in range(pageNo, endPage + 1): request = createRequest(page) content = getContent(request) dowImage(content)
|
2.2、jsonpath
jsonpath安装
jsonpath的基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import jsonpath import json import urllib.request url = 'https://dianying.taobao.com/cityAction.json?activityId&_ksTS=1630931434381_141&jsoncallback=jsonp142&action=cityAction&n_s=new&event_submit_doGetAllRegion=true' headers = { 'accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01', 'accept-language': 'zh-CN,zh;q=0.9', 'cookie': 't=719b007b3e7950d336a784bd7b946cc2; td_cookie=1310130070; cookie2=100b92bae0ce9a1a6910e6580c48328a; v=0; _tb_token_=33661457eb3ed; cna=Ng62GZoZwzACAd+YhpEubw0x; xlly_s=1; tfstk=c9GlBQ4CFYyWTR2mCQNSzU6HSppOZf7zfXkEgXKLJTKjgqhVitWVQj86oPno991..; l=eBjfLLvmgM2_tx-XBO5aourza77TBIRb4sPzaNbMiInca6GltF_AvNCKz2qkSdtjgtCffetP_1j3WdLHR3xg5c0c07kqm0Jn3xvO.; isg=BFRUAfoQyTFjK119l_936Tp6JZLGrXiXTdCAjO41GV9i2fQjFr-VJ0xX2dHBIbDv', 'referer': 'https://dianying.taobao.com/', 'sec-ch-ua': '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"', 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-origin', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36', 'x-requested-with': 'XMLHttpRequest' } request = urllib.request.Request(url=url, headers=headers) response = urllib.request.urlopen(request) content = response.read().decode('utf-8') content = content.split('(')[1].split(')')[0] file = open('2、jsonpath解析淘票票.json', 'w', encoding='utf-8') file.write(content) file.close()
obj = json.load(open('2、jsonpath解析淘票票.json', 'r', encoding='utf-8')) name = jsonpath.jsonpath(obj, '$.returnValue.A[0].regionName') print(name)
|
2.3、.BeautifulSoup
2.3.1、安装及简介
基本简介
- BeautifulSoup简称: bs4
- 什么是BeatifulSoup?
- BeautifulSoup,和lxml一样,是一个html的解析器,主要功能也是解析和提取数据
- 优缺点?
- 缺点:效率没有lxml的效率高
- 优点:接口设计人性化,使用方便
安装及其创建
- 安装
- 导入
- from bs4 import BeautifulSoup
- 创建对象
- 服务器响应的文件生成对象
- soup = BeautifulSoup(response.read().decode(), ‘lxml’)
- 本地文件生成对象
- soup = BeautifulSoup(open(‘1.html’), ‘lxml’)
- 注意:默认打开文件的编码格式gbk所以需要指定打开编码格式
2.3.2、bs4的基本使用
格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 1.根据标签名查找节点 soup.a 【注】只能找到第一个a soup.a.name soup.a.attrs 2.函数 (1).find(返回一个对象) find('a'):只找到第一个a标签 find('a', title='名字') find('a', class_='名字') (2).find_all(返回一个列表) find_all('a') 查找到所有的a find_all(['a', 'span']) 返回所有的a和span find_all('a', limit=2) 只找前两个a (3).select(根据选择器得到节点对象)【推荐】 1.element eg:p 2..class eg:.firstname 3. eg: 4.属性选择器 [attribute] eg:li = soup.select('li[class]') [attribute=value] eg:li = soup.select('li[class="hengheng1"]') 5.层级选择器 element element div p element>element div>p element,element div,p eg:soup = soup.select('a,span')
|
示例
1 2 3 4 5 6
| <ul> <li><a href="#" title="测试" class="aaa">测试</a></li> <li><a href="21321" title="测试2" class="bbb">测试2</a></li> <li><a href="#"><span>测试一下</span></a></li> <li><a href="##" id="ccc"></a></li> </ul>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| from bs4 import BeautifulSoup
soup = BeautifulSoup(open('1、bs4的基本使用.html', 'r', encoding='utf-8'), 'lxml')
print(soup.a)
print(soup.a.attrs)
print(soup.find('a')) print(soup.find('a', title='测试2')) print(soup.find('a', class_='aaa'))
print(soup.find_all('a')) print(soup.find_all('a', class_='bbb'))
print(soup.find_all(['a', 'span'])) print(soup.find_all('li', limit=1))
print("=====================select=========================") print(soup.select('a')) print(soup.select('a[class="aaa"]'))
|
2.3.3、节点信息-获取标签内容
基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from bs4 import BeautifulSoup
soup = BeautifulSoup(open('1、bs4的基本使用.html', 'r', encoding='utf-8'), 'lxml') obj = soup.select('#div1')[0]
1、获取节点内容:适用于标签中嵌套标签的结构 obj.string obj.get_text()【推荐】 2、节点的属性 tag.name 获取标签名 eg:tag = find('li') print(tag.name) tag.attrs将属性值作为一个字典返回【属性名:属性值】 3、获取节点属性:因为obj.attrs返回一个字典,可以直接使用字典的方法le obj.attrs.get('title')【常用】 obj.get('title') obj['title']
|
示例
1
| <div id="div1"><span>测试一下</span></div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| from bs4 import BeautifulSoup
soup = BeautifulSoup(open('1、bs4的基本使用.html', 'r', encoding='utf-8'), 'lxml')
textValue = soup.select('#div1')[0] print(textValue.value) print(textValue.get_text()) print(textValue.attrs) print(textValue.attrs.get('id'))
|
使用bs4获取星巴克数据
1 2 3 4 5 6 7 8 9 10 11 12 13
| import urllib.request from bs4 import BeautifulSoup
url = 'https://www.starbucks.com.cn/menu/' response = urllib.request.urlopen(url=url) content = response.read().decode('utf-8')
soup = BeautifulSoup(content, 'lxml')
names = soup.select('ul[class="grid padded-3 product"] strong')
for name in names: print(name.get_text().replace('™', ''))
|
3、Selenium
3.1、selenium
3.1.1、Seleneum基本使用
- 什么是selenium是一个用于web程序
- Selenium是一个用于Web应用程序测试的工具。
- Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。
- 支持通过各种driver(FirfoxDriver,IternetExplorerDriver,OperaDriver,ChromeDriver)驱动 真实浏览器完成测试。
- selenium也是支持无界面浏览器操作的
- 为什么使用selenium?
- 模拟浏览器功能,自动执行网页中的js代码,实现动态加载
- 如何安装selenium?
- selenium的使用步骤?
- 导入:from selenium import webdriver
- 创建谷歌浏览器操作对象: path = 谷歌浏览器驱动文件路径 browser = webdriver.Chrome(path)
- 访问网址 url = 要访问的网址 browser.get(url)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from selenium import webdriver
path = 'chromedriver.exe' browser = webdriver.Chrome(path)
url = 'https://www.jd.com/' browser.get(url)
content = browser.page_source print(content)
|
3.1.2、Selenium元素定位
api
1 2 3 4 5 6 7 8 9 10 11 12
| 1.find_element_by_id eg:button = browser.find_element_by_id('su') 2.find_elements_by_name eg:name = browser.find_element_by_name('wd') 3.find_elements_by_xpath eg:xpath1 = browser.find_elements_by_xpath('//input[@id="su"]') 4.find_elements_by_tag_name eg:names = browser.find_elements_by_tag_name('input') 5.find_elements_by_css_selector eg:my_input = browser.find_elements_by_css_selector('#kw')[0] 6.find_elements_by_link_text eg:browser.find_element_by_link_text("新闻")
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from selenium import webdriver
path = 'chromedriver.exe' browser = webdriver.Chrome(path)
url = 'https://www.baidu.com/' browser.get(url)
respById = browser.find_element_by_id('su')
respByName = browser.find_element_by_name('wd')
respByXpath = browser.find_element_by_xpath('//input[@id="su"]')
respByTagName = browser.find_elements_by_tag_name('input')
respByCss = browser.find_element_by_css_selector('#su')
respByLink = browser.find_element_by_link_text('地图')
|
3.1.3、selenium访问元素信息
方法
1 2 3
| 获取元素信息:【 .get_attribute 】 获取标签之间的文本信息:【 .text 】 获取标签的名字:【 .tag_name 】
|
示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| from selenium import webdriver
path = 'chromedriver.exe' browser = webdriver.Chrome(path)
url = 'https://www.baidu.com/' browser.get(url)
respById = browser.find_element_by_id('su') print(respById.get_attribute('class')) print(respById.tag_name) print(respById.text) print(respById.get_attribute('value'))
|
3.1.4、selenium交互
selenium交互就是模拟用户操作浏览器,点击按钮,上一页,往文本框中输入信息等操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from selenium import webdriver import time
path = 'chromedriver.exe' browser = webdriver.Chrome(path) url = 'https://www.baidu.com/'
browser.get(url)
time.sleep(2) respById = browser.find_element_by_id('kw') respById.send_keys('周杰伦') time.sleep(2) respByIdBtn = browser.find_element_by_id('su') respByIdBtn.click() time.sleep(2) toBottom = 'document.documentElement.scrollTop=100000' browser.execute_script(toBottom) time.sleep(2) nextBtn = browser.find_element_by_xpath('//a[@class="n"]') nextBtn.click() time.sleep(2) browser.back() time.sleep(2) browser.forward() browser.quit()
|
3.2、Phantomjs
下载
https://phantomjs.org/download.html
使用
1 2 3 4 5 6 7 8
| from selenium import webdriver
path = 'phantomjs.exe' browser = webdriver.PhantomJS(path)
url = 'https://www.baidu.com/' browser.get(url) browser.save_screenshot('百度首页截图.webp')
|
3.3、Chrome handless
Chrome-headless 模式, Google 针对 Chrome 浏览器 59版 新增加的一种模式,可以让你不打开UI界面的情况下 使用 Chrome 浏览器,所以运行效果与 Chrome 保持完美一致。
系统要求
1 2 3 4 5 6 7
| 1.系统要求: Chrome Unix\Linux 系统需要 chrome >= 59 Windows 系统需要 chrome >= 60 Python3.6 Selenium==3.4.* ChromeDriver==2.31
|
配置和使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from selenium import webdriver from selenium.webdriver.chrome.options import Options
def shareBrowser(): chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable‐gpu')
path = r'C:\Program Files\Google\Chrome\Application\chrome.exe' chrome_options.binary_location = path
browser = webdriver.Chrome(options=chrome_options) return browser
browser = shareBrowser() url = 'https://www.baidu.com/' browser.get(url) browser.save_screenshot('百度首页.webp')
|
4、requests
4.1、基本使用
文档
官网:https://docs.python-requests.org/zh_CN/latest/
快速上手:https://docs.python-requests.org/zh_CN/latest/user/quickstart.html
安装
responses基本属性
1 2 3 4 5 6 7 8
| 3.response的属性以及类型 类型 :models.Response r.text :获取网站源码 r.encoding :访问或定制编码方式 r.url :获取请求的url r.content :响应的字节类型 r.status_code :响应的状态码 r.headers :响应的头信息
|
使用【一个类型和六个方法】
1 2 3 4 5 6 7 8 9 10 11 12 13
| import requests
url = 'https://www.baidu.com/'
response = requests.get(url=url) print(type(response)) response.encoding = 'utf-8' print(response.url) print(response.content) print(response.status_code) print(response.text) print(response.headers)
|
4.2、requests-get请求
urllib和requests对比
request-get请求使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import requests
url = 'https://www.baidu.com/s'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' }
data = { 'wd': '北京' }
response = requests.get(url=url, params=data, headers=headers) content = response.text print(content)
|
4.3、requests-post请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import requests import json
url = 'https://fanyi.baidu.com/sug'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' }
data = { 'kw': 'eye' }
response = requests.post(url=url, data=data, headers=headers)
content = response.text
obj = json.loads(content) print(obj)
|
4.4、代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import requests
url = 'https://www.baidu.com/s?'
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36', }
data = { 'wd': 'ip' }
proxy = { 'http': '183.240.203.136:8118' }
response = requests.get(url=url, params=data, headers=headers, proxies=proxy)
content = response.text
with open('代理.html', 'w', encoding='utf-8')as fp: fp.write(content)
|
5、scrapy
5.1、scrapy
5.1.1、scrapy简介
1 2 3 4 5 6 7
| 1、scrapy是什么? scrapy是为了一个爬取网页数据,提取结构性数据而编写的应用框架,可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中
2、安装scrapy pip install scrapy 安装出错,自行百度
|
5.1.2、scrapy项目的创建及运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 1、scrapy创建项目 终端输入:scrapy startproject 项目名称 【例如:scrapy startproject baidu-project】 2、项目组成: spiders __init__.py 自定义爬虫文件.py ----> 自己创建、编写的爬虫文件 __init__.py items.py ---->定义数据结构的地方 ,是一个集成scrapy.Item的类 middlewares.py ---->中间件 代理 pipelines.py ---->管道文件,里面只有一个类,用于处理下载的后续处理,默认是300优先级,值越小优先级越高(1-1000) settings.py ---->配置文件,比如:是否遵守robots协议,User-Agent定义等 3、创建爬虫文件 (1)进入到spiders文件夹 (2)scrapy genspider 爬虫文件的名字 要爬取网页【例如:scrapy genspider baidu www.baidu.com】 4、爬虫文件的基本组成 集成scrapy.spider类 name='baidu' allowed_domains = ['www.baidu.com'] start_urls = ['http://www.baidu.com/'] def parse(self, response): response.txt response.body response.xpath() extract() extract_first() 5、scrapy文件运行 scrapy crawl 文件名称【例如:在spiders文件夹中编写的python文件'get_baidu.py',运行:scrapy crawl get_baidu】 注意:应放在spiders文件夹内部执行
|
5.1.3、scrapy架构组成
1 2 3 4 5 6 7 8 9 10
| 1、引擎 ----->自动运行,无需关注 2、下载器 ---->从引擎处获取到请求对象后,请求数据 3、spiders ----->spider类定义了如何爬取某个(或某些)网站,包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。换句话说,spider就是定义爬取的动作及分析某个网页(或有些网页)的地方。 4、调度器 ---->有自己的调度规则,无需关注 5、管道(Item pipeline) ---->最终处理数据的管道,会预留接口供我们处理数据。当Item在Spider中被收集之后,它将会被传递到Item pipeline,一些组件会按照一定的执行顺序执行对Item的处理,每个Item pipeline(有时称之为”Item pipeline“)是实现了简单方法的python类,他们接收到Item并通过它执行一些行为,同时也决定此Item是否创建通过pipeline,或是被丢弃而不再进行处理 以下是item pipeline的一些典型应用: 清理HTML数据 验证爬取的数据(检查Item包含某些字段) 查重(并丢弃) 将爬取结果保存到数据库中
|
5.1.4、scrapy工作原理
5.2、scrapy shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 1、什么是scrapy shell? scrapy终端,是一个交互终端,可以在未启动spider的情况下尝试及调试爬取代码,其本意是用来测试提取数据的代码。不过,可以将其视作为正常的python终端,在上面测试任何python代码 该终端是用来测试xpath 或css表达式,查看他们的工作方式及从爬取的网页中提取的数据。在编写spider时,该终端提供了交互性测试的表达式代码的功能,免去了每次修改后运行spider的麻烦 2、安装ipython 安装:pip install ipython 简介:如果安装了ipython,scrapy终端将使用ipython(替代标准python终端)。ipython终端与其他相比,更强大,提供了代码自动补全,高亮等其他功能 3、应用 scrapy shell www.baidu.com scrapy shell http://www.baidu.com scrapy shell "http://www.baidu.com" scrapy shell "www.baidu.com" 4、语法 (1)response对象: response.body、response.text、response.url、response.status (2)response的解析: response.xpath() 使用xpath路径查询特定元素,返回一个selector列表对象 response.css() 使用css_selector查询元素,返回一个selector列表对象 获取内容:response.css('#su::text').extract_first() 获取属性:response.css('#su::attr("value")').extrace_first() extract_first() 提取selector列表中的第一个值 如果提取不到值,会返回一个空值 返回第一个解析到的值,如果列表为空,此方法不会报错,会返回一个空值 xpath() css() 注意:每一个selector对象可以再次的去使用xpath或css方法
|
5.3、yield
- 带有yield的函数不再是一个普通函数,而是一个生成器generator,可用于迭代
- yield是一个类似return的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行
- 简单理解:yield就是return返回一个值,并且记住这个返回值的位置,下次迭代就是从这个位置后(下一次)开始
案例:
- 当当网:(1)yield (2) 管道封装 (3)多条管道下载 (4) 多页数据下载
- 电影天堂 (1) 一个item包含多级页面的数据
5.4、
5.5、MySQL和pymysql安装和使用
MySQL安装
自行百度查询
pymysql安装和使用
pymysql是一个连接mysql的工具
1 2 3 4 5 6 7
| pip install pymysql
conn = pymysql.connect(host,port,user,password,db,charset) cursor = conn.cursor() cursor.executer()
|
5.4、当当网
5.5、电影天堂