I.VII python字符串高级应用
I.VIII python列表、元组、字典高级
🎯 列表的高级使用
🎯 元组的高级使用
🎯 切片
🎯 字典的高级使用
I.IX python函数的使用介绍
🎯 函数的定义
🎯 函数的传参
🎯 函数的返回值
🎯 局部变量与全局变量
I.X python文件基础操作
🎯 文件的创建和写入
🎯 文件的读出
🎯 文件的序列化与反序列化
I.XI python异常处理介绍
II. python爬虫篇
II.I urllib库的使用介绍
🎯 初识urlliib库:爬取某网站的源代码
🎯 HttpResponse响应的六种常见的读取方法
🎯 urllib库之下载图片、音频、视频
🎯 urllib库之定制请求头
🎯 urllib库之GET请求的爬虫操作
🎯 urllib库之POST请求的处理
🎯 GET请求与POST请求处理的区别
🎯 urllib库之handler处理器
🎯 urllib库之代理ip与代理池
🎯 urllib库的异常处理
II.II cookie的使用
🎯 什么是cookie?
🎯 利用cookie绕过登录
II.III requests库的学习
🎯 requests库的介绍与安装
🎯 requests库的基本语法
🎯 requests库的GET请求
🎯 requests库的POST请求
🎯 requests库的代理ip方法
🎯 requests库小结
II.IV 爬虫解析方法之xpath解析
🎯 xpath的安装
🎯 xpath的基本语法
II.V 爬虫解析方法之jsonpath解析
🎯 jsonpath的介绍
🎯 jsonpath的安装
🎯 jsonpath的基础语法介绍
II.VI 爬虫解析方法之bs4解析
🎯 bs4的介绍
🎯 bs4的安装
🎯 bs4的基本语法使用
🎯 bs4处理服务器响应文件
II.VII selenium库的介绍
🎯 selenium库的安装及相关浏览器工具的下载
🎯 selenium库的基本语法
🎯 selenium爬虫实战案例:获取网页源码
🎯 selenium无界面浏览器的学习
II.VIII scrapy框架的使用介绍
🎯 scrapy框架的工作原理介绍
🎯 scrapy框架的安装
🎯 用scrapy框架搭建并运行第一个项目
🎯 scrapy框架的项目结构
🎯 robots协议
🎯 scrapy框架的基本语法介绍
🎯 scrapy框架管道学习
🎯 scrapy框架的日志级别与推荐级别方案
II.IX 爬虫补充内容之Excel文件的读写
🎯 安装相关库
🎯 Excel文件的读写操作
🎯 完整的Excel操作示例代码
🎯 Excel读写常见报错解决方案
序言:
本文是我的原创博客专栏**【python爬虫学习笔记】**的精简整合版,尽管是精简版,仍然有6w字,所以大家可以先收藏;与专栏一致,本文的受众也是小白,并且保证小白通过本文能上手爬虫基础。🌟🌟🌟
另,因为篇幅原因,如果有空的朋友也可以去看一看专栏,如果不想麻烦的本文的内容也是足够的!
最后是我的经典开场白:高产量博主,点个关注💓不迷路!
I. python基础篇
============
I.I python运行方式及pycharm配置
🎯 pip指令的使用
首先简单介绍一下pip指令是什么:
pip(Python Package Index)是一个以 Python 语言写成的软件包管理系統,使用 pip 可以非常方便的安装和管理 python 软件包。
pip常用的指令有:
1️⃣ 安装指令(-i及后面的网址可以加也可以不加,加上后改用国内的源)
pip install 名称 -i https://pypi.douban.com/simple
2️⃣ 卸载指令
pip uninstall 名称
3️⃣ 查看已安装的文件
pip list
🎯 python的三种运行方式
1️⃣ 终端打代码运行:
首先运行终端:快捷键Win + R,输入 cmd,弹出终端:
输入指令:
python
运行后出现这样的提示和画面:
之后就可以正常运行python的代码,例如我们打印一个 跳探戈的小龙虾 字符串:
print(‘跳探戈的小龙虾’)
终端退出python的指令是:
exit()
执行之后,我们就回到了正常的终端状态:
2️⃣ 终端运行py文件:
提前准备一个.py文件,之后我们输入指令:
python 文件路径
即可运行。其中文件路径如果手打不方便,可以直接把文件拖动到终端,它会自动转成路径。
3️⃣ 使用IDE运行:
首先介绍一下IDE:
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。
使用IDE才是最终开发采用的方法,因为我们的代码文件需要有可修改性。
一般来说pycharm是我们首选的IDE,也有其他的选择,这里我采用pycharm。
🎯 pycharm的基础配置
1️⃣ 设置字体字号:
选择 File->Settings
之后点击 Editor->Font,即可修改
2️⃣ 自动生成指定的注释:
像这样的一段注释,可以在pycharm里设置为每次新建文件默认生成:
* coding : utf-8 *
@Time : 2022/1/14 15:27
@Author : Lobster
@File : pythonDemo2
@Project : python基础
首先,仍然是点击File->Settings:
之后,点击 Editor->File and Code Templates->Python Script,里面的内容会作为默认生成的注释:
这里给一下常用的默认注释,大家修改一下AuthorName为自己的名字即可,其他的部分可直接复制。修改后新建的py文件都会生成这段注释。
* coding : utf-8 *
@Time : ${DATE} ${TIME}
@Author : AuthorName
@File : ${NAME}
@Project : ${PROJECT_NAME}
I.II python注释及变量类型
🎯 python注释写法
在python中,分为单行注释和多行注释两种注释模式:
1️⃣ 单行注释:
单行注释在python中的语法是这样的:
单行注释
2️⃣ 多行注释:
多行注释在python中的语法是这样的:
‘’’
多
行
注
释
‘’’
🎯 python变量类型
在python中,有六种变量类型:
1️⃣ 数字(Numbers)
数字类型下,又细分为两种子数据类型:
🅰️ 整型数据:
money = 100
🅱️ 浮点数:
money = 100.5
2️⃣ 布尔值(Boolean)
布尔型变量有两个取值,分别定义如下:(True和False一定要大写!)
a = True
b = False
3️⃣ 字符串(String)
字符串即多个字符连接成的变量,在python中一个字符也是一个字符串,可以用单引号或双引号表示:
a = ‘Python yyds’
b = “Python yyds”
4️⃣ 列表(List)
列表也是python中的一个常见的数据类型,它的定义格式如下:
#list
name_list = [‘A’,‘B’]
print(name_list)
学过其他编程语言的朋友能够发现,它的格式和定义一个数组很相似。
5️⃣ 元组(Tuple)
元组在python爬虫中有很大的意义,同时它也与上面的列表类型有所不同,现阶段最大的不同在于它们的定义格式:
tuple
age_tuple = (18,19,20,21)
print(age_tuple)
6️⃣ 字典(Dict)
字典是爬虫技术中最重要的数据类型,是一个键值对的结构,它的定义如下:
dict
格式:变量的名字 = {key1 : value1,key2 : value2}
dict_demo = {‘key1’ : ‘value1’,‘key2’ : ‘value2’}
print(dict_demo)
上面的六种数据类型是python必须掌握的数据类型,也是服务于后面的爬虫技术的基础!🌟🌟🌟
I.III python类型查询与类型转换
🎯 python数据类型查询
python,众所周知,是一个弱类语言,也即它在定义变量的时候,不会事先声明变量的类型,变量的类型真正被确定的地方是在变量的赋值处。
在python中,**函数type()**可以返回变量的数据类型,例如下面的代码示例:
int
a = 1
print(a)
print(type(a))
float
b = 1.2
print(b)
print(type(b))
boolean
c = True
print©
print(type©)
string
d = ‘跳探戈的小龙虾’
print(d)
print(type(d))
list
e = [1,2,3,4,5]
print(e)
print(type(e))
tuple
f = (1,2,3,4,5)
print(f)
print(type(f))
dict
g = {‘name’ : ‘张三’}
print(g)
print(type(g))
通过type(),在变量赋值步骤被隐藏时,能够很快地找出变量的类型,这在爬虫技术中非常常用(爬取的数据进行类型查询)。
🎯 python类型转换
类型转换在python中也非常的常见,通常情况下类型转换分为这几个情况:
1️⃣ 其他类型转整型(int)
a = ‘123’
print(type(a))
b = int(a)
print(type(b))
print(b)
float --> int
c = 1.63
print(type©)
float转成整数,会返回小数点前的整数,不涉及四舍五入
d = int©
print(type(d))
print(d)
boolean --> int
True 代表 1,False 代表 0
e = True
print(type(e))
f = int(e)
print(type(f))
print(f)
g = False
h = int(g)
print(h)
这部分有两个注意事项:
🅰️ 在float转int过程中,不涉及四舍五入,只是单单的把小数点后面的数据抹掉了(丢失精度)
🅱️ 布尔型变量True转int后的值是 1,False转int后的值是 0
2️⃣ 其他类型转浮点数(float)
a = ‘12.34’
print(type(a))
b = float(a)
print(type(b))
print(b)
c = 666
print(type©)
d = float©
print(type(d))
print(d)
这部分本身没有需要注意的地方,但是要点名的是,第一句 a = ‘12.34’ 的变量a,是不能直接由字符串转成整型int类型的,只能直接转浮点数float(即转int的字符串本身不能包含特殊字符)
3️⃣ 其他类型转字符串(string)
int -> string
a = 80
print(type(a))
b = str(a)
print(type(b))
print(b)
float -> string
c = 1.2
print(type©)
d = str©
print(type(d))
print(d)
boolean -> string
e = True
print(type(e))
f = str(e)
print(type(f))
print(f)
要注意的是,布尔型转string的时候,不是转成0或1,而是转成字符串’False’或’True’。
4️⃣ 其他类型转布尔型(boolean)
int -> boolean
a = 1
print(type(a))
b = bool(a)
print(type(b))
print(b)
非0的整数都是true,包括负整数和正整数
c = 0
print(type©)
d = bool©
print(type(d))
print(d)
e = -1
print(type(e))
f = bool(e)
print(type(f))
print(f)
float -> boolean
g = 1.0
print(type(g))
h = bool(g)
print(type(h))
print(h)
0.0相当于0,所以0.0是false,除了0.0的浮点数无论正负都是false
i = 0.0
print(type(i))
j = bool(i)
print(type(j))
print(j)
string -> boolean
只要字符串有内容,都是True(内容甚至包括空格),但是没有内容的,就是False
k = ‘跳探戈的小龙虾’
print(type(k))
l = bool(k)
print(type(l))
print(l)
这个就是包含空格,运行结果是True
m = ’ ’
print(type(m))
n = bool(m)
print(type(n))
print(n)
list -> boolean
只要列表有数据,就是True
o = [‘a’,‘b’,‘c’]
print(type(o))
p = bool(o)
print(type(o))
print§
空列表是False
q = []
print(type(q))
r = bool(q)
print(type®)
print®
tuple -> boolean
只要元组有数据,就是True
s = (‘a’,‘b’)
print(type(s))
t = bool(s)
print(type(t))
print(t)
空元组是False
u = ()
print(type(u))
v = bool(u)
print(type(v))
print(v)
dict -> boolean
只要字典有数据,就是True
w = {‘a’ : ‘1’,‘b’ : ‘2’}
print(type(w))
x = bool(w)
print(type(x))
print(x)
空字典是False
y = {‘a’ : ‘1’,‘b’ : ‘2’}
print(type(y))
z = bool(y)
print(type(z))
print(z)
这部分的所有规定全部注释在代码中,可认真观察代码学习!🌟🌟🌟
I.IV python运算符
🎯 算术运算符
算术运算符是python中最基础的一类运算符,表示的是运算的关系,示例代码如下:
算术运算符
a = 3
b = 2
加法
print(a + b)
减法
print(a - b)
乘法
print(a * b)
除法 默认是保留小数
print(a / b)
取整
print(a // b)
取余
print(a % b)
幂运算
print(a ** b)
字符串加法:字符串拼接
c = ‘123’
d = ‘456’
print(c + d)
在Python中,字符串做加法时,加号两端必须两端都是字符串,若只有一端是字符串,则会报错:
e = ‘123’
f = 456
#print(e + f) # 此行会报错
print(e + str(f)) # 这是出现这种情况的处理策略:先转成str再来
在python中,还支持字符串乘法:
g = 'hello world ’
print(g * 3)
其中,想要强调两个细节:
1️⃣ 首先是两个字符串相加,相当于做了字符串拼接,不过这一点在其他编程语言中也是如此。
2️⃣ 其次是与其他编程语言不同,python不支持string类型与int类型直接做加法,这样做会报错!
🎯 赋值运算符
赋值运算符是我们常说的把一个值赋给变量,示例代码如下:
赋值运算符
a = 10
print(a)
多个变量赋同一个值
b = c = 20
print(b)
print©
多个变量同时赋值
d,e,f = 1,2,3
print(d)
print(e)
print(f)
复合赋值运算符
a = 1
a = a + 4
print(a)
a += 2
print(a)
a -= 2
print(a)
a *= 2
print(a)
a /= 2
print(a)
a //= 2
print(a)
a %= 2
print(a)
a **= 2
print(a)
这部分有意思的地方在于python支持多个变量同时赋不同的值,但是变量间和值之间都要用逗号隔开!
🎯 比较运算符
比较运算符是表示两个变量之间关系的运算符,返回值是布尔值(boolean),示例代码如下:
比较运算符
a = 10
b = 10
print(a == b)
print(a != b)
print(a > b)
print(a < b)
print(a >= b)
print(a <= b)
🎯 逻辑运算符
逻辑运算符在python中一共有三个,即 与、或、非(取反),示例代码如下:
逻辑运算符 and or not
and 与 , 没错python中的and是手打一个and,不是||
print(10 > 20 and 10 > 11)
or 或者
print(10 > 20 or 10 > 21)
not 非 取反
print(not True)
print(not False)
a = 36
关于逻辑运算符,python有别于其他编程语言的地方在于它是用英文单词表示逻辑关系,其他编程语言可能用 & | ! 这样的符号表示。另外关于逻辑运算符的短路示例代码如下:
and 的性能优化:
左侧是False,因而右侧不再执行(短路and)
a < 10 and print(‘hello world’)
or的性能优化:
左侧是True,因而右侧不再执行(短路or)
a = 38
a > 37 or print(‘你好世界’)
短路的设定,优化了逻辑运算符的执行效率!🌟🌟🌟
I.V python读入与格式化输出
🎯 输出与格式化输出
python中,普通的输出在前面的笔记中已经是经常使用了,因而不再介绍,示例代码如下:
普通输出
print(‘跳探戈的小龙虾’)
在python中,支持类似于C、C++的格式化输出,它的具体格式如下示例代码:
格式化输出:后续爬虫scrapy框架中会使用,将爬取的内容存入 Excel、MySQL、Redis
age = 20
name = ‘Lobster’
格式化输出时,%s 代表字符串,%d 代表数字,其他的数据类型的格式化输出爬虫中一般不使用,
不做介绍。格式化输出的格式如下:
在需要放置输出变量的位置根据类型放置对应的符号,之后在print函数引号后面用一个百分号把
变量名放入即可,一个变量名时无需加括号,多个变量名用一个括号按顺序括起来,逗号隔开
print(‘昵称:%s,年龄:%d’ % (name,age))
🎯 读入
读入在python中通过调用input()函数实现,它的具体格式示例如下:
python输入
nickname = input(‘请输入你的昵称’)
input()函数内的字符串会作为读入的提示语句显示在控制台。
🎯 读入和输出组合小demo
最后是实现一个简单的读入和格式化输出组合的小demo,功能是读入昵称后,回显昵称:
python输入
nickname = input(‘请输入你的昵称’)
输入内容结合格式化输出
print(‘昵称:%s’ % nickname)
这部分是关于python的格式化输出和读入的内容!🌟🌟🌟
I.VI python流程控制语句
🎯 if-elif-else流程控制
python爬虫中最常用的第一种流程控制语句是if-elif-else控制语句。学过其他编程语言的朋友会觉得elif很陌生,其实elif就是其他编程语句中else if 的缩写而已。具体的示例代码如下:
python流程控制
if、else、elif的语法结构:if 条件:
四个空格缩进 具体执行内容(if的第二行一定要有缩进,否则会报错,四个空格是一个习惯性写法,不是四个也可运行但不规范)
else:
四个空格缩进 具体执行内容(同缩进)
score = 80
if score >= 90:
print(‘优秀’)
elif score >= 80:
print(‘良好’)
elif score >= 70:
print(‘一般’)
elif score >= 60:
print(‘及格’)
else:
print(‘不及格’)
注意一下,python的if-elif-else结构中不含其他编程语言的大括号,因而要注意缩进要有并且要正确地缩进,否则逻辑会发生错误!
最后补一个if-elif-else与读入、输出结合的小demo,实现功能为读入成绩,返回打印成绩的等级:
if、else流程控制小demo:读入分数,判断成绩等级,并输出结果
这里注意,input读入函数默认读入的类型是字符串,
而python本身不支持字符串与整型比较,因此跟整型比较时,要做一步转换,否则会报错:
score = int(input(‘输入成绩:’))
if score >= 90:
print(‘优秀’)
elif score >= 80:
print(‘良好’)
elif score >= 70:
print(‘一般’)
elif score >= 60:
print(‘及格’)
else:
print(‘不及格’)
这里注意一个小细节:print()函数读入的内容默认是字符串(string)类型的,我们要先做一步强制类型转换为整型(int),而后与int型数值进行比较,否则会报错。(python不支持int和string直接比较!)
🎯 for循环流程控制
第二类爬虫中常用的是for循环流程控制语句。它的基本格式如下:
python流程控制
for循环格式:
for 变量 in 要遍历的数据:
方法体
s = ‘china’
在字符串类型遍历时,i代表了字符串中的单个字符,s代表要遍历的数据
for i in s:
print(i)
for循环通常结合range()函数一起使用,它的格式如下:
range(n),它是一个左闭右开区间
range方法的结果:一个可以遍历的对象,
如果里面是一个数字,会从0到这个数字-1
for i in range(5):
print(i) # 输出:0 1 2 3 4
如果里面有两个数字,那么有:
其中第一个代表起始数字,第二个代表末尾数字,返回这其中的数字
for i in range(1,5):
print(i) # 输出:1 2 3 4
如果里面有三个数字,前两个是起始数字和末尾数字,
最后一个数字代表间隔值或步长
for i in range(1,10,3):
print(i) # 输出:1 4 7 注意没有10,因为是左闭右开区间
以上三种是range()函数的三种传参的方式,我们通常结合range()函数对字典、元组、列表进行循环打印。另外要注意range()函数是左开右闭的一个范围!
最后附一个for循环结合列表的小demo,循环打印列表:
for循环小demo,循环打印一个列表
a_list = [‘J’,‘L’,‘T’];
for i in a_list:
print(i) # 这里的i代表了列表的每一项
I.VII python字符串高级应用
python中,字符串有很多内置的函数,详细见下面的示例:
字符串高级:字符串常见的函数
1.获取长度:len(),返回整型
s = ‘Lobster’
print(len(s))
2.获取某个字符在字符串中第一次出现的位置索引值(区分大小写): s.find(‘’),返回整型
print(s.find(‘L’))
3.判断是否以某个字符开头、结尾:s.startswith(‘’),s.endswith(‘’),返回布尔值
print(s.startswith(‘O’))
print(s.endswith(‘r’))
4.查找某个字符的个数:s.count(‘’)
print(s.count(‘o’))
5.替换某个字符:s.replace(‘’,‘’)
print(s.replace(‘L’,‘l’))
6.切割字符串:s.split(‘’),意思是以传入的字符为切割位把原字符串切开,
传入这个字符会变成空格
print(s.split(‘o’))
7.大小写转换:s.upper(),s.lower(),整个字符串转成大写或小写
print(s.upper())
print(s.lower())
8. 去掉字符串空格的函数:strip(),能把整个字符串所有空格去掉
s1 = ’ Lobster ’
print(len(s1))
print(len(s1.strip())) # 刚好是Lobster的长度7
9. join()函数,了解即可,是把一个字符串插入
到另一个字符串的每一位的后面,而不是简单的拼接,不是很常用:
s2 = ‘aaaaaa’
s3 = ‘bb’
print(s3.join(s2)) # 输出:abbabbabbabbabba
这上面最后一种函数,意义不是很大,不需要太关心,感兴趣的可以跑一跑代码感受一下,**其他的八种函数,需要掌握!**🌟🌟🌟
I.VIII python列表、元组、字典高级
🎯 列表的高级使用
对于列表来说,它的高级使用将从 增删改查 四个角度进行介绍,下面的示例代码:
列表高级:添加
1. append 追加,在列表的最后一位添加一个对象/数据
food_list = [‘apple’, ‘banana’]
print(food_list)
food_list.append(‘cock’)
print(food_list)
2. insert 插入,两个参数,第一个参数代表想要插入的下标位置,
第二个参数代表你要插入的对象/数据
char_list = [‘a’,‘c’,‘d’]
print(char_list)
char_list.insert(1,‘b’)
print(char_list) # a b c d
3. extend 继承,传入的是一个列表,把传入的列表整个插入到
调用extend()函数的列表的末尾:
num_list = [1,2,3]
num_list2 = [4,5,6]
num_list.extend(num_list2)
print(num_list)
列表高级:修改
将列表中的元素的值修改
实现的方法类似于其他编程语言中给数组某一位赋一个新的值覆盖旧值:
city_list = [‘Beijing’,‘Shanghai’,‘Shenzhen’,‘Henan’]
print(city_list)
假设想要修改第三位,Shenzhen,其索引值是2:
city_list[2] = ‘Changchun’
print(city_list)
列表高级:查询
判断已知数据是否在列表内:
用关键字:in或者not in即可,in/not in的前面是待查询的元素,in/not in后面是一个列表
1. in代表待查询的元素在列表中:
存在时返回true,不存在返回false
food_list = [‘apple’, ‘banana’,‘cock’]
food = ‘apple’
if food in food_list:
print(‘存在’)
else:
print(‘不存在’)
2. not in也是查询的关键字,代表待查询的元素不在列表中:
不存在时返回true,存在时返回false
ball_list = [‘Basketball’,‘Football’]
ball = ‘pingpang’
if ball not in ball_list:
print(‘不存在’)
else:
print(‘存在’)
列表高级:删除
1. 根据下标删除列表中的元素
a_list = [1,2,3,4,5]
print(a_list)
例如要删除下标为2的元素3,使用关键字del 加列表 加对应索引:
del a_list[2]
2. 删除列表的最后一位元素,使用关键字
b_list = [1,2,3,4,5]
print(b_list)
使用pop()函数能够删除最后一位元素:
b_list.pop()
print(b_list)
3. 根据元素的值,删除元素
c_list = [1,2,3,4,5]
print(c_list)
例如想要删除元素值为3的元素,使用remove()函数即可,传入值:
c_list.remove(3)
print(c_list) # 打印结果:1 2 4 5,如果是索引,那应是 1 2 3 5
要注意的是,对于增和删,有几种不同的模式,每种模式适用于不同的场景!
🎯 元组的高级使用
元组的高级使用,介绍的思路是从元组与列表的联系与区别入手,它们有如下联系与区别:
元组高级:与列表区别与联系:
首先,元组是圆括号(),列表是[]
a_tuple = (1,2,3,4)
a_list = [1,2,3,4]
其次,元组和列表访问某个元组的格式是一样的,
都是 变量名[index]
print(a_tuple[0])
print(a_list[0])
最后,元组的元素不可修改,列表的元素显然可以修改
a_tuple[0] = 2 #这句话会报错,因为元组不可修改
a_list[0] = 2 # 但是列表支持修改
补充:当元组中只有一个元素的时候,它是一个整型数据
b_tuple = (5)
print(type(b_tuple)) # int
如果这时候只有一个元组,还想让它是元组类型,需要在数据后面加一个逗号:
c_tuple = (5,)
print(type(c_tuple)) # tuple
由上述可以看出,元组更像其他编程语言中的 constant 变量,也即声明之后就不能再修改的变量类型。
🎯 切片
切片是一种经常运用于字符串、列表和元组中的技术方法,它的意思是将字符串、列表和元组中的元素切割成不同的片段,并把这些片段返回。下面的示例代码以字符串的切片为例,列表和元组的使用方法大同小异:
切片:适用于字符串、列表和元组,这里以字符串为例
列表和元组使用方法完全相同:
s = ‘hello world’
1.在[]中直接写下标,此时可以看做切片,也可以看做对单个元素的访问:
print(s[4])
2.在[]中写起始位索引 : 终止位索引,
此时切片是从起始位到终止位的字符串,且 【左闭右开】
print(s[0 : 4])
3. 在[]中写 n :
此时表示从第n位索引对应元素开始,一直到最后一位
print(s[1 :])
4. 在[]中写 : n
此时表示从第0位索引对应元素开始,到第n位索引,且【左闭右开】
print(s[: 3])
5. 在[]中写 n : m : o
从下标为 n 的位置开始,到下标为 m 的位置结束,且【左闭右开】
步长是 o (每次增加的位置数),且【左闭右开】
print(s[0:5:2]) # hlo,代表索引 0 2 4
🎯 字典的高级使用
字典的高级使用,和列表类似,思路是从字典的增删改查入手,并且增加了一项,那就是对字典的不同遍历方法,下面是五种操作的详细示例代码(增删改查+遍历):
字典高级
定义一个字典:
person = {‘name’ : ‘跳探戈的小龙虾’, ‘age’ : 20}
字典高级:查询
(1). 字典变量名[‘key’] 查询元素
print(person[‘name’])
print(person[‘age’])
当访问不存在的’key’值时,出现的情况是会报错:
print(person[‘sex’] 会报错 key error
(2). get()函数 查询元素
print(person.get(‘name’))
print(person.get(‘age’))
字典高级:修改
例如修改上例中 ‘name’ 键的值为 ‘张三’
person[‘name’] = ‘张三’
print(person[‘name’])
字典高级:添加
例如添加一个新的 键值对:‘sex’ ‘nan’
person[‘sex’] = ‘nan’
添加的格式与修改相同,只是此时 键 key 是不存在的,
因此会新建该键值对,如果该键存在,那就是修改操作
字典高级:删除
(1) del 关键字删除:删除字典中指定的某一个元素
del person[‘sex’]
print(person)
(2) del 关键字删除:删除整个字典,包括字典对象本身
del person
print(person) # 这时打印会报错,因为person字典已经不存在了
(3) clear 清空字典内容,但是保留字典对象
person = {‘name’ : ‘跳探戈的小龙虾’, ‘age’ : 20}
person.clear()
print(person) # 此时打印的结果只有一个 {},因为内容已被清空!但不会报错
字典高级:遍历
(1) 遍历字典的key
字典.keys() 方法,获取字典所有的key值,而后用
for循环即可,用一个临时变量进行遍历
person = {‘name’ : ‘跳探戈的小龙虾’, ‘age’ : 20}
for key in person.keys():
print(key)
(2) 遍历字典的value
字典.values() 方法,获取字典所有的value值,而后用
for循环即可,用一个临时变量进行遍历
for value in person.values():
print(value)
(3) 遍历字典的key和value
字典.items() 方法,获取所有的key value键值对,
并且用两个临时变量通过for循环遍历
for key,value in person.items():
print(key,value)
(4) 遍历字典的项/元素
仍然是字典.items() 方法,但是此时只用一个临时变量去循环遍历
即可获取字典的每一项,这与上一种的区别在于获取的
键值对会用一个()包围,即打印的结果是(key,value)
for item in person.items():
print(item)
最后关于遍历的最后一种方式,也即遍历字典的项,这里稍作说明:
遍历字典的项,它和前一种遍历key和value很相似,区别在于遍历项的结果被包含进了括号里面,也即遍历的结果是:(key,value) 的形式,**这更符合‘项’的定义。**🌟🌟🌟
I.IX python函数的使用介绍
🎯 函数的定义
在python中,为了减少代码块的重复性,与其它编程语言一样,也有函数的相关概念与实现方式,首先介绍python中函数的定义,它的格式是这样的:
python 函数
定义函数
格式为:def 函数名():
四个空格 函数体
def f_1():
print(‘Hello,Function’)
函数体前面的空格个数也可以不是4个,但是为了标准起见,尽量保持四个空格!
调用函数
格式为:函数名() 即可
f_1()
函数定义的时候,要注意缩进的规范性,尽量按照统一标准,有四个空格或者一个tab键的缩进(用pycharm打完def关键字后,会车会自动生成四个空格的缩进,不需要手动敲四个空格)。调用时,与其他编程语言类似,也是直接放一个函数名()即可。
🎯 函数的传参
在python中,函数同样支持传参,只不过与其他编程语言不同的是传参是不包含类型的,这也是python的特色。函数传参的格式如下:
函数的参数
定义格式为:
def 函数名(参数1,参数2,参数3…)
def sum(a,b):
c = a + b
print©
调用时,有两种传参方法:
1. 位置传参,即直接传递参数,按照函数定义参数的顺序传参
sum(1,9)
2. 关键字传参,即按照函数定义的参数名称进行传参
sum(b = 1, a = 9)
第二种关键字传参的方式,实际开发中运用很少,了解即可。另外关于传参,对小白稍微解释一下:定义函数时,书写的参数叫做形参;调用函数时,书写的参数叫实参或传参。
🎯 函数的返回值
返回值这块,python的格式与其他编程语言也类似,区别仍然在于python没有类型,因而即使有返回值,在定义函数时也无需提前声明。它的具体格式如下:
函数的返回值
返回值的格式为:
def 函数名():
return 返回值
def sum(a,b):
c = a + b
return c
🎯 局部变量与全局变量
在函数部分的最后,简单聊一下局部变量与全局变量,这部分仅面向小白,有其他语言基础的可以跳过。对于函数来说,在函数体内定义的变量称为局部变量,它的作用域仅限于函数体内,在函数体外该变量等价于不存在;在函数体外定义的变量称为全局变量,它的作用域是全局,也即既可以在函数体内使用,也可以在函数体外使用。下面是一个简单的demo演示:
局部变量和全局变量
局部变量:在函数的内部定义的变量,我们称为局部变量
特点:作用域范围是函数内部,在外部不可用
def f1():
a = 1
print(a)
在外部,就不能再次print(a),因为a只在函数f1()可用
全局变量:定义在函数外部的变量,我们称之为全局变量
特点:可以在函数的外部或内部使用
a = 1
print(a)
def f2():
print(a)
f2()
以上是关于python函数的基础知识介绍。🌟🌟🌟
I.X python文件基础操作
🎯 文件的创建和写入
python中,一个文件可以被创建和写入,它的示例代码如下:
python文件操作
创建/打开一个文件:test.txt
格式为:open(文件的路径;文件的模式)
模式有:w 可写 r 可读 a 追加
fp = open(‘demo/test.txt’,‘w’)
文件的关闭
执行打开、读写操作后要及时关闭文件,释放内存!
fp.close()
文件的读写
向文件内写入内容:
格式为 文件对象.write(‘内容’)
fp_w = open(‘demo/test1.txt’, ‘w’)
fp_w.write(‘hello,world\n’ * 5)
fp_w.close()
在w 写入模式下,每一次打开后,写入的位置都是开头,也即会覆盖之前的内容
在a 追加模式下,每一次会紧接着上一次写入的内容,不会覆盖:
fp_a = open(‘demo/test2.txt’, ‘a’)
fp_a.write(‘hello\n’ * 5)
fp_a.close()
需要注意的是,当文件在路径下不存在的时候,运行’w’写入模式时会自动创建文件并定为写入模式;'a’追加模式下,我们才可以每一次接着前一次的结尾写入,否则’w’模式下每一次都会覆盖前一次写入的内容!
🎯 文件的读出
文件的读操作有很多不同的类型,它的示例代码如下:
读取文件的内容
read函数是按每字节读取,效率较低
fp_r = open(‘demo/test2.txt’, ‘r’)
content = fp_r.read()
print(content)
fp_r.close()
readline函数是一行一行的读取,但是调用一次只能读取一行:
fp_l = open(‘demo/test2.txt’,‘r’)
line = fp_l.readline()
print(line)
fp_l.close()
readlines函数也是按照行来读取,并且可以一次性把所有行都读取到,
并返回一个列表的形式:
fp_ls = open(‘demo/test2.txt’,‘r’)
lines = fp_ls.readlines()
print(lines)
fp_ls.close()
需要注意的是,当文件不存在时,运行’r’读出模式是不会新建文件的,反而会抛出异常,因此要注意先新建好文件再读出。
🎯 文件的序列化与反序列化
最后介绍一下序列化和反序列化,先介绍一下序列化和反序列化的定义:
序列化:将列表、元组、字典等对象转成有序的字符串类型数据。
反序列化:将字符串类型数据转回列表、元组、字典等对象
下面是具体操作的示例代码:
文件的序列化和反序列化
默认情况下,只能直接将字符串写入文件,列表、元组、字典等对象无法写入文件:
fp = open(‘demo/test3.txt’,‘w’)
fp.write(‘hello world’)
fp.close()
name_list = [‘张三’,‘李四’]
fp_1 = open(‘demo/test4.txt’,‘w’)
fp_1.write(name_list) 这句话就会报错,因为无法直接向文件写入列表对象,
只能先进行序列化,而后写入
fp_1.close()
序列化:对象 - - - > 字节序列(json字符串)
序列化有两种方式:
(1) dumps() 函数 法
首先创建一个文件,并定义一个列表:
fp_2 = open(‘demo/test5.txt’,‘w’)
name_list = [‘zhangsan’,‘lisi’]
导入json模块到python文件:
import json
进行序列化:使用json库的dumps()函数进行对象序列化:
names = json.dumps(name_list)
fp_2.write(names)
fp_2.close()
(2) dump() 函数 法
它与dumps()的区别在于
dump()函数在完成序列化的同时,会指定目标文件,并完成写入操作
类似于一步完成dumps()的两个操作:
fp_3 = open(‘demo/test6.txt’,‘w’)
这里可以看出,传入的参数多了一个文件对象,也即这就是指定的目标文件,序列化的内容会直接写进去:
json.dump(name_list,fp_3)
fp_3.close()
fp_4 = open(‘demo/test6.txt’,‘r’)
此时执行读取,它的结果是一个字符串类型:
content = fp_4.read()
print(type(content))
print(content)
fp_4.close()
但是我们的目的是要读出一个列表/元组/字典对象,因此需要做反序列化:
反序列化:字节序列 (json字符串)- - - > 对象
反序列化也有两种方法:
(1) loads() 函数 法
fp_5 = open(‘demo/test6.txt’,‘r’)
content = fp_5.read()
调用json库中的loads()函数,传入被序列化的字符串变量,返回反序列化的json字符串:
import json
content = json.loads(content)
print(type(content))
print(content)
fp_5.close()
(2) load()函数 法:
此法与dumps和dump的区别一样,也是实现了两步合成一步
即读取字符串与字符串转json对象(列表、元组、字典)合并在一步:
fp_6 = open(‘demo/test6.txt’,‘r’)
调用json库中的load()函数,同时完成读取+转换json对象:
result = json.load(fp_6)
print(result)
print(type(result))
fp_6.close()
之所以要做序列化和反序列化,在代码中有解释,这里再重复一下,原因在于文件的写入操作不支持字典、元组、列表等对象的写入操作,因而需要先序列化后写入文件,而后读出时执行反序列化操作。🌟🌟🌟
I.XI python异常处理介绍
python中,有时候运行一段代码会报错,这时我们使用的IDE会给我们返回错误的类型在控制台,例如这样的情况,在没有创建对应文件的情况下执行读操作:
fp = open(‘text.txt’,‘r’)
此时控制台打印出这样的错误:
这固然是错误的类型,但是这样的提示是很不友好的,尤其面向客户开发的过程中,这样的错误提示会让人摸不着头脑。因此我们可以使用python中的try catch语句来自定义抛出异常提示:
异常处理:由于代码错误后,默认弹出的错误不利于用户理解,
因而在写代码时,对于可能出错的部分,做异常处理,使得弹
出的错误能被用户理解为上上策。
异常处理格式:
try:
可能出现异常的代码
except 异常的类型
便于用户理解的提示
try:
fp = open(‘text.txt’,‘r’)
except FileNotFoundError:
print(‘文件可能暂时丢失’)
此时再次运行,我们能够看到错误的提示是这样的:
这样就更方便我们去查看了!🌟🌟🌟
到这里,python的基础内容介绍完毕,如果是小白看到这里,请认真再复习一下上面的部分,然后可开始下面的部分,python基础扎实的朋友请直接进入下一部分:【python爬虫】!
II. python爬虫篇
=============
II.I urllib库的使用介绍
🎯 初识urlliib库:爬取某网站的源代码
urllib库是爬虫常用的一个库,通过这个库的学习,能够了解一些爬虫的基础技术。
下面以爬取某网站首页源码的示例代码介绍urilib库中常用的request()方法:
导入urllib库
import urllib.request
urllib爬取某网站首页的步骤:
(1) 定义一个url 即目标地址
url = ‘http://www.xxx.com’
(2) 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(url)
(3) 获取响应中的页面的源码
这里read()函数可以获取响应,但是响应的格式是二进制的,需要解码
解码:decode(‘编码格式’) 编码格式在 中显示
content = response.read().decode(‘utf-8’)
(4) 打印数据
print(content)
注意上面的解码步骤,如果不解码,获得的内容将会是二进制的格式,不利于我们的正常使用。
🎯 HttpResponse响应的六种常见的读取方法
这部分的开头,首先说明通过urllib.request()获取的对象是类型是HttpReponse型的,针对这种类型,有六种常见的读取方法,它们的示例如下:
HTTPResponse这个类型
六个方法:read、readline、readlines、getcode、geturl、getheaders
response = urllib.request.urlopen(url)
print(type(response)) # response是HTTPResponse的类型
(1) 按照一个字节一个字节去读
content = response.read()
print(content)
读取具体的n个字节,在read()函数中传参即可
content2 = response.read(5)
print(content2)
(2) 按行读取,但是只能读取一行
content3 = response.readline()
print(content3)
(3) 按行读取,并且读取所有行
content4 = response.readlines()
print(content4)
(4) 返回状态码的方法:200状态码没有问题,其他的状态码可能有问题
print(response.getcode())
(5) 返回访问的目标的url地址
print(response.geturl())
(6) 获取的是响应头
print(response.getheaders())
上述的response是在第一部分获取的响应变量,大家注意!
🎯 urllib库之下载图片、音频、视频
下面介绍一下用urllib.request()方法如何下载文件:
urllib下载文件的操作
(1) 下载网页
url_page = ‘http://www.baidu.com’
使用urillib.request.urlretrieve() 函数,
传参分别是url(网页的地址路径)、filename(网页文件的名字)
urllib.request.urlretrieve(url_page,‘baidu.html’)
(2) 下载图片
url_img = ‘https://xxx’
urllib.request.urlretrieve(url_img,‘xxx.jpg’)
(3) 下载视频
url_video = ‘https://xxx’
urllib.request.urlretrieve(url_video,‘xxx.mov’)
图片和视频的路径,可以通过在网页中右键、按F12查看网页元素找到。其中视频通常可以通过按F12,之后按ctrl+f查找’'标签的src属性后面拿到。另外所有的第二个传参都代表文件的名字,这个名字是自己起的,因此不用太拘谨,但是要注意后缀.xxx要正确,否则后缀错误导致文件将不可访问!🌟🌟🌟
🎯 urllib库之定制请求头
承接前文,此时我们开始在请求中定制我们的请求,也即要开始伪装,下面介绍最基本是一种伪装的方式,也即添加请求头:
请求对象的定制:为了解决反爬虫的第一种手段
url = ‘https://www.baidu.com’
用户代理:UA
headers = {
‘user-agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
urlopen()方法中不能传参字典,因而用户代理UA不能作为传参传入
此时需要定制一个请求对象:
这里要注意,因为resquest.Resquest()函数有三个传参,这里我们传入两个参数,所以要写成关键字传参
如果request = urllib.request.Request(url,headers) 写会报错
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode()
print(content)
这里再次强调,由于urllib.request.Request()函数有三个传参,但是我们此时只用到了两个,因此我们一定要用关键字传参法去传参,不知道什么是关键字传参的请翻阅本篇博客上面部分python函数介绍。
🎯 urllib库之GET请求的爬虫操作
下面是urllib库关于GET请求的用例代码:
get请求的quote()方法:单个参数的情况下常用该方法进行编解码
需求:用get请求的quote()方法获取源码
(1) 传统方法:
找到网页地址url:此时复制的汉字会自动转成unicode编码,如下,即这段编码就是周杰伦三个汉字的编码
url = ‘https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6’
寻找UA
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
定制请求对象
request = urllib.request.Request(url = url,headers = headers)
模拟浏览器向服务器发起请求
response = urllib.request.urlopen(request)
获取响应内容
content = response.read().decode(‘utf-8’)
打印内容
print(content)
(2) get请求的quote()方法:
定义固定的url部分
url = ‘https://www.xxx.com/s?wd=’
名字的汉字传入quote()方法做一步unicode进行编解码操作
name = urllib.parse.quote(‘xxx’)
url = url + name
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 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请求的urlencode()方法:适用于多个参数的编解码,例如下面的案例,有两个参数时这种方法更便捷
首先写出基础部分的url
base_url = ‘https://www.xxx.com/s?’
接下来定义多个参数,这些参数可以是中文的,不需要是unicode码
data = {
‘wd’ : ‘xx’,
‘sex’ : ‘xx’,
‘location’ : ‘xx’
}
此时使用urlencode()把整个多参数全部转成unicode码:
uni_data = urllib.parse.urlencode(data)
拼接url即可:
url = base_url + uni_data
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode(‘utf-8’)
print(content)
🎯 urllib库之POST请求的处理
这部分主要介绍urllib库对POST请求的处理,下面是urllib库处理POST请求的示例代码:
post请求:
import urllib.request
url = ‘https://xxx’
headers = {
‘User-Agent’:‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
data = {
‘data’:‘data’
}
import urllib.parse
post请求的参数 必须 进行编码
data = urllib.parse.urlencode(data).encode(‘utf-8’)
post请求的参数是不会拼接在url 的后面的,而是需要放置在请求对象定制的地方
request = urllib.request.Request(url = url,data = data,headers = headers)
模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)
获取响应的数据
content = response.read().decode(‘utf-8’)
import json
字符串 - - - > json 对象
obj = json.loads(content)
print(obj)
通过上面的示例代码,我们联系之前的GET请求的处理,可以考虑一下二者处理上的区别。示例代码最后部分转换json对象的原因是获取的数据格式是json字符串,我们通过转为json对象能够具体的对获取的数据进行进一步的分析。
🎯 GET请求与POST请求处理的区别
下面总结一下urllib处理GET请求与POST请求的区别:
1️⃣ post请求的参数必须编码+转码,也即编码之后,必须调用encode方法:
data = urllib.parse.urlencode(data).encode(‘utf-8’)
但get请求的参数只需要进行编码即可,也即:
data = urllib.parse.urlencode(data)
2️⃣ post请求的参数放在请求对象的定制过程中,而不是拼接字符串:
request = urllib.request.Request(url = url,data = data,headers = headers)
response = urllib.request.urlopen(request)
但get请求的参数使用字符串拼接在url上:
url = base_url + uni_data
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
🎯 urllib库之handler处理器
首先简单介绍一下handler处理器:
handler处理器是urllib库中继urlopen()方法之后又一种模拟浏览器向服务器发起请求的方法或技术。
它的意义在于使用handler处理器,能够携带代理ip,这为对抗反爬机制提供了一种策略(很多的网站会封掉短时间多次访问的ip地址)。
下面是handler处理器的具体使用方法,其中不含代理ip的部分,代理ip这部分将在下一篇笔记中介绍。
handler处理器的基础使用
需求:使用handler访问百度 获取网页源码
import urllib.request
url = ‘http://www.baidu.com’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
request = urllib.request.Request(url = url,headers = headers)
handler build_opener open
第一步:获取handler对象
handler = urllib.request.HTTPHandler()
第二步:通过handler获取opener对象
opener = urllib.request.build_opener(handler)
第三步:调用open()函数
response = opener.open(request)
content = response.read().decode(‘utf-8’)
print(content)
代码的步骤很清晰,我们可以简化整个过程为三个步骤:首先通过urllib库新建一个handler对象,而后通过urllib库的build_opener()方法新建一个opener对象,其中build_opener()要传入handler对象,最后通过opener的open()方法,获取响应,传参是我们的request定制请求对象。🌟🌟🌟
🎯 urllib库之代理ip与代理池
首先先介绍一下什么是代理ip地址:
代理IP地址:代理IP地址一般是说代理服务器的IP地址,就是说你的电脑先连接到代理IP,然后通过代理服务器上网,网页的内容 通过代理服务器,传回你自己的电脑**。代理IP就是一个安全保障,这样一来暴露在公网的就是代理IP而不是你的IP了!**
以上是对代理ip的介绍,通过介绍可以看出,我们通过代理ip能够防止自己的ip在爬取内容的时候暴露,这样一方面提高了保密性,最重要的点是通过代理ip,我们可以应对ip被封这一反爬机制了!
下面是使用代理ip的示例代码,代码中主要涉及到的知识点是handler处理器的使用(handler处理器使用方式见本文上面部分)
urllib代理
import urllib.request
url = ‘https://www.xxx’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
proxies = {
‘http’ : ‘40.83.102.86:80’
}
request = urllib.request.Request(url = url, headers = headers)
handler = urllib.request.ProxyHandler(proxies = proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode(‘utf-8’)
with open(‘daili.html’,‘w’,encoding = ‘utf-8’) as fp:
fp.write(content)
此时我们对比一下之前的handler处理器的基础使用代码,发现只有一个地方发生了变化:
handler = urllib.request.HTTPHandler() => handler = urllib.request.ProxyHandler(proxies = proxies)
这句代码换成了新的ProxyHandler对象后,我们才能把ip地址作为参数传入(proxies是ip地址的变量)。
有了代理ip的基本使用方法,我们可以继续研究一下ip代理池:
所谓代理池,就是很多的ip在一起的一个结构,在这个结构里,我们能够在每一次请求中使用不同的ip地址,从而减少同一个ip的使用频率,以降低ip被封掉的风险,对抗反爬机制!
下面展示了一个简易的代理池示例代码:
代理池的使用
import urllib.request
import random
proxies_pool = [
{ ‘http’ : ‘27.203.215.138:8060’ },
{ ‘http’: ‘40.83.102.86:80’ },
{‘http’: ‘14.215.212.37:9168’}
]
proxies = random.choice(proxies_pool)
url = ‘https://www.xxx.com’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
request = urllib.request.Request(url = url,headers = headers)
handler = urllib.request.ProxyHandler(proxies = proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode(‘utf-8’)
with open(‘dail2.html’,‘w’,encoding=‘utf-8’) as fp:
fp.write(content)
对比第一段代码,我们这里的区别在于ip地址有三个,组成了一个简单的代理池,我们通过random.choice(),从代理池这一字典对象中随机一个ip地址,而后传入handler对象的创建中,同上!🌟🌟🌟
🎯 urllib库的异常处理
在前面提到了python的异常处理,在爬虫中,urllib库的使用过程中会出现几种常见的错误如下:
try:
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode(‘utf-8’)
print(content)
except urllib.error.HTTPError:
print(‘系统正在升级…’)
except urllib.error.URLError:
print(‘都说了系统在升级…’)
1️⃣ 第一个错误是HTTPError,这是HTTP请求的错误,我们通过urllib.error.HTTPError这个类型进行匹配,捕捉后对错误进行处理即可,处理方式与之前的笔记介绍的方式相同。
2️⃣ 第二个错误是URLError,这是把url书写错误后的错误,我们通过urllib.error.URLError这个类型进行匹配,捕捉后同样处理错误。
II.II cookie的使用
🎯 什么是cookie?
首先,作为这部分的第一部分,先介绍一下什么是cookie:
Cookie 并不是它的原意“甜饼”的意思, 而是一个保存在客户机中的简单的文本文件, 这个文件与特定的 Web 文档关联在一起, 保存了该客户机访问这个Web 文档时的信息, 当客户机再次访问这个 Web 文档时这些信息可供该文档使用。由于“Cookie”具有可以保存在客户机上的神奇特性, 因此它可以帮助我们实现记录用户个人信息的功能, 而这一切都不必使用复杂的CGI等程序 。
举例来说, 一个 Web 站点可能会为每一个访问者产生一个唯一的ID, 然后以 Cookie 文件的形式保存在每个用户的机器上。如果使用浏览器访问 Web, 会看到所有保存在硬盘上的 Cookie。在这个文件夹里每一个文件都是一个由“名/值”对组成的文本文件,另外还有一个文件保存有所有对应的 Web 站点的信息。在这里的每个 Cookie 文件都是一个简单而又普通的文本文件。透过文件名, 就可以看到是哪个 Web 站点在机器上放置了Cookie(当然站点信息在文件里也有保存)
这是某度对cookie的介绍和我对cookie的理解,用一句话总结就是cookie是携带了用户信息的标识,由于我们的HTTP协议是没有记忆的,通过cookie就能够将用户进行点对点的识别。当你进入某个网站并登录后,关闭网站再次进入,如果不需要再次登录而是直接进入登录状态,那么这个网站就是使用了cookie技术。
🎯 利用cookie绕过登录
这是我们的重点:利用cookie绕过登录。
需要这么做的原因在于当使用爬虫爬取一些网页时,这些网页对应的网站会将我们对于某个页面请求重定向到网站的登录页面,也就是这样的一个逻辑顺序:
假设我们要爬取页面A,该网站的登录页面是页面B,当我们遇到会重定向到登录页面进行反爬的网站时,会出现:请求A - - - > 返回B 的效果,但是我们需要的效果是:请求A - - - > 返回A,此时就需要cookie绕过登录的操作:
数据的采集时,绕过登录,进入某个页面,这是cookie登录
import urllib.request
url = ‘https://xxx’
headers = {
cookie中携带着登录信息,如果有登陆之后的cookie,那我们可以携带者cookie进入到任何页面
‘cookie’: ‘xxx’,
referer 判断当前路径是不是由referer链接进来的 如果不是从这个链接进入,则不可访问
‘referer’: ‘https://xxx’,
‘user-agent’: ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36’,
}
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode(‘utf-8’)
保存本地
with open(‘xxx.html’,‘w’,encoding=‘utf-8’)as fp:
fp.write(content)
cookie的具体值可以通过F12检查网络源代码后获取:按F12 - - - > 选择 Network - - - > Headers - - - > cookie,我以一个网站为例:
最后简单介绍一下参数referer,这个参数的含义是源url,也就是通过这个源url,我们进入了这个目标页面,因此很多的网站会通过referer这个源url参数来进行一个反爬判定,我们可以添加referer这个参数在headers里,作为对抗这一机制的方法!🌟🌟🌟
II.III requests库的学习
🎯 requests库的介绍与安装
首先,了解一下什么是requests库:
它是一个Python第三方库,处理URL资源特别方便,可以完全取代之前学习的urllib库,并且更加精简代码量(相较于urllib库)。
那么话不多说,我们安装一下:
1️⃣ 首先,我们依旧是打开pycharm,查看一下自己的python解释器的安装位置:File - - - > Settings - - - > Project - - - > Python Interpreter
2️⃣ 进入python解释器安装目录下,打开终端: Win + R,输入cmd ,回车,之后输入指令 cd,把Scripts文件夹拖入cd后的光标中并执行切换:
3️⃣ 输入安装指令并执行:
pip install requests
🎯 requests库的基本语法
接下来,介绍requests的基本语法,与urllib库类似,requests库的语法大致分为一种类型与六种属性:
首先回忆一下urllib库,在urllib库中,我们通过测试发现,它获取的服务器响应是HTTPResponse的类型,而requests库获取的服务器响应是requests.models.Response的类型。
然后我们用requests库模拟浏览器,向服务器发起一次普通的请求,这次请求只是为了辅助下面的六种属性:
import requests
url = ‘http://www.xxx.com’
response = requests.get(url = url)
用requests库时,我们发起请求是通过requests.get()函数进行的,传参是目的网页的url(后续会有其他的传参,暂时此处传入一个url),并且用response变量接受服务器的响应。
接下来是requests库的六种属性:
1️⃣ text属性:字符串形式返回网页源码(由于此时编码格式是gbk,中文部分可能会乱码,稍后解决)
(1) text属性:以字符串形式返回网页源码
print(response.text) # 由于没有设置编码格式,中文会乱码
2️⃣ **encoding属性:**设置相应的编码格式
(2) encoding属性:设置相应的编码格式:
response.encoding = ‘utf-8’
这之后的response就不会出现中文乱码现象了。
3️⃣ url属性:返回url地址
(3) url属性:返回url地址
url = response.url
4️⃣ content属性:返回二进制的数据
(4) content属性:返回二进制的数据
content_binary = response.content
5️⃣ status_code属性:返回状态码 200是正常
(5) status_code属性:返回状态码 200是正常
status_code = response.status_code
6️⃣ headers属性:返回响应头
(6) headers属性:返回响应头
headers = response.headers
🎯 requests库的GET请求
requests库的get请求的示例代码如下:
import requests
url = ‘https://www.xxx.com’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
data = {
‘data’ : ‘data’
}
三个参数:
url:请求路径
params:请求参数
kwargs:字典
不需要请求对象的定制
参数使用params进行传递
参数无需编码
同时不需要请求对象定制
请求路径的?字符可以加也可以省略
response = requests.get(url = url,params = data,headers = headers)
response.encoding = ‘utf-8’
content = response.text
print(content)
从上面可以看出来,requests最省代码的地方在于,它不需要进行请求对象的定制,如果换成urllib库,我们需要先封装一个request请求对象,而后把这个对象传入urllib.request.urlopen()函数中,而在requests库中,我们只需要把三个参数,即url、data和headers传入,即可完成get请求,十分方便!(上面的代码执行的是在百度中搜索‘跳探戈的小龙虾’返回的网页源码)
🎯 requests库的POST请求
接下来是requests库的post请求:
requests_post请求
import requests
url = ‘https://www.com’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
data = {
‘data’ : ‘xxx’
}
四个参数:
url:请求路径
data:请求参数
json数据
kwargs:字典
response = requests.post(url = url,data = data,headers = headers)
content = response.text
import json
obj = json.loads(content.encode(‘utf-8’))
print(obj)
如果说get请求requests库只比urllib库简单一点点的话,那么post请求绝对是requests库更加便捷,它不仅省去的请求对象的定制,而且省略了参数的编码和转码的操作,可以说非常方便,只需要和get请求一样把三个参数url、data和headers传入即可,因此post请求个人强烈推荐用requests库代替urllib库。
🎯 requests库的代理ip方法
最后介绍一下requests使用代理ip的方式,它又简化了urllib库,回忆urllib库代理ip,我们需要创建handler处理器,还要定义opener对象,但requests库中,我们只需要把代理ip作为一个普通的参数,传入requests.get()/requests.post()函数即可(简直太方便了!)
requests_ip代理
import requests
url = ‘http://www.baidu.com/s’
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
data = {
‘wd’ : ‘ip’
}
proxy = {
‘http:’ : ‘218.14.108.53’
}
response = requests.get(url = url, params = data,headers = headers,proxies = proxy)
content = response.text
🎯 requests库小结
最后,简单总结一下requests库,首先对于requests库,不再是六种方法,而是有六个属性;其次是对于get请求和post请求,requests库都不再需要请求对象的定制,而且post请求不再需要编解码操作;最后对于ip代理,不需要定义一些中间对象,直接传入代理ip,作为一个普通参数即可。同时,我们的requests.get()/requests.post()函数,能够传入四个参数:url、data、headers、ip代理。🌟🌟🌟
II.IV 爬虫解析方法之xpath解析
🎯 xpath的安装
在第一部分安装的介绍之前,先介绍一下什么是xpath,以及为什么我们要学习xpath:
xpath是一门在XML文档中查找信息的语言。xpath可用来在XML文档中对元素和属性进行遍历。
通俗的说,xpath可以用来精确的定位和切割某个标签,标签指的是我们的html文件的源码中的标签,例如
、 这些标签。那么这个和我们的爬虫有什么关系呢?在之前的笔记中,我们大体上只获得过页面的源代码,这很大程度是不够的,我们需要的是精确的信息,这些信息就需要从混乱的源码中提取出来,而xpath就提供了这样的一种方法。总结,我们用xpath来精确提取html源码中的信息。
下面我们进行xpath的安装:
1️⃣ 在python的解释器所在的文件目录中Script文件夹内安装lxml库:
lxml库包含了我们需要的xpath,因此我们需要先安装lxml库,这个库要怎么安装呢,这里提供了详细的步骤:
首先,我们打开pycharm,选中File - - - > setting:
打开后,选择Project - - - > Python Interpreter:
之后能够看到python interpreter 的路径,我们可以选择进入这个路径,也可以稍后手打路径,我这边推荐我们先进入这个路径对应的文件,也即我们进入Python38文件夹。
之后我们打开终端(Win + R,而后输入cmd),并输入指令:cd
之后我们不必手打后面的路径,而是可以把Scripts文件拖动到cd的光标后(cd后面要留一个空格!) :
拖动后,路径会被自动输入,我们回车确认即可。而后我们通过终端进入了Scripts文件夹,之后我们输入这句指令安装lxml库:
pip install lxml -i https://pypi.douban,com/simple
安装后,我们就可以在pycharm中导入lxml库中的xpath了,导入xpath的代码是这样的:
from lxml import etree
2️⃣ 接下来我们安装浏览器插件:xpath插件:
针对谷歌浏览器的朋友,打开自己的扩展程序:
而后保持扩展程序被打开的状态,我们下载xpath的zip文件(提取码:dxzj):
下载后,不要解压zip,而是把这个zip文件拖入我们刚才打开的扩展程序页面,之后xpath插件就会被自动安装在浏览器上了:
🎯 xpath的基本语法
xpath的基本语法,都展示在了下面的示例代码中,这些语法与正则表达式很类似:
解析:xpath的基础使用
from lxml import etree
xpath解析
1. 本地文件:etree.parse
2. 解析服务器响应的数据 response.read().decode(‘utf-8’) ***** etree.HTML()
xpath解析本地文件
tree = etree.parse(‘new.html’)
查找ul下面的li
li_list = tree.xpath(‘//body//li’)
判断列表的长度:length
print(li_list)
print(len(li_list))
查找带有id属性的li标签
li_list = tree.xpath(‘//ul/li[@id]’)
print(li_list)
print(len(li_list))
获取标签的内容:text()
li_list = tree.xpath(‘//ul/li[@id]/text()’)
print(li_list)
print(len(li_list))
获取指定id的标签,属性值id要加引号
li_list = tree.xpath(‘//ul/li[@id = “l1”]/text()’)
print(li_list)
查找指定id的标签的class属性值
li_list = tree.xpath(‘//ul/li[@id = “l1”]/@class’)
print(li_list)
模糊查询:
(1) id中含有l的li标签
li_list = tree.xpath(‘//ul/li[contains(@id,“l”)]/text()’)
print(li_list)
(2) id的值以l开头的li标签
li_list = tree.xpath(‘//ul/li[starts-with(@id,“c”)]/text()’)
print(li_list)
逻辑运算:
(1) 查询id为l1和class为c1的标签:
li_list = tree.xpath(‘//ul/li[@id = “l1” and @ class = “c1”]/text()’)
print(li_list)
(2) 查询id为l1或l2的标签:
li_list = tree.xpath(‘//ul/li[@id = “l1”]/text() | //ul/li[@id = “l2”]/text()’)
print(li_list)
xpath解析服务器响应文件:从某网站html文件中提取内容
(1) 获取源码
import urllib.request
url = “https://xxx.com”
headers = {
‘User-Agent’ : ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36’
}
request = urllib.request.Request(url = url,headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode(‘utf-8’)
print(content)
(2) xpath解析服务器响应的文件
from lxml import etree
解析服务器响应的文件的核心操作:
tree = etree.HTML(content)
注意xpath的返回数据类型是列表,我们可以用索引值:
result = tree.xpath(‘//input[@id = “su”]/@value’)[0]
print(result)
最后强调一下,xpath既可以处理本地html文件,也可以处理服务器的响应html文件,这是它的一个特性,这个特性在后面其他的提取技术(jsonpath)中可能不具备!🌟🌟🌟
II.V 爬虫解析方法之jsonpath解析
🎯 jsonpath的介绍
首先介绍一下jsonpath是什么:
jsonpath是一种简单的方法来提取给定JSON文档的部分内容。
那么我们为什么要学习jsonpath?原因其实很简单,因为有时候我们拿到的数据是以json为格式的数据,此时我们不再能够使用之前学习的xpath对内容进行解析,因此我们需要一种方法来解析json格式的数据,它就是jsonpath!
🎯 jsonpath的安装
在语法介绍之前,先安装一下jsonpath库:
安装的方法是这样的:
1️⃣ 首先,我们打开pycharm,选中File - - - > setting
之后选择 Project:xxxx - - - > Python Interpreter
最后按照图中位置,找到自己的python的安装地址,并且进入改地址。
2️⃣ 之后,在地址所示的这个位置,我们按 Win + R,调出终端框,并输入 cd,之后路径还是用拖拽法把Scripts文件夹拖进cd光标后(要在cd后面间隔一个空格):
3️⃣ 最后,在终端框输入下面的指令,安装jsonpath:
pip install jsonpath
🎯 jsonpath的基础语法介绍
介绍语法之前,先强调一点,那就jsonpath只能处理本地的json文件,不能直接处理服务器的响应,这是它与xpath的第二点区别(第一点是处理的对象不同)。
然后我们先以下面这个json源码为例子,进行语法介绍:
{
“store”: {
“book”: [
{
“category”: “reference”,
“author”: “Nigel Rees”,
“title”: “Sayings of the Century”,
“price”: 8.95
},
{
“category”: “fiction”,
“author”: “Evelyn Waugh”,
“title”: “Sword of Honour”,
“price”: 12.99
},
{
“category”: “fiction”,
“author”: “Herman Melville”,
“title”: “Moby Dick”,
“isbn”: “0-553-21311-3”,
“price”: 8.99
},
{
“category”: “fiction”,
“author”: “J. R. R. Tolkien”,
“title”: “The Lord of the Rings”,
“isbn”: “0-395-19395-8”,
“price”: 22.99
}
],
“bicycle”: {
“author”: “Tony”,
“color”: “red”,
“price”: 19.95
}
},
“expensive”: 10
}
新建一个json文件,把上面的代码拷贝进去,并命名文件,我这里命名为store.json。(或者直接点击这里下载:store.json,提取码:yrso)
1️⃣ 读取一个json文件:
首先介绍如何读入一个json文件,它的语法格式是这样的:
import json
import jsonpath
注意,默认打开文件的格式是gbk,但json.load()返回的的对象格式要求编码为utf-8,
因此我们要强制编码为utf-8
obj = json.load(open(‘store.json’,‘r’,encoding = ‘utf-8’))
这里要注意,我们调用函数之前,要先导入json库和jsonpath库;此外,我们通过json.load()函数导入我们的json文件,这个函数的传参不是文件名,而是一个文件对象。
这里多解释一下,也就是说,我们传参是:json.load(文件对象),而不是json.load(‘store.json’),后者是一个字符串,会报错,至于这个文件对象,我们可以直接用open()函数创建,也可以在外面先用open函数新建一个文件对象,之后将对象传入,二者均可。
2️⃣ 解析json文件:
导入后,我们开始学习jsonpath的语法,首先我们参考下表,对照一下jsonpath的语法与xpath:
XPath | JSONPath | 描述 |
/ | $ | 根元素 |
. | @ | 当前元素 |
/ | . or [] | 当前元素的子元素 |
.. | n/a | 当前元素的父元素 |
// | .. | 当前元素的子孙元素 |
* | * | 通配符 |
@ | n/a | 属性的访问字符 |
注意,第一行的/是根元素的意思,也就是说在jsonpath中,每一句jsonpath语言都要以一个$符号开头,后面的部分按照上面与xpath对照进行理解即可。(n/a表示该项不存在)
基于上面的表格,我们能够对前面提到的store.json做如下的实战演练,加强对jsonpath使用的理解:
import json
import jsonpath
注意,默认打开文件的格式是gbk,但json.load()返回的的对象格式要求编码为utf-8,
因此我们要强制编码为utf-8
obj = json.load(open(‘store.json’,‘r’,encoding = ‘utf-8’))
解析书店所有书的作者
book_author_list = jsonpath.jsonpath(obj,‘$.store.book[*].author’)
print(book_author_list)
可以用索引值标注第几本书:
author = jsonpath.jsonpath(obj,‘$.store.book[1].author’)
print(author)
所有的作者,包括自行车
author_list = jsonpath.jsonpath(obj,‘$…author’)
print(author_list)
store下面所有的元素
tag_list = jsonpath.jsonpath(obj,‘$.store.*’)
print(tag_list)
store下面所有的price
price_list = jsonpath.jsonpath(obj,‘$.store…price’)
print(price_list)
第三个书
book = jsonpath.jsonpath(obj,‘$.store.book[2]’) # 也可以写作 $…book[2]
print(book)
最后一本书
@相当于this,指代当前的每一个对象
@.length表示当前的json的字典长度
last_book = jsonpath.jsonpath(obj,‘$…book[(@.length-1)]’)
print(last_book)
前两本书
用切片思维:
book_list = jsonpath.jsonpath(obj,‘$…book[0,1]’)
另一种写法:
book_list = jsonpath.jsonpath(obj,‘$…book[:2]’)
过滤包含版本号isbn的书:
条件过滤需要在圆括号前面添加一个问号
book_list = jsonpath.jsonpath(obj,‘$…book[?(@.isbn)]’)
print(book_list)
过滤超过十元的书
book_list = jsonpath.jsonpath(obj,‘$…book[?(@.price > 10)]’)
print(book_list)
II.VI 爬虫解析方法之bs4解析
🎯 bs4的介绍
首先,介绍一下bs4,它是又一种解析的手段,之前有xpath和jsonpath。bs4的特点是这样的:
BS4全称是Beatiful Soup,它提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
bs4最舒服的一点是提供了更适合前端开发工作者使用的语言习惯,它的语法很大程度对前端开发工作者是友好的,同时它解析的对象是本地html文件和服务器的响应html文件。
🎯 bs4的安装
接下来,我们安装一下bs4:
1️⃣ 首先,我们打开pycharm,选中File - - - > setting
之后选择 Project:xxxx - - - > Python Interpreter
最后按照图中位置,找到自己的python的安装地址,并且进入该地址:
2️⃣ 之后,在地址所示的这个位置,我们按 Win + R,调出终端框,并输入 cd,之后路径还是用拖拽法把Scripts文件夹拖进cd光标后(要在cd后面间隔一个空格):
3️⃣ 最后,在终端框输入下面的指令,安装jsonpath:
pip install bs4
🎯 bs4的基本语法使用
前面提到bs4可以解析本地和服务器响应html文件,为了方便介绍bs4的基本语法,我们以本地的html为例,下面是本地html的源码:
- 张三
- 李四
- 王五
- 周六
-
hhh
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)
tf-8
obj = json.load(open(‘store.json’,‘r’,encoding = ‘utf-8’))
这里要注意,我们调用函数之前,要先导入json库和jsonpath库;此外,我们通过json.load()函数导入我们的json文件,这个函数的传参不是文件名,而是一个文件对象。
这里多解释一下,也就是说,我们传参是:json.load(文件对象),而不是json.load(‘store.json’),后者是一个字符串,会报错,至于这个文件对象,我们可以直接用open()函数创建,也可以在外面先用open函数新建一个文件对象,之后将对象传入,二者均可。
2️⃣ 解析json文件:
导入后,我们开始学习jsonpath的语法,首先我们参考下表,对照一下jsonpath的语法与xpath:
XPath JSONPath 描述 / $ 根元素 . @ 当前元素 / . or [] 当前元素的子元素 .. n/a 当前元素的父元素 // .. 当前元素的子孙元素 * * 通配符 @ n/a 属性的访问字符 注意,第一行的/是根元素的意思,也就是说在jsonpath中,每一句jsonpath语言都要以一个$符号开头,后面的部分按照上面与xpath对照进行理解即可。(n/a表示该项不存在)
基于上面的表格,我们能够对前面提到的store.json做如下的实战演练,加强对jsonpath使用的理解:
import json
import jsonpath
注意,默认打开文件的格式是gbk,但json.load()返回的的对象格式要求编码为utf-8,
因此我们要强制编码为utf-8
obj = json.load(open(‘store.json’,‘r’,encoding = ‘utf-8’))
解析书店所有书的作者
book_author_list = jsonpath.jsonpath(obj,‘$.store.book[*].author’)
print(book_author_list)
可以用索引值标注第几本书:
author = jsonpath.jsonpath(obj,‘$.store.book[1].author’)
print(author)
所有的作者,包括自行车
author_list = jsonpath.jsonpath(obj,‘$…author’)
print(author_list)
store下面所有的元素
tag_list = jsonpath.jsonpath(obj,‘$.store.*’)
print(tag_list)
store下面所有的price
price_list = jsonpath.jsonpath(obj,‘$.store…price’)
print(price_list)
第三个书
book = jsonpath.jsonpath(obj,‘$.store.book[2]’) # 也可以写作 $…book[2]
print(book)
最后一本书
@相当于this,指代当前的每一个对象
@.length表示当前的json的字典长度
last_book = jsonpath.jsonpath(obj,‘$…book[(@.length-1)]’)
print(last_book)
前两本书
用切片思维:
book_list = jsonpath.jsonpath(obj,‘$…book[0,1]’)
另一种写法:
book_list = jsonpath.jsonpath(obj,‘$…book[:2]’)
过滤包含版本号isbn的书:
条件过滤需要在圆括号前面添加一个问号
book_list = jsonpath.jsonpath(obj,‘$…book[?(@.isbn)]’)
print(book_list)
过滤超过十元的书
book_list = jsonpath.jsonpath(obj,‘$…book[?(@.price > 10)]’)
print(book_list)
II.VI 爬虫解析方法之bs4解析
🎯 bs4的介绍
首先,介绍一下bs4,它是又一种解析的手段,之前有xpath和jsonpath。bs4的特点是这样的:
BS4全称是Beatiful Soup,它提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
bs4最舒服的一点是提供了更适合前端开发工作者使用的语言习惯,它的语法很大程度对前端开发工作者是友好的,同时它解析的对象是本地html文件和服务器的响应html文件。
🎯 bs4的安装
接下来,我们安装一下bs4:
1️⃣ 首先,我们打开pycharm,选中File - - - > setting
之后选择 Project:xxxx - - - > Python Interpreter
最后按照图中位置,找到自己的python的安装地址,并且进入该地址:
2️⃣ 之后,在地址所示的这个位置,我们按 Win + R,调出终端框,并输入 cd,之后路径还是用拖拽法把Scripts文件夹拖进cd光标后(要在cd后面间隔一个空格):
3️⃣ 最后,在终端框输入下面的指令,安装jsonpath:
pip install bs4
🎯 bs4的基本语法使用
前面提到bs4可以解析本地和服务器响应html文件,为了方便介绍bs4的基本语法,我们以本地的html为例,下面是本地html的源码:
soupDemo - 张三
- 李四
- 王五
- 周六
-
hhh
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-Kb6WXdHl-1713758969607)]
[外链图片转存中…(img-mk3Y2E7H-1713758969608)]
[外链图片转存中…(img-k8tKFTo3-1713758969609)]
[外链图片转存中…(img-bWbwEiwg-1713758969610)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)