前言

!!!注意:本系列所写的文章全部是学习笔记,来自于观看视频的笔记记录,防止丢失。观看的视频笔记来自于:哔哩哔哩武沛齐老师的视频:2022 Python的web开发(完整版) 入门全套教程,零基础入门到项目实战

概要:

  • 模块
  • 自定义模块(已经讲了)
  • 内置模块
  • shutil
  • re 正则表达式
  • 第三方模块
  • requests 模块
  • bs4 模块
  • 面向对象: 面向对象(Object-Oriented Programming),简称OOP,是一种编程范式,它使用“对象”来设计软件,这些对象包含了数据(属性)和可以操作这些数据的方法。面向对象的核心思想是将现实世界中的事物抽象成对象,通过对象之间的交互来实现软件功能。 面向对象编程具有以下几个基本特性:
  1. 封装(Encapsulation):封装是将对象的状态(属性)和行为(方法)结合在一起,并对外隐藏其内部实现细节的过程。通过使用访问修饰符(如public、private等)来控制对对象内部状态的访问,确保对象的完整性和安全性。
  2. 继承(Inheritance):继承是一种可以让一个类(子类或派生类)继承另一个类(父类或基类)属性和方法的机制。继承支持代码的重用,并能够建立类之间的层次关系,使得子类具有父类的所有特性,并且还可以添加或修改原有的行为。
  3. 多态(Polymorphism):多态是指允许使用子类的对象来替代父类的对象,从而在运行时确定具体调用哪个类的方法。多态性可以使得代码更加灵活和可扩展,同时也支持接口的实现,允许不同的对象对同一消息做出响应。

1 模块

1.1 自定义模块

  • py文件或者文件夹
  • from import
  • sys.path【运行的当前脚本的目录+系统内置模块的目录】
  • 自己的模块名不要和内置模块名冲突。
补充-主文件

主文件:就是程序的入口,只有执行这个主文件(.py文件),程序才能运行起来.

# 运行当前脚本时,__name__是python内部创建的一个变量 __name__ = "__main__"
# 如果当前的脚本是别人导入执行的,那么python会在这个脚本的内部创建__name__ = "module_name"
if __name__ == "__main__":  # 标志这个文件是主文件 
    ...
  • 标志:含有if __name__ == "__main__":的为主文件
  • 防止别人导入咱们的程序时执行程序。只有自己主动执行时才会执行程序。

1.2 内置模块

  • os
  • random
  • hashlib
  • json
  • time
  • datetime
1.2.1 shutil模块
  • 删除==文件夹==

[!IMPORTANT]

是删除文件夹 不是删除文件

import shutil

shutil.rmtree("xx/xxx/xxxx")
  • 拷贝文件夹
import shutil

shutil.copytree("原文件夹", "目标文件夹路径")  # 没有文件夹会自动创建
import shutil
shutil.copytree(r"D:/tree", r"D:/xx/xxx/xxxx")
  • 拷贝文件
import shutil

shutil.copy("源文件路径", "目标文件夹路径")
import shutil
shutil.copytree(r"D:/tree/xxx.txt", r"D:/xx/xxx/xxxx")  # 如果不存在xxxx,那么创建一个较xxxx的文件(这个文件没有后缀)
shutil.copytree(r"D:/tree/xxx.txt", r"D:/xx/xxx/xxxx/")  # 拷贝文件到文件夹 文件夹要是不存在会报错
  • 重命名文件/文件夹
import shutil

shutil.move("原来的文件名/文件夹名", "改变名字之后的文件名/文件夹名")  # 源文件不存在会报错 源文件夹不存在也会报错
  • 压缩、解压缩
import shutil

# 压缩
# base_name: 压缩包文件名 format: 后缀名 root_dir: 要压缩到的文件夹路径
shutil.make_archive(base_name="xx", format="zip", root_dir="xx/xxx/xxxx/")

# 解压
# filename: 压缩包文件名 extract_dir: 解压目录 format: 压缩的格式
shutil.unpack(filename="xx.zip", extract_dir="xx/xxx/xxxx/", format="zip")

练习题:目录层级如下所示

day01
	01 fullstack s7 day01 xxx.mp4
    02 fullstack s7 day01 xxx.mp4
    03 fullstack s7 day01 xxx.mp4
    04 fullstack s7 day01 xxx.mp4
    xxxx.md

寻找day01目录下的所有mp4为后缀的文件 重命名为

04 fullstack s7 day01 xxx.mp4 -> 01 xxx.mp4

import os
import shutil

folder_path = r"D:\CSProjects\PycharmProjects\studyProject\wupeiqiStudyBilibili\day07\day01"

for name in os.listdir(folder_path):
    if name.rsplit(".", maxsplit=1)[-1] == "mp4":  # 参数“.”表示从右边(rsplit)分割 maxsplit=1表示分割右边第一个点
        new_name = name.replace("fullstack s7 day01 ", "")
        shutil.move(os.path.join(folder_path, name), os.path.join(folder_path, new_name))
1.2.2 re模块
  • 正则表达式?【与语言无关】
  • python中的re模块

正则表达式是干什么的?

text = """正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。正则表达式是对字符串(包括普通字符和特殊字符)操作的一种逻辑公式,就是用事先定义好的一些特定字符以及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式用来检索、替换那些符合某个模式(规则)的文本,通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提取字符串等等,许多程序设计语言都支持利用正则表达式进行字符串操作。楼主:瑾瑜,电话 18866666666,邮箱: 12345679@163.com。求点赞求转发,求一键三连!!!"""

# 需求:将字符串中的邮箱提取出来 / 手机号
# 手机号特征: 1[3|5|8|9]\d{9}    ->  正则表达式规则
import re

re_str = "1[3|5|8|9]\d{9}"


text = """正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,
包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。正则表达式是对字符串(包括普
通字符和特殊字符)操作的一种逻辑公式,就是用事先定义好的一些特定字符以及这些特定字符的组合,组成一个“规则字符串”,这
个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式用来检索、替换那些符合某个模式(规则)的文本,通常被用来检索、
替换那些符合某个模式(规则)的文本。正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提
取字符串等等,许多程序设计语言都支持利用正则表达式进行字符串操作。楼主:瑾瑜,电话 18866666666,邮箱: 12345679@163.com。
求点赞求转发,求一键三连!!!"""

phone_number = re.findall(re_str, text)

print(phone_number)  # 18866666666

提取邮箱

\w+@\w+.\w+
1.2.2.1 字符相关
  • 固定文本
import re

text = "你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 打倒美帝国主义纸老虎 日本鬼子不得豪斯"

data_list = re.findall("computer", text)  # ['computer']
  • 匹配字符
import re

text = "你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 打倒美帝国主义纸老虎 日本鬼子不得豪斯 祝没有真心反对日本核污水拍害的日本人全都收到核辐射而死 hahaha 耶"

data_list = re.findall("[abc]", text)  # 找 a b c 从前向后找
# ['b', 'b', 'b', 'c', 'c', 'c', 'c', 'a', 'a', 'a']
import re

text = "你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 打倒美帝国主义纸老虎 日本鬼子不得豪斯 祝没有真心反对日本核污水拍害的日本人全都收到核辐射而死 hahaha 耶"

data_list = re.findall("h[abc]", text)  # 找 ha hb hc 从前向后找
# ['ha', 'ha', 'ha']
  • 字符范围 a-z 0-9
import re

text = """你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 
打倒美帝国主义纸老虎 日本鬼子不得豪斯 祝没有真心反对日本核污水拍害的日本人全都收到核辐射而死 hahaha 耶 2024年3月10日"""

data_list = re.findall("[a-z]", text)  # 按照范围找
"""['b', 'i', 'u', 'b', 'i', 'u', 'b', 'i', 'u', 'c', 'o', 'm', 'p', 'u', 't', 'e', 'r', 's', 'c', 'i', 'e', 'n', 'c', 'e', 'g', 'o', 'o', 'd', 'm', 'o', 'r', 'n', 'i', 'n', 'g', 'l', 'o', 'n', 'g', 'r', 'c', 'h', 'a', 'h', 'a', 'h', 'a']"""
  • \d -- 代表一个数字
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d", text)  # \d代表数字
print(data_list)  # ['1', '3', '4', '4', '2', '3', '4', '1', '6', '2', '3', '4']
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d+", text)  # + 代表1个或者n个
print(data_list)
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d*", text)  # * 代表0个或者n个
print(data_list)
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d?", text)  # ? 代表0个或者1个  意思是只拿0个或1个(不管后面本来有多少个)
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d{2}", text)  # {n} 固定n个
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d{2,}", text)  # {n,} 固定n个,或者比n个更多
import re

text = """root-ad13main-c4ompu423416ter science-aad234main"""

data_list = re.findall(r"\d{2, 4}", text)  # {n, m} 固定n个到m个之间   :  n个 <= 个数 <= m个
  • \w -- 字母 数字 下划线 (包括汉字) 不匹配空格!
import re

text = """你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 
打倒美帝国主义纸老虎 日本鬼子不得豪斯 祝没有真心反对日本核污水拍害的日本人全都收到核辐射而死 hahaha 耶 2024年3月10日"""

data_list = re.findall("计算机\w+技术", text)  # 尽可能多的去匹配  -- 贪婪匹配 默认是贪婪的
print(data_list)  # ['计算机科学与技术']
import re

text = """你好巴拉巴拉 biubiubiu computer science good morning longArc架构 计算机科学与技术 华为牛逼 
打倒美帝国主义纸老虎 日本鬼子不得豪斯 祝没有真心反对日本核污水拍害的日本人全都收到核辐射而死 hahaha 耶 2024年3月10日"""

data_list = re.findall("计算机\w+?技术", text)  # 尽可能少的去匹配  -- 非贪婪匹配
print(data_list)  # ['计算机科学与技术']

[!Caution]

"计算机\w+?技术"这个正则表达式表示的是非贪婪匹配非贪婪匹配:在一个匹配数量的语法后面添加一个?代表非贪婪匹配。

正则默认是贪婪匹配,加一个?那么就是非贪婪匹配。

  • . 除换行符以外的任意字符(一个)
import re

text = "computerscience admain root"
data_list = re.findall("r.o", text)  # 贪婪
print(data_list)  # ['roo']
import re

text = "computerscience admain root"
data_list = re.findall("r.+o", text)  # 贪婪
print(data_list)  # ['rscience admain roo']
import re

text = "computerscience admain root"
data_list = re.findall("r.+?o", text)  # 非贪婪
print(data_list)  # ['rscience admain ro']
  • \s 一个任意空白字符(注意:tab(\t)在这里不是空白字符)
import re

text = "computer science admain add root"
data_list = re.findall("a\w+\s\w+", text)
print(data_list)  # ['admin add']
1.2.2.2 关于数量
  • * 0个或者n个
  • + 1个或者n个
  • ? 0个或者1个
  • {n} 固定n个
  • {n,} n个或者n个以上
  • {n, m} n到m个
  • 注意:默认贪婪匹配,如果要非贪婪匹配,那么在数量后面加?
1.2.2.3 分组
  • 提取数据区域
import re

text = """正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,
包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。正则表达式是对字符串(包括普
通字符和特殊字符)操作的一种逻辑公式,就是用事先定义好的一些特定字符以及这些特定字符的组合,组成一个“规则字符串”,这
个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式用来检索、替换那些符合某个模式(规则)的文本,通常被用来检索、
替换那些符合某个模式(规则)的文本。正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提
取字符串等等,许多程序设计语言都支持利用正则表达式进行字符串操作。楼主:瑾瑜,电话 18866666666,邮箱: 12345679@163.com。
求点赞求转发,求一键三连!!!18866668888"""

data_list = re.findall("1886(6\d{5})", text)
print(data_list)  # ['666666', '666888']
import re

text = """正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,
包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。正则表达式是对字符串(包括普
通字符和特殊字符)操作的一种逻辑公式,就是用事先定义好的一些特定字符以及这些特定字符的组合,组成一个“规则字符串”,这
个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式用来检索、替换那些符合某个模式(规则)的文本,通常被用来检索、
替换那些符合某个模式(规则)的文本。正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提
取字符串等等,许多程序设计语言都支持利用正则表达式进行字符串操作。楼主:瑾瑜,电话 18866666666,邮箱: 12345679@163.com。
求点赞求转发,求一键三连!!!18866668888"""

data_list = re.findall("(1\d{2})66(6\d{5})", text)
print(data_list)  # [('188', '666666'), ('188', '668888')]
  • 提取数据区域 + 或
import re

text = """正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,
包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”),是计算机科学的一个概念。18866root太牛逼了。正则表达式是对字符串(包括普
通字符和特殊字符)操作的一种逻辑公式,就是用事先定义好的一些特定字符以及这些特定字符的组合,组成一个“规则字符串”,这
个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式用来检索、替换那些符合某个模式(规则)的文本,通常被用来检索、
替换那些符合某个模式(规则)的文本。正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提
取字符串等等,许多程序设计语言都支持利用正则表达式进行字符串操作。楼主:瑾瑜,电话 18866666666,邮箱: 12345679@163.com。
求点赞求转发,求一键三连!!!18866668888"""

data_list = re.findall("18866(6\d{5}|r\w+太)", text)
print(data_list)  # ['root太', '666666', '668888']
例题:
  1. QQ号
[1-9]\d{4,12}
  1. 身份证号码
13044919991203887X
130449199912038879

"\d{17}[\dX]"

"\d{6}(\d{4})\d{7}[\dX]"  # 拿到出生年份

"(\d{6}(\d{4})\d{7}[\dX])"  # 拿到出生年份 和 整体的证件号码
  1. 手机号
1[3-9]\d{9}
  1. 邮箱
xxxx@xxx.com

"\w+@\w+\.\w+"  # 这里的\.是将.转义成.,使正则直接匹配.而不是匹配任意的字符

re.findall("\w+@\w+\.\w+", text, re.ASCII)  # re.ASCII使匹配到的不包含中文
"[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+"
  1. re模块
  • re.findall() 获取匹配成功的所有结果
  • re.match() 从开头进行匹配 开头要是没有匹配成功就不再继续往后匹配,返回第一个对象
import re
 
 text = "大小逗2B最逗3B欢乐"
 
 regular = r"逗\dB"
 data_list = re.findall(regular, text)
 print(data_list)  # ['逗2B', '逗3B']
 
 data_list = re.match(regular, text)
 print(data_list)  # None
import re
 
 regular = r"大小逗\dB"
 text = "大小逗2B最逗3B欢乐"
 data_list = re.match(regular, text)
 print(data_list)  # <re.Match object; span=(0, 5), match='大小逗2B'>
import re
 
 regular = r"大小逗\dB"
 text = "大小逗2B最逗3B欢乐"
 data_obj = re.match(regular, text)
 if data_obj:
     data = data_obj.group()
     print(data)  # 大小逗2B
  • 关于match的应用场景
# 想对用户的手机号进行校验
 
 import re
 import sys
 
 print("请输入手机号:")
 mobile_number = input(">>> ")
 mobile_number = mobile_number.strip()
 # 验证手机号码是否合法
 regular = r"^1[3|5|8|9]\d{9}$"  # ^指开头 $指结尾
 if re.match(regular, mobile_number):
     print("手机号码合法, ", mobile_number)
 else:
     print("手机号码非法", mobile_number, file=sys.stderr)
  • re.search 浏览整个字符串去匹配,匹配失败返回 None,成功返回第一个对象
import re
 
 regular = r"逗\dB"
 text = "大小逗2B最逗3B欢乐"
 data_list = re.search(regular, text)
 if data_list:
     print(data_list)  # <re.Match object; span=(2, 5), match='逗2B'>
  • re.split
# 字符串的split
 text = "dsadfeferfg.mp4"
 text.split(".")
# re的切割
 
 import re
 
 text = "大小逗2B最逗3B欢乐"
 data_list = re.split("\dB", text)
 print(data_list)  # ['大小逗', '最逗', '欢乐']
import re
 
 text = "1+8-7+18-20"
 data_list = re.split("[+-]", text)
 print(data_list)  # ['1', '8', '7', '18', '20']

1.2.3 小结

以上就是常见的内置模块的需要了解的内容。

1.3 第三方模块

python安装第三方模块:

  • pip
  • 源码
  • wheel

第三方模块都会保存在site-packages目录下面。

导入模块的时候,只需要在代码中import 模块名

1.3.1 requests模块

requests,让我们可以通过代码向某些地址发送网络请求,然后帮助我们获取到结果。

pip install requests
import requests
 
 requests.功能
  1. 基于浏览器抓包: 查看他的网络请求:
  • 地址
  • 请求的方式
  • 传递的数据

使用谷歌浏览器打开豆瓣电影:

在页面空白位置 鼠标右键 -> 检查 (也可以使用快捷键 F12)

就会出现浏览器帮我们做的抓包工具.

点击 网络(network) 浏览器会监测这个网站上所有的网络请求.

随便找一个网络包,点开他的headers,然后会出现一些相关的参数:

点击response,会看到服务器给我们返回的数据:

  1. requests代替浏览器发送请求
    然后我们就可以通过程序伪造浏览器发请求来获取数据:
# 这个url和以前那个url不一样,但是浏览器抓包的方式是一样的.
 import requests
 
 url = r"https://search.douban.com/movie/subject_search?search_text=%E7%83%AD%E9%97%A8&cat=1002"
 
 # 返回的所有response数据都拿到
 res = requests.get(url=url)  # 原始的utf-8编码的数据
 
 # 原始的响应体
 text = res.content.decode("utf-8")  # 吧utf-8的数据转换成字符串
 
 # 注意:这儿可能拿不到数据,因为有反爬虫策略,所以可能导致服务器不会向我们返回数据 -- 伪造一个user-agent参数
 # 有时候,有的网站也会限制我们的IP -- 多找几个代理IP / 发请求的速度(一秒多少多少次请求) -- 发送慢一点 / 算法 -- 逆向算法反反爬
 # 一般IP限制和发送请求速度会一起使用来反爬
 print(text)
import requests
 
 url = r"https://search.douban.com/movie/subject_search?search_text=%E7%83%AD%E9%97%A8&cat=1002"
 headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                   "Chrome/122.0.0.0 Safari/537.36",
 }
 
 # 返回的所有response数据都拿到
 res = requests.get(url=url, headers=headers)  # # python中的字节(utf-8)
 
 # 原始的响应体
 text = res.content.decode("utf-8")  # python中的字符串(unicode)
 print(text)

要拿到字符串,也可以这样:

import requests
 
 url = r"https://search.douban.com/movie/subject_search?search_text=%E7%83%AD%E9%97%A8&cat=1002"
 headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                   "Chrome/122.0.0.0 Safari/537.36",
 }
 
 # 返回的所有response数据都拿到
 res = requests.get(url=url, headers=headers)
 
 print(res.text)

如果获得json格式的数据,那么可以将数据利用python中的json模块将json串转换成python中的数据结构.

# 获取豆瓣电影top250所有的页面信息
 page_num = 10
 headers = {
     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                   "Chrome/122.0.0.0 Safari/537.36",
 }
 for i range(0, page_num):
     url = "https://movie.douban.com/top250?start=" + str(25*i)
     res = requests.get(url=url, headers=headers)
     print(res.text)
requests小结
import requests

url = "地址"
headers = {
    "": "",
}
res = requests.get(url=url, headers=headers)

# 字符串类型
print(res.text)
# 下面这段代码看一下就行了,有bug,不要模仿!!!
import requests

page_count = 1
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/99.0.4844.84 Safari/537.36 HBPC/12.1.3.306"
}

while True:
    print("第一页:")
    url = r"https://www.chinaunicom.com.cn/43/menu01/1/column05?pageNo={}&pageSize=10&year=2023&month=11".format(page_count)

    response = requests.get(url=url, headers=headers)
    page_count += 1
    if not response.text.strip():
        break
    print(response.text)

写在最后

由于这些笔记都是从typora里面粘贴过来的,导致图片会加载失败,如果想要带图片的笔记的话,我已经上传至github,网址(https://github.com/wephiles/python-foundation-note)如果github上不去的话也可以去我的gitee下载,网址(https://gitee.com/wephiles/python-django-notes)。欢迎大家来下载白嫖哦,最后,如果可爱又善良的你能够给我github点个star,那你将会是这个世界上运气最好的人喔。

python基础--shutil模块、正则表达式(re模块)和requests模块(用来爬虫)_requests模块