商业网站需要的,品牌策划推广方案,怎么早网站上放广告,临沂网站建设兼职Python爬虫学习#xff08;网络爬虫#xff08;又称为网页蜘蛛#xff0c;网络机器人#xff0c;在FOAF社区中间#xff0c;更经常的称为网页追逐者#xff09;#xff0c;是一种按照一定的规则#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字…Python爬虫学习网络爬虫又称为网页蜘蛛网络机器人在FOAF社区中间更经常的称为网页追逐者是一种按照一定的规则自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
python学习资料已打包好需要的小伙伴可以戳这里【python资料】 一、基础知识准备 Python在各个编程语言中比较适合新手学习Python解释器易于扩展可以使用C、C或其他可以通过C调用的语言扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库提供了适用于各个主要系统平台的源码或机器码。 1 条件判断语句
score 60
if score 90 and score 100:print(本次考试等级为A)
elif score 70 and score 90: #elif else ifprint(本次考试等级为B)
else:print(本次考试等级为C) #output: 本次考试等级为C2 循环语句
2.1 for循环
for i in range(5): #输出5个数 [0 1 2 3 4]print(i)for i in range(0,10,3):#从[0,10)以3为间距输出 #output: [0 3 6 9]print(i)for i in range(-10,-100,-30):#从[-10-100)以-30为间距 #output: [-10 -40 -70]print(i)namechengdu
for x in name:print(x) #output: [c h e n g d u]a [a, b, c]
for i in range(len(a)):print(i, a[i]) #output: [0 a 1 b 2 c]2.2 while循环
i0
while i3:print(这是第%d次循环%(i1))print(i%d%i)i1#output:
这是第1次循环
i0
这是第2次循环
i1
这是第3次循环
i2count 0
while count3:print(count,小于3)count 1
else:print(count,大于或等于3)#output:
0 小于3
1 小于3
2 小于3
3 大于或等于33 字符串
strchengdu
print(str) #chengdu
print(str[0]) #c
print(str[0:5]) #[0,5) cheng
print(str[1:7:2]) #[起始位置结束位置步进值] hnd
print(str[5:]) #显示5以后的 du
print(str[:5]) #显示5以前的 cheng
print(str,hello) #字符串连接 chengdu,hello
print(str*3) #打印3次 chengduchengduchengdu
print(hello\nchengdu) #\n换行 hello chengdu
print(rhello\nchengdu) #前面加r表示显示原始字符串不进行转义hello\nchengdu
print(-*30) #打印30个“-”4 列表-List 列表中的每个元素都分配一个数字 - 它的位置或索引第一个索引是0第二个索引是1依此类推。 4.1 列表定义
namelist [小张,小王,小李]
testlist [1,测试,str] #列表中可以存储混合类型
testlist [[a,b],[c,d],[e,f,g]] #列表嵌套4.2 列表元素输出
namelist [小张,小王,小李]
#输出指定元素
print(namelist[1]) #output: 小王#遍历输出
for name in namelist: print(name)output
小张
小王
小李#使用枚举函数enenumerate()同时拿到列表下标和元素类容
for i,name in enumerate(namelist): print(i,name)output
0 小张
1 小王
2 小李4.3 列表元素切片
如下所示L[‘Google’, ‘Python’, ‘Taobao’]
Python表达式 结果描述L[2]‘Taobao’读取第三个元素L[-1]‘Taobao’读取最后一个元素L[1:][‘Python’, ‘Taobao’]输出从第二个元素开始后的所有元素L[:-1][‘Google’, ‘Python’]输出从第一个到倒数第一个的所有元素L[-2:][‘Python’, ‘Taobao’]输出从倒数第二个到末尾的所有元素
4.4 列表元素追加
#append
a [1,2]
b [3,4]
a.append(b) #将b列表当做一个元素加入到a中
print(a) #output: [1, 2, [3, 4]]#extend
a [1,2]
b [3,4]
a.extend(b) #将b列表中的诶个元素逐一追加到a中
print(a) #output: [1, 2, 3, 4]#insert
a[1,2,4]
a.insert(2,3) ##在下标为2的位置插入3 #指定下标位置插入元素第一个表示下标第二个表示元素
print(a) #output: [1, 2, 3, 4] 4.5 列表元素删除
#del
a [小张,小王,小李]
del a[2] #删除指定下标元素
print(a) #output: [小张, 小王]#pop
a [小张,小王,小李]
a.pop() #弹出末尾元素
print(a) #output: [小张, 小王]#remove
a [小张,小王,小李]
a.remove(小李) #直接删除指定内容的元素
print(a) #output: [小张, 小李]4.6 列表元素修改
a [小张,小王,小李]
a[2] 小红 #修改指定下标元素内容
print(a) #output: [小张, 小王, 小红]4.7 列表元素查找
#in / not in
a [小张,小王,小李]
findName input(请输入你要查找的学生姓名)
if findName in a:print(找到)
else:print(未找到)#index
a [小张,小王,小李]
print(a.index(小王,0,2)) #可以查找指定下标范围的元素并返回找到对应数据的下标 #output: 1
print(a.index(小李,0,2)) #范围区间左开右闭[0,2) # ValueError: 小李 is not in list#count
print(a.count(小王)) #查找某个元素出现的次数 #output: 14.8 列表元素反转和排序
a [1,4,2,3]
a.reverse() #将列表所有元素反转
print(a) #output: [3, 2, 4, 1]a.sort() #升序
print(a) #output: [1, 2, 3, 4]a.sort(reverseTrue) #降序
print(a) #output: [1, 2, 3, 4]5 前段知识综合练习 Topic: 将8个老师随机分配到3个办公室 import random
offices [[],[],[]] #3个教室
teachers [A,B,C,D,E,F,G,H] #8个老师
for teacher in teachers: #遍历teachers放入office中index random.randint(0,2) #产生随机数0,1,2offices[index].append(teacher) #将teachers追加到office中
i1 #office1
for office in offices: #输出每个office人数和对应的老师print(office%d的人数为%d%(i,len(office)))i 1 #遍历officesfor name in office:print(%s%name,end\t) #打印每个office老师的名字print(\n) #打印完一个office换行print(-*20) #打印完一个office输出20个-6 元组-Tuple 元组与列表类似不同之处在于元组的元素不能修改。 元组使用小括号列表使用方括号。 6.1 元组定义
tup1() #空元组
tup2(5) #class int 不是元组
tup2(5,) #class tuple
tup3 (Google, Python, 1997, 2000)6.2 元组元素切片
tup(1,2,3)
print(tup[0]) #第一个元素 #output: 1
print(tup[-1]) #最后一个元素 #output: 3
print(tup[0:2]) #左闭右开[0,2) #output: (1, 2)6.3 元组元素增加(连接)
tup1 (12,34,56)
tup2 (ab,cd,ef)
tup3 tup1tup2
print(tup3) #(12, 34, 56, ab, cd, ef)6.4 元组元素删除
tup1 (12,34,56)
#del tup1[0] #不允许删除单个元素
del tup1 #删除了整个元组变量6.5 元组元素不能修改
tup1 (12,34,56)
tup1[0] 72 #报错 不能修改7 字典-dict 字典使用键值对(keyvalue)存储键必须是唯一的但值则不必。 7.1 字典定义
dict {key1 : value1, key2 : value2 }
info {name:简简,age:18}7.2 字典访问
info {name:简简,age:18}
print(info[name])
print(info[age])#访问不存在键
print(info[sex]) #直接访问不存在的键会报错
print(info.get(sex)) #使用get()方法访问不存在的键默认返回none
print(info.get(sex,没有)) #没有找到的时候返回自定义值 #output 没有7.3 字典键值增加
info {name:简简,age:18}
info[sex]man #新增sex
print(info) #output: {name: 简简, age: 18, sex: man}7.4 字典键值删除
#del
info {name:简简,age:18}
del info[name] #删除name键值对
print(info) #output: {age: 18}del info #删除整个字典
print(info) #output: NameError: name info is not defined#clear
info {name:简简,age:18}
info.clear() #清空字典内键值对
print(info) #output: {}7.5 字典键值修改
info {name:简简,age:18}
info[age]20
print(info)7.6 字典键值查找
info {name:简简,age:18}
print(info.keys()) #得到所有的键 #output: dict_keys([name, age])
print(info.values()) #得到所有的值 #output: dict_values([简简, 18])
print(info.items()) #得到所有的键值对 #output: dict_items([(name, 简简), (age, 18)])#遍历所有的键
for key in info.keys():print(key) #output: name age#遍历所有的值
for value in info.values():print(value) #output: 简简 18#遍历所有的键值对
for key,value in info.items():print((key%s,value%s)%(key,value))
#output: (keyname,value简简) (keyage,value18)8 函数
8.1 函数定义和使用
def printinfo(a,b): #函数定义c a bprint(c)printinfo(1,2) #函数的使用8.2 带返回值的函数
def info(a,b):c a breturn c #返回值print(info(1,2)) 8.3 返回多个值的函数
def divid(a,b):shang a//byushu a%breturn shang,yushu #多个返回值用逗号隔开sh,yu divid(5,2) #需要用多个值来保存返回内容
print(商%d 余数:%d%(sh,yu))9 文件操作
9.1 打开文件(open)
用法对象open(文件名访问模式)
f open(test.txt, w)模式说明r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。w打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在创建新文件。a打开一个文件用于追加。如果该文件已存在文件指针将会放在文件的结尾。也就是说新的内容将会被写入到已有内容之后。如果该文件不存在创建新文件进行写入。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。wb以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在创建新文件。ab以二进制格式打开一个文件用于追加。如果该文件已存在文件指针将会放在文件的结尾。也就是说新的内容将会被写入到已有内容之后。如果该文件不存在创建新文件进行写入。r打开一个文件用于读写。文件指针将会放在文件的开头。w打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在创建新文件。a打开一个文件用于读写。如果该文件已存在文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在创建新文件用于读写。rb以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。wb以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在创建新文件。ab以二进制格式打开一个文件用于追加。如果该文件已存在文件指针将会放在文件的结尾。如果该文件不存在创建新文件用于读写。
9.2 关闭文件(close)
用法对象.close()
f.close()9.3 写数据(write)
用法对象.write()
fopen(test.txt,w) # 打开文件w(写模式)-文件不存在就在当前路径给你新建一个
f.write(hello,world) # write将字符写入文件
f.close()9.4 读数据(read)
用法对象.read()
fopen(test.txt,r) #打开文件r(读模式)
contentf.read(5) #read读取5个字符
print(content)
f.close()9.5 读一行数据(readline)
用法对象.readline()
f open(test.txt, r)
content f.readline()
print(1:%s%content)#读取一行
content f.readline()
print(2:%s%content)#再读下一行
f.close()9.6 读多行数据(readlines)
用法对象.readlines()
fopen(test.txt,r) #打开文件r(读模式)
contentf.readlines() #readlines读取整个文件以列表形式输出
print(content) #输出形式为列表 #output: [hello,world\n, hello,world]#对列表进行处理按序号一行一行输出
i1
for temp in content:print(%d:%s % (i, temp))i 1 #output: 1:hello,world 2:hello,world
f.close() 9.7 OS模块
使用该模块必须先导入模块 import osos模块中的函数:
序号函数名称描述格式1getcwd()获取当前的工作目录格式os.getcwd() 返回值路径字符串2chdir()修改当前工作目录格式:os.chdir() 返回值:None3listdir()获取指定文件夹中的 所有文件和文件夹组成的列表格式:os.listdir(目录路径) 返回值目录中内容名称的列表4mkdir()创建一个目录/文件夹格式os.mkdir(目录路径) 返回值None5makedirs()递归创建文件夹格式:os.makedirs(路径)6rmdir()移除一个目录必须是空目录格式os.rmdir(目录路径) 返回值:None7removedirs()递归删除文件夹格式os.removedirs(目录路径) 返回值None 注意最底层目录必须为空8rename()修改文件和文件夹的名称格式os.rename(源文件或文件夹目标文件或文件夹) 返回值None9stat()获取文件的相关 信息格式os.stat(文件路径) 返回值包含文件信息的元组10system()执行系统命令格式:os.system() 返回值整型 慎用 玩意来个rm -rf 你就爽了11getenv()获取系统环境变量格式os.getenv(获取的环境变量名称) 返回值字符串12putenv()设置系统环境变量格式os.putenv(‘环境变量名称’,值) 返回值无 注意无法正常的getenv检测到。13exit()推出当前执行命令直接关闭当前操作格式:exit() 返回值无
10 异常处理
10.1 异常简介 print -----test--1--- open(123.txt,r) print -----test--2---打开一个不存在的文件123.txt当找不到123.txt 文件时就会抛出给我们一个IOError类型的错误No such file or directory123.txt 没有123.txt这样的文件或目录 10.2 捕获异常
try:print(-----test--1---) open(123.txt,r) print(-----test--2---)
except IOError:pass此程序看不到任何错误因为用except 捕获到了IOError异常并添加了处理的方法 pass 表示实现了相应的实现但什么也不做如果把pass改为print语句那么就会输出其他信息 总结 把可能出现问题的代码放在try中 把处理异常的代码放在except中
try:print num
except IOError:print(产生错误了)上例程序已经使用except来捕获异常但是还会看到错误的信息提示 except捕获的错误类型是IOError而此时程序产生的异常为 NameError 所以except没有生效 try:print num
except NameError:print(产生错误了)Python的一些內建异常
异常描述Exception常规错误的基类AttributeError对象没有这个属性IOError输入/输出操作失败IndexError序列中没有此索引(index)KeyError映射中没有这个键NameError未声明/初始化对象 (没有属性)SyntaxErrorPython 语法错误TypeError对类型无效的操作ValueError传入无效的参数ZeroDivisionError除(或取模)零 (所有数据类型)
10.3 捕获多个异常
#codingutf-8
try:print(-----test--1---)open(123.txt,r) # 如果123.txt文件不存在那么会产生 IOError 异常 print(-----test--2---)print(num)# 如果num变量没有定义那么会产生 NameError 异常except (IOError,NameError):#如果想通过一次except捕获到多个异常可以用一个元组的形式10.4 获取异常的信息描述 10.5 try…finally… 在程序中如果一个段代码必须要执行即无论异常是否产生都要执行那么此时就需要使用finally。 比如文件关闭释放锁把数据库连接返还给连接池等 import time
try:f open(test.txt)try:while True:content f.readline()if len(content) 0:breaktime.sleep(2)print(content)except:#如果在读取文件的过程中产生了异常那么就会捕获到 #比如 按下了 ctrlcpassfinally:f.close()print(关闭文件)
except:print(没有这个文件)test.txt文件中每一行数据打印但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候按Ctrlc中断取消程序。 我们可以观察到KeyboardInterrupt异常被触发程序退出。但是在程序退出之前finally从句仍然被执行把文件关闭。
11 Python知识
除法
除 /整除 //求余 %商和余数的元组 divmod
移位操作
左移
a左移 n 位相当于原操作数乘以 2^n原操作数不发生变化。 31 # 向右移动一位相当于是乘以2
6 -32 # 向右移动一位相当于是乘以4
-12右移
an则a a//(2^n)左移 n 位相当于原操作数整除 2^n原操作数不发生变化。 21 # 移动一位相当于是2//2
1 22 # 相当于先左移一位得到1结果1再除以2等于0
023 # 相当于2//8
0 -82 # 移动2位相当于-8//4
-2-83 # 移动3位相当于是用结果-2再除以2
-1-84 # 移动4位相当于是用结果-1再除以2
-1如果操作数是正数那么对之不停进行右移操作最终结果一定可以得到 0如果操作数是负数对之不停进行右移操作最终结果一定可以得到 -1。
匿名函数lambda
匿名函数 lambda 是指一类无需定义标识符函数名的函数或子程序。 lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。
语法
lambda [arg1,arg2,.....argn]:expression冒号前是参数可以有多个用逗号隔开冒号右边的为表达式只能为一个。其实lambda返回值是一个函数的地址也就是函数对象。
lambda arg: print(hello,world,arg)lambda表达式限制只能包含一行代码但是其实可以利用元组或列表强行让其包含多行。但是这么做会严重影响可读性除非万不得已不要使用
lambda :(print(hello),print(world),
)切片 t[1,2,3,4,5]print(t[1:]) 取第二个到最后一个元素
结果[2 3 4 5]print(t[:]) 取所有元素
结果[1 2 3 4 5]print(t[1:3]) 取t[1]-t[2]
结果[ 2 3 ]print(t[:-1]) 除了最后一个取全部
结果[ 1 2 3 4 ]print(t[::-1]) 取从后向前相反的元素
结果[ 5 4 3 2 1 ]print(t[2::-1]) 取从下标为2的元素翻转读取
结果[ 3 2 1 ]字符串方法
join(iterable) 获取可迭代对象(iterable)中的所有项目并将它们连接为一个字符串。 实例1
myTuple (Bill, Steve, Elon)
x #.join(myTuple)
print(x)
输出
Bill#Steve#Elon实例2
myDict {name: Bill, country: USA}
mySeparator TEST
x mySeparator.join(myDict)
print(x)
输出
nameTESTcountry注释在使用字典作为迭代器时返回的值是键而不是值。
split(separator, max) 将字符串拆分为列表您可以指定分隔符默认分隔符是任何空白字符。若指定 max列表将包含指定数量加一的元素。 实例1
txt welcome to China
x txt.split()
print(x)
输出
[welcome, to, China]实例2
txt apple#banana#cherry#orange
# 将 max 参数设置为 1将返回包含 2 个元素的列表
x txt.split(#, 1)
print(x)
输出
[apple, banana#cherry#orange]内置函数
enumerate() 用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列同时列出数据和数据下标一般用在 for 循环当中。 实例1
seq [one, two, three]for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three实例2
seasons [Spring, Summer, Fall, Winter]list(enumerate(seasons))
[(0, Spring), (1, Summer), (2, Fall), (3, Winter)]list(enumerate(seasons, start1)) # 下标从 1 开始
[(1, Spring), (2, Summer), (3, Fall), (4, Winter)]exec() exec 执行储存在字符串或文件中的 Python 语句相比于 evalexec可以执行更复杂的 Python 代码。 # 单行语句字符串
exec(print(Hello World))
Hello World# 多行语句字符串exec (for i in range(5):
... print (iter time: %d % i)
... )
iter time: 0
iter time: 1
iter time: 2
iter time: 3
iter time: 4二、Python爬虫 下面的学习方式是以爬取豆瓣top250 网页进行开展的 基本流程: 爬取网页—解析数据—保存数据 1 requests库 Requests是一个简单方便的HTTP 库。比Python标准库中的urllib2模块功能强大。Requests 使用的是 urllib3因此继承了它的所有特性。Requests 支持使用cookie 保持会话支持文件上传支持自动确定响应内容的编码支持URL 和 POST 数据自动编码。帮助我们轻松解决关于HTTP的大部分问题。 爬取网页首先要学习requests库或者urllib库的使用,不然你无法看懂下面代码
2 爬取网页
2.1 爬取豆瓣top250第一页数据
#-*- coding utf-8 -*-
import requestsdef askUrl(url):head { #模拟浏览器头部信息向豆瓣服务器发送消息User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36 Edg/81.0.416.34# 用户代理告诉豆瓣服务器我们是什么类型的浏览器本质上是告诉浏览器我们可以接收什么水平的文件内容}html #用来接收数据r requests.get(url, headers head) #get方式发送请求html r.text #接收数据print(html) return htmlif __name__ __main__: # main函数用于测试程序askUrl(https://movie.douban.com/top250?start) #调用函数可以看到成功的爬取到豆瓣top250第一页的数据 2.2 爬取豆瓣top250前10页数据
#-*- coding utf-8 -*-
import requests#爬取一个页面
def askUrl(url):head { #模拟浏览器头部信息向豆瓣服务器发送消息User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.69 Safari/537.36 Edg/81.0.416.34# 用户代理告诉豆瓣服务器我们是什么类型的浏览器本质上是告诉浏览器我们可以接收什么水平的文件内容}#htmlr requests.get(url, headers head)html r.textprint(html)# 爬取所有页面
def getData(baseurl):for i in range(0, 10):url baseurl str(i * 25)html askUrl(url)if __name__ __main__: # main函数用于测试程序baseurl https://movie.douban.com/top250?startgetData(baseurl)可以看到排名250的梦之安魂曲也被成功爬取到 image-20200327115150029
3 BeautifulSoup4库 BeautifulSoup4和 lxml 一样Beautiful Soup 也是一个HTML/XML的解析器主要的功能也是如何解析和提取 HTML/XML 数据。 假设有这样一个baidu.html放在py文件目录下下面的例子都基于该html,具体内容如下
!DOCTYPE html
html
headmeta contenttext/html;charsetutf-8 http-equivcontent-type /meta contentIEEdge http-equivX-UA-Compatible /meta contentalways namereferrer /link hrefhttps://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css relstylesheet typetext/css /title百度一下你就知道 /title
/head
body link#0000ccdiv idwrapperdiv idheaddiv classhead_wrapperdiv idu1a classmnav hrefhttp://news.baidu.com nametj_trnews!--新闻--/aa classmnav hrefhttp://news.baidu.com nametj_trnews新闻/aa classmnav hrefhttps://www.hao123.com nametj_trhao123hao123/aa classmnav hrefhttp://map.baidu.com nametj_trmap地图/aa classmnav hrefhttp://v.baidu.com nametj_trvideo视频/aa classmnav hrefhttp://tieba.baidu.com nametj_trtieba贴吧/aa classbri href//www.baidu.com/more/ nametj_briicon styledisplay: block;更多产品 /a/div/div/div/div
/body
/html3.1 快速使用案例
# 导入模块
from bs4 import BeautifulSoup# 读取html文件信息在真实代码中是爬取的网页信息
file open(./baidu.html,rb) #解析器
content f.read()
f.close()# 创建解析器
bs BeautifulSoup(content,html.parser)# 输出网页内容注此内容已被缩进格式化自动更正格式其实这个是在上一步实例化时就已完成
print(bs)#输出网页中title标签中的内容
print(bs.title.string)3.2 BeautifulSoup4主要解析器
解析器使用方法优势劣势Python标准库BeautifulSoup(markup, “html.parser”)Python的内置标准库执行速度适中文档容错能力强Python 2.7.3 or 3.2.2前的版本中文档容错能力差lxml HTML 解析器BeautifulSoup(markup, “lxml”)速度快 文档容错能力强需要安装C语言库lxml XML 解析器BeautifulSoup(markup, [“lxml-xml”]) BeautifulSoup(markup, “xml”)速度快 唯一支持XML的解析器需要安装C语言库html5libBeautifulSoup(markup, “html5lib”)最好的容错性以浏览器的方式解析文档生成HTML5格式的文档速度慢、不依赖外部扩展
3.2 BS4四大对象种类 BeautifulSoup4将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种 TagNavigableStringBeautifulSoupComment
3.2.1 Tag Tag通俗点讲就是为了获取HTML中的一个个标签 from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) # 获取title标签的所有内容
print(bs.title) #title百度一下你就知道 /title# 获取head标签的所有内容
print(bs.head) # 获取第一个a标签的所有内容
print(bs.a) # 类型
print(type(bs.a)) # class bs4.element.Tag#bs 对象本身比较特殊它的 name 即为 [document]
print(bs.name) # [document]# head #对于其他内部标签输出的值便为标签本身的名称
print(bs.head.name) # head# 获取a标签里的所有属性打印输出来得到的类型是一个字典。
print(bs.a.attrs)
# {class: [mnav], href: http://news.baidu.com, name: tj_trnews}#还可以利用get方法传入属性的名称二者是等价的
print(bs.a[class]) # 等价 bs.a.get(class) # 可以对这些属性和内容等等进行修改
bs.a[class] newClass
print(bs.a) # 还可以对这个属性进行删除
del bs.a[class]
print(bs.a)3.2.2 NavigableString 既然我们已经得到了标签的内容那么问题来了我们要想获取标签内部的文字怎么办呢很简单用 .string 即可例如 from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #获取title标签中的字符串
print(bs.title.string) #百度一下你就知道 # 类型
print(type(bs.title.string))
#class bs4.element.NavigableString3.3.3 BeautifulSoup BeautifulSoup对象表示的是一个文档的内容。大部分时候可以把它当作 Tag 对象是一个特殊的 Tag我们可以分别获取它的类型名称以及属性例如 from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #获取整个文档
print(bs)print(type(bs)) #class bs4.BeautifulSoup3.3.4 Comment Comment 对象是一个特殊类型的 NavigableString 对象其输出的内容不包括注释符号。 from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) print(bs.a)
# a标签如下
# a classmnav hrefhttp://news.baidu.com nametj_trnews!--新闻--/aprint(bs.a.string) # 新闻 #不会输出上面a标签中的注释符号print(type(bs.a.string))
# class bs4.element.Comment3.3 遍历文档数
.contents获取Tag的所有子节点返回一个list
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) print(bs.head.contents) #获取head下面的所有直接子节点返回列表
print(bs.head.contents[1 #用列表索引来获取它的某一个元素.children获取Tag的所有子节点返回一个生成器
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) for child in bs.body.children:print(child).descendants获取Tag的所有子孙节点.strings如果Tag包含多个字符串即在子孙节点中有内容可以用此获取而后进行遍历.stripped_strings与strings用法一致只不过可以去除掉那些多余的空白内容.parent获取Tag的父节点.parents递归得到父辈元素的所有节点返回一个生成器.previous_sibling获取当前Tag的上一个节点属性通常是字符串或空白真实结果是当前标签与上一个标签之间的顿号和换行符.next_sibling获取当前Tag的下一个节点属性通常是字符串或空白真是结果是当前标签与下一个标签之间的顿号与换行符.previous_siblings获取当前Tag的上面所有的兄弟节点返回一个生成器.next_siblings获取当前Tag的下面所有的兄弟节点返回一个生成器.previous_element获取解析过程中上一个被解析的对象(字符串或tag)可能与previous_sibling相同但通常是不一样的.next_element获取解析过程中下一个被解析的对象(字符串或tag)可能与next_sibling相同但通常是不一样的.previous_elements返回一个生成器可以向前访问文档的解析内容.next_elements返回一个生成器可以向后访问文档的解析内容.has_attr判断Tag是否包含属性 3.4 文档的搜索find_all()
name参数
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #字符串过滤会查找与字符串完全匹配的内容
t_list bs.find_all(a)
t_list bs.find_all(title)
print(t_list)#正则表达式过滤如果传入的是正则表达式那么BeautifulSoup4会通过search()来匹配内容
import re
t_list bs.find_all(re.compile(a))
print(t_list)函数参数
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #定义函数传入一个函数根据函数的要求来搜索
def name_is_exists(tag):return tag.has_attr(name)#搜索包含name的标签t_list bs.find_all(name_is_exists)
for item in t_list: #打印列表内容print(item)keyword参数
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #搜索idhead的内容
t_list bs.find_all(idhead)
for item in t_list:print(item)#搜索classmanav的内容
t_list bs.find_all(class_mnav)
for item in t_list: print(item)#搜索链接的内容
t_list bs.find_all(hrefhttp://news.baidu.com)
for item in t_list: print(item)text参数
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) import re
#t_list bs.find_all(texthao123)
#t_list bs.find_all(text[hao123,贴吧,地图])
t_list bs.find_all(textre.compile(\d))#查找包含数字的文本
for item in t_list: print(item)limit 参数
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) t_list bs.find_all(a,limit3)
for item in t_list: print(item)3.5 css选择器
from bs4 import BeautifulSoup
file open(./baidu.html, rb)
content file.read()
bs BeautifulSoup(content,html.parser) #通过标签来查找
t_list bs.select(title) #通过类名.表示类来查找
t_list bs.select(.mnav)#通过id#表示id来查找
t_list bs.select(#u1)#通过属性来查找 查找a标签中classbri的内容
t_list bs.select(a[classbri]) #通过父子标签来查找
t_listbs.select(head title) #通过兄弟标签来查找
t_listbs.select(.mnav ~ .bri) for item in t_list: #打印列表内容print(item)
print(t_list[0].get_text()) #拿到t_list中的文本4 re库 正则表达式(Regular Expression)通常被用来匹配、检索、替换和分割那些符合某个模式(规则)的文本。 4.1 正则表达式常用操作符
操作符说明实例.表示除 “\n” 之外的任何单个字符。[ ]宇符集对单个字符给出取值范围[abc]表示a,b,c;[a-z]表示a到z单个字符[^ ]非字符集,对单个字符恰给出排除范围[^abc]表示非a或非b或c的单个字符*前一个字符0次或无限次扩展abc* 表示ab、abc、abcc、abcc等前一个字符1次或无限次扩展abc 表示abc、abcc、abcc等?前一个字符0次或1攻扩展abc? 表示ab、abc|左右表达式任意一个abc|def 表示abc、def扩展前一个字符m次ab(2}c表示abbc扩展前一个字符m至n次(含n)ab{1,2}c表示abc、abbc^匹配字符串开头^abc表示abc且在一个字符串的开头$匹配字符串结尾abc$表示abc且在一个字符串的结尾( )分组标记,内部只能使用|操作符(abc)表示abc ,(abc|def)表示abc、def\d数字,等价于[0-9]\w单词字符,等价于[A-Za-z0-9_ ]
4.2 re库常用函数
函数说明re.compile()返回一个正则对象的模式。re. search()在一个字符串中搜素匹配正则表达式的第一个位置 ,返回match对象re. match()从一个字符串的开始位置起匹配正则表达式,返回match对象re. findall()搜索字符串,以列表类型返回全部能匹配的子串re. split()将一个字符串按照正则表达式匹配结果进行分割,返回列表类型re. finditer()擅索字符串。返回一个匹配结果的迭代类型每个选代元素是match对象re. sub()在一个字符串中普换所有匹配正则表达式的子串,返回替换后的字符申
4.2.1 compile()
格式re.compile(pattern[,flags0])
pattern: 编译时用的表达式字符串。flags: 编译标志位用于修改正则表达式的匹配方式如re.I、re.S等
import re
patre.compile(A)
mpat.search(CBA) #等价于 re.search(A,CBA)
print(m)#re.Match object; span(2, 3), matchA 表示匹配到了mpat.search(CBD)
print(m) #None 表示没匹配到4.2.2 search()
在字符串中寻找模式格式re.search(pattern, string[, flags0])re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回如果字符串没有匹配则返回None。 import rem re.search(asd , ASDasd )print(m)# _sre.SRE_Match object at 0xb72cd6e8 #匹配到了返回MatchObjectTruem re.search(asd , ASDASD )print(m) #没有匹配到返回NoneFalse4.2.3 match()
在字符串开始处匹配模式格式re.match(pattern, string[, flags0])
import re
patre.compile( a )
print(pat.match( Aasd )) #输出Nonepatre.compile( A )
print(pat.match( Aasd )) #输出_sre.SRE_Match object; span(0, 1), matchA注match和search一旦匹配成功就是一个match object对象而match object对象有以下方法 group() 返回被 RE 匹配的字符串start() 返回匹配开始的位置end() 返回匹配结束的位置span() 返回一个元组包含匹配 (开始,结束) 的位置
4.2.3 findall()
列表形式返回匹配项格式re.findall(pattern, string[, flags0]) import re#前面字符串是规则正则表达式后面字符串是被校验的字符串print(re.findall(a,ASDaDFGAa)) #[a,a] #列表形式返回匹配到的字符串p re.compile(r\d)print(p.findall(o1n2m3k4))#执行结果如下#[1, 2, 3, 4]print(re.findall([A-Z],ASDaDFGAa))#[ A , S , D , D , F , G , A ] print(re.findall([A-Z],ASDaDFGAa))#[ ASD , DFGA ]pat re.compile([A-Za-z])print(pat.findall(ASDcDFGAa))#[ A , S , D , c , D , F , G , A , a ]4.2.4 re. split()
按照能够匹配的子串将string分割后返回列表。可以使用re.split来分割字符串如re.split(r’\s’, text)将字符串按空格分割成一个单词列表。格式re.split(pattern, string[, maxsplit]) maxsplit: 用于指定最大分割次数不指定将全部分割。
print(re.split(\d,one1two2three3four4five5))# 执行结果如下
# [one, two, three, four, five, ]4.2.5 finditer() 搜索string返回一个顺序访问每一个匹配结果Match对象的迭代器。 找到 RE 匹配的所有子串并把它们作为一个迭代器返回。 格式re.finditer(pattern, string[, flags0]) import re
iter re.finditer(r\d,12 drumm44ers drumming, 11 ... 10 ...)
for i in iter:print(i)print(i.group())print(i.span())
# 执行结果如下
_sre.SRE_Match object; span(0, 2), match12
12
(0, 2)
_sre.SRE_Match object; span(8, 10), match44
44
(8, 10)
_sre.SRE_Match object; span(24, 26), match11
11
(24, 26)
_sre.SRE_Match object; span(31, 33), match10
10
(31, 33)4.2.6 sub() 格式re.sub(pattern, repl, string, count) 用repl替换 pattern匹配项 import re
print(re.sub(a,A,abcasd)) #找到a用A替换后面见和group的配合使用
#AbcAsd #第四个参数指替换个数。默认为0表示每个匹配项都替换。text JGood is a handsome boy, he is cool, clever, and so on...
print(re.sub(r\s, -, text)) #\s:空格
#JGood-is-a-handsome-boy,-he-is-cool,-clever,-and-so-on...4.3 模式修正符 所谓模式修正符即可以在不改变正则表达式的情况下通过模式修正符改变正则表达式的含义从而实现一些匹配结果的调整等功能。 修饰符描述re.I使匹配对大小写不敏感re.L做本地化识别locale-aware匹配re.M多行匹配影响 ^ 和 $re.S使 . 匹配包括换行在内的所有字符re.U根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
import re
string Python
pat pyt
rst re.search(pat,string,re.I) # 第三个参数
print(rst)#_sre.SRE_Match object; span(0, 3), matchPyt