博客cpen_web
练习1
1、电子邮箱验证(username@domain-inc.com)
·username长度6-18之间,则字母、数字、下划线组成
·domain-inc由字母、数字、中划线组成
示例
import re
msg = input("请输入email:")
if re.findall(r"^\w{6,18}@[A-Za-z0-9\-]+\.com$", msg):
print("yes")
else:
print("no")
2、从左往右依次匹配
示例
import re
msg = 'san chuang tong le, huan ying ni "hello world", learn python'
ret = re.findall(r'\w+|"[\w ]+', msg) # 注:不是零宽断言 匹配到引号
print(ret)
#结果为 ['san', 'chuang', 'tong', 'le', 'huan', 'ying', 'ni', '"hello world', 'learn', 'python']
ret = re.findall(r'\w+|(?<=")(?:[\w ]+)(?=")', msg) # 注:这种写法 先匹配\w+
print(ret)
#结果为 ['san', 'chuang', 'tong', 'le', 'huan', 'ying', 'ni', 'hello', 'world', 'learn', 'python']
ret = re.findall(r'(?<=\")(?:[\w ]+)(?=")|\w+', msg) # 注:匹配到引号时发现 前面没引号 后面也没有引号
print(ret) # 注:解决问题了 因为断言先行 每次匹配先匹配零宽断言的;引号不占用匹配宽度,仅仅只是占有位置
#结果为 ['san', 'chuang', 'tong', 'le', 'huan', 'ying', 'ni', 'hello world', 'learn', 'python']
3、抓取任意站点,将所有的图片下载到本地
豆瓣电影首页的图片()
前置知识:urllib或requests模块
示例1:curl命令
[root@sanchuang-linux ~]# curl "https://movie.douban.com/" # 注:curl命令模拟请求
% Total % Received % Xferd Average Speed Time Time Time Current
……………………………
<html lang="zh-CN" class="">…………………………
</title>
[root@sanchuang-linux ~]# curl "https://movie.douban.com/" &> /tmp/douban #注:将内容写入文件
[root@sanchuang-linux ~]# less /tmp/douban
% Total % Received % Xferd Average Speed Time Time Time Current
……………………………
<html lang="zh-CN" class="">…………………………
</title>
示例2:对称差集
>>> s = {1,2,3,4}
>>> t = {3,4,5,6}
>>> s-t # 注:差集
{1, 2}
>>> s^t # 注:对称差集
{1, 2, 5, 6}
print(set(ret) ^ set(a))
#结果为 {'/uploads/allimg/170812/1-1FQ2154ZW47.jpg', ………………'/uploads/allimg/170812/1-1FQ2154641G8.jpg', '/uploads/allimg/170812/1-1FQ2152ZUX.jpg'}
#结果为 set()
示例3
方法1
#正则表达式练习
import re
import requests
ws = requests.get('https://www.sucai8.com/') # 注:requests获取请求
# print(ws.text) # 注:获取内容
#结果为<html xmlns="http://www.w3.org/1999/xhtml">
#<head>…………………………
#ret = re.findall(r'<img.*(?<=src=")(.+(?:\.jpg))(?=")',ws.text,re.M) # 注:写错了<img.*贪婪匹配一直匹配 出错
ret = re.findall(r'<img.*?(?<=src=")(.+?(?:\.jpg))(?=")',ws.text,re.M) # 注:<img.*?非贪婪匹配
# imglist = re.findall(r'(?<=<img)(?:.+?src=")(.+?.jpg)', html,re.M) #
p = []
for i in ret:
if i.startswith("http"):
p.append(i)
else:
j = "https://www.sucai8.com"+i
p.append(j)
print(p)
print(len(p)) # 注:结果为 19
#结果为 ['https://www.sucai8.com/uploads/allimg/170812/1-1FQ2143HS18.jpg', ……'https://www.sucai8.com/uploads/allimg/170817/1-1FQG405560-L.jpg']
方法2:将文件下载到本地
import re
import requests # 注:贪婪匹配 非贪婪匹配 +*? 或者{n,m}
ret1 = requests.get("https://www.sucai8.com") # 注:非贪婪匹配 在* + 后 加 ? 号
a = re.findall(r"(?:src=\")(.*?\.(?:jpg))",ret1.text) # 注:?:jpg 为了元组只有1个元素
# imglist = re.findall(r'(?<=<img)(?:.+?src=")(.+?.jpg)', html,re.M) #
print(a)
# b = re.findall(r"(?:\<a)")
for i in range(len(a)):
try:
ret = requests.get(url = f"{a[i]}")
print(ret.url)
with open(f"E:/hxli/{i}.jpg","wb") as f:
f.write(ret.content)
except Exception as af:
ret = requests.get(url = f"http:{a[i]}")
print(ret.url)
with open(f"E:/hxli/{i}.jpg","wb") as f:
f.write(ret.content)
ret = re.findall(r'<img.*?(?<=src=")(.+?(?:\.jpg))(?=")',ws.text,re.M) # 注:推荐
a = re.findall(r"(?:src=\")(.*?\.(?:jpg))",ret1.text) #注:没有img标签
imglist = re.findall(r'(?<=<img)(?:.+?src=")(.+?.jpg)', html,re.M)#注:写法没错,是匹配的内容错了
imglist = re.findall(r'(?<=<img)(?:.+?src=")(.+?.jpg)', ws.text,re.M) #
print(imglist)
ret = re.findall(r'<img.*?(?<=src=")(.+?(?:\.jpg))(?=")',ws.text,re.M)
print(ret)
a = re.findall(r"(?:src=\")(.*?\.(?:jpg))",ws.text,re.M)
print(ret)
#结果都是 #['/uploads/allimg/170812/1-1FQ2152ZUX.jpg''/uploads/allimg/170817/1-1FQG405560-L.jpg']
4、获取a标签 href 网址
示例
import re
import requests
ws = requests.get('https://www.sucai8.com')
b = re.findall(r"(?:<a href=\")(.+?)(?:\")",ws.text) # 注:核心
p = []
for i in range(len(b)):
if b[i][0] == "/":
p.append("https://www.sucai8.com/"+b[i])
elif b[i][0] == "h":
p.append(b[i])
else:
pass
print(len(set(p))) # 注:去重
ret2 = re.findall(r'(?:<a.*?(?<=href=\"))([/h].*?)(?=\")',ws.text,re.M) # 注:核心
print(len(set(ret2)))
#结果都是 45个
知识点2 高阶函数
高阶函数
·把函数作为参数传入,这样的函数称为高阶函数,
示例
# 高阶函数
# 把函数作为参数传入,这样的函数称为高阶函数
def func01(a, b):
print(f"{a} {b}")
func01("x", "y") # 注:函数的调用;位置参数一一对应
func01(b = "bb", a = "aa") # 注:关键字参数;参数的传递和接收的位置不需要一一对应;Key=value的形式传参
#结果为 x y
#aa bb
def func02(func,a,b): # 注:把函数作为参数传递;func02称为高阶函数
print("start func......")
func(a,b)
func02(func01,"x","y")
#结果为 start func......
#x y
# def func02(func):
# print("start func......")
# func()
# func02(func01)
# 注:报错:func01缺少2个位置的位置参数
知识点3 常用高阶函数-map
用Python-map代码实现:f(x)=x*x
·内置函数map,map()函数接收两个参数,一个是函数,一个是Iterable(可多个),
·map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
用Python-map代码实现:f(x)=x*x
·map()传入的第一个参数是f,即函数对象本身。
·由于结果r是一个Iterator,Iterator是惰性序列。
·可通过list()函数让它把整个序列都计算出来并返回一个list。
实现方式比较
·map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x**2,还可以计算任意复杂的函数
示例1
# map 映射
def func(item): # 接收1个参数item
return item*item # 返回数的平方
a = [1,2,3,4,5,6] # 注:a是可迭代对象
result = map(func, a)
print(result) # 注:返回 map对象
#结果为 <map object at 0x0000020EDE156970>
print(list(result))
#结果为 [1, 4, 9, 16, 25, 36]
#注:返回的是映射,按照func里面规定的方式做映射,再输出为1个map对象
#注:不可以直接获得map对象,可视化需要转换成list
#注:映射关系(一一对应)
#注:将可迭代对象里的每一个值 按照func来映射
#注:func默认1个参数,不能接收2个参数
a = [1,2,3,4,5,6]
result = map(lambda x:x*x, a) # 注:匿名函数;:前面接参数,后面接函数体
print(list(result))
#结果为 [1, 4, 9, 16, 25, 36]
示例2 保留2位小数
# 保留2位小数
b = [1.239865,4.56,3.2,9.82356]
#方法1
result = map(lambda x:'%.2f'%x, b)
print(list(result))
#结果为 ['1.24', '4.56', '3.20', '9.82']
#方法2
result = map(lambda x:round(x,2), b)
print(list(result))
#结果为 [1.24, 4.56, 3.2, 9.82]
示例3 转化为百分数,并且保留2位小数
#转化为百分数,并且保留2位小数
c = [0.000564, 0.456723, 0.5, 0.71345]
#方法1 forma函数
result = map(lambda x:format(x,'.2%'), c)
print(list(result))
#结果为 ['0.06%', '45.67%', '50.00%', '71.34%']
#方法2 x*100
result = map(lambda x:'%.2f%%'%(x*100), c)
print(list(result))
#结果为 ['0.06%', '45.67%', '50.00%', '71.34%']
练习4
有列表[1,2,3,4,5],将所有元素转换成str:[‘1’,‘2’,‘3’,‘4’,‘5’]
有列表字符串’span’,将各字符转换成对应的ascii码的列表[115, 112, 97, 109]
有列表[-1,-2,0,1,2],将各元素转换成绝对值[1, 2, 0, 1, 2]
示例
# 有列表[1,2,3,4,5],将所有元素转换成str:['1','2','3','4','5']
a = [1,2,3,4,5]
result = map(lambda x:str(x), a)
print(list(result))
# 有列表字符串'span',将各字符转换成对应的ascii码的列表[115, 112, 97, 109]
b = 'span'
result = map(lambda x:ord(x), b) # 注:内建函数ord()获取ascii编码
print(list(result))
# 有列表[-1,-2,0,1,2],将各元素转换成绝对值[1, 2, 0, 1, 2]
c = [-1,-2,0,1,2]
result = map(lambda x:abs(x), c) # 注:内建函数abs()获取绝对值
print(list(result))
知识点5 常用高阶函数-filter
用Python-filter代码实现:在一个list中,删掉偶数,只保留奇数
·Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列
·filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。 # 注:为True保留;为False丢弃
·注意到filter()函数返回的是一个Iterator,也就是一个惰性序列。
#filter 过滤
示例1 保留奇数
#filter 过滤
#保留奇数
a = [1,2,3,4,5,6,7,8]
def func01(x):
return x % 2 == 1 # 注:保留奇数;返回结果true\false
result = filter(func01, a)
print(list(result))
#结果为 [1, 3, 5, 7]
示例2 返回结果true\false
>>> 3 % 2 == 1
True
>>> 4 % 2 == 1
False
示例3 返回100以内的回数
# 返回100以内的回数 (不包括100)
# 回数 从左至右 和 从右至左 都是一样的
# b = range(1,100+1) # 注:不能判断 1-9
# def func02(x):
# return x%11 == 0
# result = filter(func02,b)
# print(list(result))
#结果为 [11, 22, 33, 44, 55, 66, 77, 88, 99]
b = range(1, 101) # 注:字符串反向切片
def func02(x):
return str(x) == str(x)[::-1]
result = filter(func02, b)
print(list(result))
#结果为 [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99]
示例4:过滤出 1-100 以内 开平方根 是整数的数
方法1:开平方后还在原列表里
# 过滤出 1-100 以内 开平方根 是整数的数
#math,sqrt
from math import sqrt
c = range(1, 101)
result = filter(lambda x:sqrt(x) in range(1, 101) , range(1, 101))
print(list(result)) # 注:开平方后的数还在 c 里面
#结果为 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
方法2:int取整
from math import sqrt
c = range(1, 101)
def func03(x): # 注:浮点数的取整
result = int(sqrt(x))
return result * result == x
>>> int(2.1)
2
>>> int(3.8)
3
方法3:isdigit 判断
>>> a = "1.2"
>>> a.isdigit()
False
>>> a = "2"
>>> a.isdigit()
True