Python 基础知识笔记

2023年 9月 28日 103.6k 0

1 下载安装 Anaconda

  • 去官网下载安装包,双击安装包安装,安装路径可自定义安装。
  • 安装完成后设置环境变量,在环境变量中的 path 中添加 Anaconda 的安装路径及路径下的 Scripts 的路径
  • 然后打开 cmd 命令窗口,输入 conda --version 校验是否安装成功
  • 启动 Anaconda ,在电脑搜索的地方搜索 “Jupyter Notebook” 进行启动。

2 基础知识

2.1 print:用于字符串打印

语法:

print(value,...,sep='',end='')
# 1. value:输入一个或多个要打印的字符串
# 2. sep:代表可自定义 value 之间的符号,默认为空格
# 3. end:代表可自定义 value 结尾的符号,默认为换行符号
print('lemon','apple','banana',sep=',',end='.')

2.2 注释与换行操作

单行注释:

print('hello','world') # 向屏幕输出 hello world

多行注释:

'''
先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。
然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。
诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
'''

"""
宫中府中,俱为一体,陟罚臧否,不宜异同。
若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
"""

print('侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。')
print('愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。')
print('将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。')

换行:

print('愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
亲贤臣,远小人,此先汉所以兴隆也;
亲小人,远贤臣,此后汉所以倾颓也。
先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。
侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。')

2.3 单引号、双引号及转义字符

print('臣本布衣,躬耕于南阳')
print("臣本布衣,躬耕于南阳")
print(''' I'm pythonic,I said:"Practice makes perfect" ''')
print(""" I'm pythonic,I said:"Practice makes perfect" """)

# 用反斜杠()转义特殊字符
print('n')
print('\n')
# 可以用 r 和 R 来定义原始字符串
print(r'\n')  # 打印的是 \n
print(R'\n')  # 打印的是 \n

2.4 运算符和数学函数

运算符:

# 乘方
4 ** 4  # 表示4的4次方,结果:256

# 取整
20 // 6  # 结果:3

# round 四舍五入
round(8.9)  # 四舍五入保留到整数位
round(10.671,2)  # 四舍五入保留小数点后两位

# abs绝对值取整
abs(-1)

math 数学函数:

import math
math.ceil(5.01)  # 向上取整
math.floor(5.99)  # 向下取整
math.trunc(10.9)  # 截取整数位
math.pow(2,4)  # 幂运算,表示2的4次方

2.5 字符串

特点:由单引号、双引号、三个单引号、三个双引号 组成

'A' + 'B'  # 结果:AB
'A' * 3  # 结果:AAA

'python'[1]  # 结果:y
'python'[-2]  # 结果:o
'python'[1:4]  # 结果:yth
'python'[2:]  # 结果:thon
  • String.strip([chars]) :

    • chars为空:去除头尾空白符(n、r、t、'',即换行、回车、制表符、空格)
    • chars不为空:将chars拆成一个一个字符,去除头尾指定的字符
  • '   abc123abc   '.strip()  # 结果:'abc123abc' 
    'abc123abc'.strip('ab')  # 结果:'c123abc' 
    'abc123abc'.strip('ba')  # 结果:'c123abc' 
    'eabc123abc'.strip('ba')  # 结果:'eabc123abc' 
    'abc123cba'.strip('bac')  # 结果:'123' 
    'abc12abc3cba'.strip('bac')  # 结果:'12abc3' 
    
  • String.lstrip([chars]) :
  • '   abc123abc   '.lstrip()  # 结果:'abc123abc   ' 
    
  • String.rstrip([chars]) :
  • '   abc123abc   '.rstrip()  # 结果:'   abc123abc' 
    
  • 判断字符串开头结尾字符:
  • 'python'.startswith('p')  # 结果:true 
    'python'.endswith('n')  # 结果:true 
    
  • 返回字符串中字符的位置:
  • 'apple'.find('p')  # 结果:1
    'apple'.index('p')  # 结果:1
    
    'apple'.find('m')  # 结果:-1
    'apple'.index('m')  # 结果:报错
    
  • 字符串替换:
  • 'python'.replace('t','TT')  # 结果:'pyTThon'
    'python'.replace('python','hello')  # 结果:'hello'
    
  • len(S): 返回字符串长度
  • S.count('x'): 查找某个字符在字符串里面出现的次数
  • S.upper(): 将字符串中小写字母,转为大写字母
  • S.lower(): 将字符串中大写字母,转为小写字母
  • S.center(n,'-'): 把字符串放中间,两边用-补齐,n为字符串长度,若n小于字符串长度则返回原值
  • 字符串格式化:% format
    • %s: 使用 str() 函数进行字符串转换
    • %d: 转为十进制整数
    • %f: 转为浮点数
  • 'hello %s' %('world')  # 结果:'hello world'
    'hello %s,%s' %('world')  # 结果:报错
    'hello %s,%s' %('world','apple')  # 结果:'hello world,apple'
    'I am %{name}s, I am %{age}s years old' %{'name':'cily','age':16}  # 结果:'I am cily, I am 16 years old'
    
    'I am %d years old' % (16)  # 结果:'I am 16 years old'
    
    '%f' % (3.14)  # 结果:'3.140000'
    '%.3f' % (3.14)  # 结果:'3.140'
    
    
    'hello {}'.format('world')  # 结果:'hello world'
    'hello {} {}'.format('world','python')  # 结果:'hello world python'
    'hello {1} {0}'.format('world','python')  # 结果:'hello python world'
    'I am {name}, I am {age} years old'.format(name = "cily",age = 16)  # 结果:'I am cily, I am 16 years old'
    

    2.6 Number(数字):整形、浮点型、复数

    Python数字类型:整形(int)、浮点型(float)、复数(complex)、布尔型(bool)

    进制转换:

    • bin 转化为二进制 0b1010
    • oct 转化为八进制 0o12
    • int 转化为十进制 10
    • hex 转化为十六进制 0xa
  • 浮点型(float):
  • type(10)  # int
    type(10.)  # float
    
    print(3+1.0)  # 4.0
    print(type(3+1.0))  # 
    
    # Python 中相除,默认返回浮点型
    print(3/1)  # 3.0
    print(type(3/1))  # 
    # 整除
    print(3//1)  # 3
    print(type(3//1))  # 
    
  • 复数(complex):complex([real[,imag]])
  • complex(3,)  # (3+0j)
    complex(3,4)  # (3+4j)
    complex(3,4).real  # 实部,结果:3.0
    complex(3,4).imag  # 虚部,结果:4.0
    complex('3',4)  # 报错
    complex('3+4j')  # (3+4j)
    complex('3 + 4j')  # 报错
    
  • 布尔类型:判断条件是否成立,只有 True、False
  • int(True)  # 1
    int(False)  # 0
    isinstance(1,int)  # True
    isinstance(0,int)  # True
    isinstance(True,int)  # True
    isinstance(False,int)  # True
    
    bool(1)  # True
    bool(0)  # False
    bool(-1)  # True
    bool(None)  # False
    bool()  # False
    bool('')  # False
    bool(' ')  # True
    bool([])  # False
    bool({})  # False
    

    2.7 列表、元组、字典

  • 列表
  • # 创建空列表
    list[]
    []
    
    # 创建只有一个元素的列表
    [1,]
    [1]
    
    # 创建包含不同数据类型的列表
    ['a',1,2,3.14,[1,2,3,4]]
    
    # 列表操作
    ['a',1,2,3.14,[1,2,3,4]][0]  # 'a'
    ['a',1,3.14,[1,2,3,4]][3][2]  # 3
    [1,2] + [3.4]  # [1,2,3.4]
    [1,2] - [3.4]  # 报错,列表间不支持相减操作
    [1,2] * 5  # [1,2,1,2,1,2,1,2,1,2]
    [1,2] / [3.4]  # 报错,列表间不支持相除操作
    
    • list.count(x) : 统计列表中 x 出现的次数,若不存在则返回 0
    • list.append(x) : 向列表尾部追加成员 x
    • list.extend(l): 向列表尾部追加另外一个列表 l
    • list.index(x) : 返回参数 x 在列表中的序号,若不存在则报错
    • list.insert(index, object) : 在列表指定位置插入数据
    • list.pop() : 默认删除列表尾部成员,并返回删除的成员
    • list.remove(x) : 删除列表中指定成员(有多个则只删除第一个),若指定成员不存在则报错
    • list.reverse() : 将列表中的成员顺序颠倒
    • list.sort() : 排序(要求成员间可排序,否则报错)
    x = [1,2,3,4,2,5,3,8,2,9,0,19,2,14,12,34,25]
    x.count(2)  # 4
    [1,2,3].append([7,8,9])  # [1,2,3,[7,8,9]]
    [1,2,3].extend([7,8,9])  # [1,2,3,7,8,9]
    [11,12,13,14].pop()  # 14
    [11,12,13,14].pop(1)  # 12
    
  • 元组(tuple):
  • 元组基本形式:圆括号 () 包围的数据集合,可以通过序号访问元素。一种特殊形式的列表。一但创建不可变。

    【注意】:元组的元素不可变,但当元组元素为列表或字典数据类型时,列表或字典内的内容是可以变的。

    # 创建空元组
    ()
    tuple()
    (1,)  # 创建只有一个元素的元组不能省略这个逗号
    type((1,))  # tuple
    type((1))  # int
    
    a = (1,2,3,[4,5,6])
    a[1] = 10  # 报错
    a[3][0] = 10  # a的值变为 (1,2,3,[10,5,6])
    
    • 元组常见函数:
      • len(tuple) # 返回元组数量
      • max(tuple) # 返回元组最大值
      • min(tuple) # 返回元组最小值
      • tuple(seq) # 将序列转为元组
  • 字典基本操作:
  • {}  # 创建空字段
    dict()  # 创建空字段
    
    fruits = {"lemon":5,"apple":10}
    fruits['lemon']  # 5
    fruits['pear']  # 通过不存在的键访问成员会报错
    
    fruits['lemon'] = 20
    fruits['pear'] = 15
    
    del fruits['pear']  # 删除pear
    fruits.clear()  # 清空整个字典
    
    del fruits  # 删除 fruits
    

    字典的键的数据类型可以是:字符串、数字、元组不可变数据类型,不能为列表类型。

    • dict.copy() # 复制字典
    • dict.get(key,default=None) # 获取key对应的值,若key不存在则返回default
    • dict.items() # 获取由键和值组成的迭代器
    • dict.keys() # 获取键的迭代器
    • dict.values() # 获取值的迭代器
    • dict.pop(key,[default]) # 删除key:value的指定成员对。若key不存在,则返回default
    • dict.popitem() # 从字典末尾删除key:value,并返回key:value
    • dict.update({key:value}) # 从另外一个字典更新成员(存在则覆盖,若不存在就创建。)
    • dict.setdefault(key,default=None) # 若字典存在key,则返回对应的值(不会覆盖原值)。若不存在,则建立一个key:default的字典成员。
    fruits1 = {'lemon':5,'apple':10}
    fruits2 = fruits1.copy()
    fruits1.get('pear','该键不存在')
    fruits1.items()  # dict_items([{'lemon':5},{'apple':10}])
    fruits1.keys()  # dict_keys(['lemon', 'apple'])
    

    2.8 Set集合类型

    集合(set):无序、不重复的数据集合。无法通过键访问成员。可以使用大括号{}或者set()函数创建集合。

    # 注意:创建一个空集合必须用 set() 而不是 {},因为 {} 是创建一个空字典。
    type(set())  # set
    
    a = {1,2,3,4}
    type(a)  # set
    
    b = {1,1,3,3,2,2,4,4}  # 最终 b 的值为 {1,3,2,4}
    
    c = ['lemon','lemon','apple','apple']
    set(c)  # 去重,结果:{'lemon','apple'}
    
    d = {1,2,3,4,5,6}
    len(d)  # 6
    1 in d  # True
    7 in d  # False
    
    d - a  # 得出集合间的差集 {5,6}
    d & a  # 得出集合间的交集 {1,2,3,4}
    d | a  # 得出集合间的并集 {1,2,3,4,5,6}
    

    2.9 Python 基本数据类型总结

  • 数字(Number):整型(int)、浮点型(float)、复数(complex)、布尔型(bool)
  • 序列:列表(可变序列)、字符串(不可变序列)、元组(不可变序列)
  • 字典:无序,没有索引,通过键值对访问,键是不可变的
  • 集合:无序,没有索引,没有重复元素
  • 2.10 变量

    命名规则:只能包含字母、数字、下划线,不能以数字开头。最好用小写字母。

    关键字:

    False、class、finally、is、return、True、continue、for、lambda、try、None、def、from、nonlocal、while、and、del、global、not、with、as、elif、if、or、yield、assert、else、import、pass、break、raise、except、in

    2.11 运算符

  • 算术运算符: + - * / % // **
  •   a = {1,2,3,4}
      b = {1,2}
      a - b  # 得出集合间的差集 {3,4}
    
      'python ' * 3  # 字符串 'python python python '
      [1,2,3] * 3  # 列表 [1,2,3,1,2,3,1,2,3]
      (1,2,3) * 3  # 元组 (1,2,3,1,2,3,1,2,3)
    
      10 // 3  # 取整运算 3
      10.0 // 3  # 取整运算 3.0
    
  • 赋值运算符:= += -= *= /= %= //+ **=

  • 比较(关系)运算符:== != => random_num:
    print('大了')
    elif guess_num0:
    lemon = 5
    print(lemon) # 5

    for i in range(10):
    lemon = 9
    print(lemon) # 9

    i = 1
    while i=3,n∈N*)

    # 实现:用户输入任意数字,返回第N项数字
    def fib(num):
      if num 5]
    b  # [6,7,8,9]
    
    num = int(input('请输入数字:'))
    fibs_list = [fib(i) for i in range(1,num+1)]
    fibs_list  # 
    

    2.19 面向对象

  • 面向过程:核心是在过程二字,面向过程设计思维,就好比精心设计好一条流水线,考虑周全,相应时候处理相应问题。
    • 优点:将复杂的问题流程化,进而简单化
    • 缺陷:扩展性差(如果更改需求,可能整个代码都需要重写,牵一发而动全身)

    面向过程适用一些简单的、固定的、不需要更新迭代的问题,如果任务复杂,且需要不断更新迭代和维护的,推荐使用面向对象。

    面向过程:

    def test(x,y):
      if x > y:
        return x
      elif x < y:
        return y
      return x + y
    
  • 面向对象:对真实世界的模拟
  • 面向对象编程特点:

  • 可以编写表示真实世界中的事物和情景的类,并基于这些类来创建对象
  • 可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率
  • 面向对象三大特点:

  • 封装性:
    将对象的特征与行为保存起来
  • 继承性:
    通过继承,子类可快速获取父类特征与行为
  • 多态性:
    不同的子类对象,调用相同的父类方法,产生不同的执行结果
  • 2.20 类

    类:描述具有相同的特征和行为的对象的集合

    • 通过变量可以刻画类的特征
    • 通过方法可以描述类的行为

    注意:类可以去定义,但不负责去执行相关方法

    语法:

    class 类名():
    
      变量  # 刻画类的特征
    
      # 实例方法
      def 相关方法名(self,相关参数):  # 描述类的行为
        pass
    
      # 类方法
      @classmethod
      def 方法名(cls,相关参数)
        print('')
    
      # 静态方法
      @staticmethod
      def 方法名(相关参数)
        print('')
    
    # 关于 self
    # self 名称是约定成俗的
    # self 指向的是类实例化后的对象本身
    # self 只有在类的方法中才会有,函数是不必带有 self 的
    # self 在定义类的方法(实例方法)时是必须有的
    # self 在调用时不必传入相应的参数
    
    # 通过 @classmethod 声明一个类方法
    
    # 静态方法:与普通函数基本上没有什么区别
    # 静态方法与类、对象没有太大关系的时候,可以使用该方法
    # 通过 @staticmethod 声明一个静态方法
    
    # 成员可见性:
    # public 公开性 (外部可以访问相关变量,或 外部可以调用相关方法)
    # private 私有性 (外部不可以访问相关变量,或 外部不可以调用相关方法)
    
    class Men():
      gender = 'male'
      avg_height = 1.7
    
      def __init__(self,name,age):
        # 初始化对象特征
        print('这是构造函数 __init__')
        self.name = name
        self.age = age
        self.__testAge = age  # 私有变量:在变量前面添加两个下划线
        self.salary = 0
    
      def think(self):
        print('thinking')
    
      def __testThink(self):  # 私有方法:在方法前面添加两个下划线
        print('thinking')
    
      def sleep(self):
        print('sleeping')
    
      def modify_salary(self,salary):
        self.salary = salary
    
      @classmethod
      def modify_height(cls,height):
        cls.avg_height += height  # 修改类变量
        print('Success.Now the avg_height is ' + str(cls.avg_height))
      # classmethod 类方法
      # cls 是区别于示例方法的 self
    
      @staticmethod
      def plus_num(x,y):
        return x + y
    
    men = Men('lemon',18)  # 类实例化,生成一个对象
    men.sleep()
    men.think()
    men.name  # lemon
    men.__dict__  # {'name':'lemon','age':18}
    men.avg_height = 1.75  # 这样修改的不是 Men 类中的 avg_height,而是相当于在类中 __init__ 创建了一个 self.avg_height = 1.75
    Men.modify_height(0.05)
    Men.__dict__
    men.plus_num(2,3)  # 6
    men.__testAge  # 报错
    men.testAge  # 报错
    men._Men__testAge  # 私有变量可以通过这种方式获取
    men.__testThink  # 报错
    men.testThink  # 报错
    men._Men__testThink  # 私有方法可以通过这种方式调用
    men.salary = 10  # 不建议这样直接修改实例变量的值,建议通过定义方法来修改实例变量的值
    men.modify_salary(20)
    

    构造函数:可以让模板生成不同特征的对象

    继承:子类可以直接使用父类的功能,减少重复代码

    super关键字:不仅可以调用父类的构造函数,也可调用父类实例方法

    class Men():  # 父类 或 几类
    
      gender = 'male'
      avg_height = 1.7
    
      def __init__(self,name,age):
    
        self.name = name
        self.age = age
    
      def sleep(self):
        print('sleeping')
    
      def think(self):
        print('thinking')
    
    
    class ChineseMen(Men):  # 子类
      def __init__(self,name,age,height):
        # self.name = name
        # self.age = age
        # 上面两行可以改为下面这一行
        # Men.__init__(self,name,age)
        # 上面一行可以改为下面这一行
        super(ChineseMen,self).__init__(name,age)
        self.height = height
    
      def sleep(self):
        # Men.sleep(self)
        # 上面一行可以改为下面这一行
        super(ChineseMen,self).sleep()
        print(self.name + 'is sleeping')
    
    
    xiaoming = ChineseMen('xiaoming', 18, 180)
    xiaoming.__dict__  # {'name':'xiaoming','age':18,'height':180}
    

    2.21 正则表达式

    import re
    
    re.findall(pattern, string, flags)  # 搜索整个字符串,返回所有匹配项
    re.match(pattern, string, flags)  # 从字符串首字符开始匹配,若首字符不匹配,则返回None,若匹配则返回第一个匹配对象
    re.search(pattern, string, flags)  # 搜索整个字符串,若全都不匹配,则返回None,若匹配则返回第一个匹配对象
    # pattern 正则表达式匹配规则
    # string 要进行匹配的字符串
    # flags 可选参数,进行特定条件的匹配
    re.sub(pattern, repl, string, count=0, flags=0)  # 正则替换
    # pattern 正则表达式
    # repl 要替换的内容,也可以传入函数
    # string 被替换的字符串
    # count 默认为0,代表全部替换,1代表替换1次,2代表替换2次
    
    match_str = 'lemon&apple&lemoon&banana&lemooon&pear&lemoooon'
    re.findall('lemon',match_str)  # ['lemon']
    re.findall('lemo{1,4}n',match_str)  # ['lemon','lemoon','lem0ooon','lemoooon']
    
    match_str = 'bac | bbc | bcc | bdc | bec'
    re.findall('b[ab]c',match_str)  # ['bac','bbc']
    re.findall('b[^ab]c',match_str)  # ['bcc','bdc','bec']
    re.findall('b[abcd]c',match_str)  # ['bac','bbc','bcc','bdc']
    re.findall('b[a-d]c',match_str)  # ['bac','bbc','bcc','bdc']
    re.findall('b[^a-d]c',match_str)  # ['bec']
    
    # d 匹配一个数字字符
    # D 匹配一个非数字字符
    match_str = '&a0b12c344d55&AC_'
    re.findall('d',match_str)
    re.findall('d{1,}',match_str)
    re.findall('D',match_str)
    # w 匹配一个包括下划线的单词字符
    # W 匹配一个非包括下划线的单词字符
    re.findall('w',match_str)
    re.findall('W',match_str)
    # s 匹配一个空白字符 如空格、制表符、换页符等
    # S 匹配一个非空白字符
    match_str = 'rt&a0b12c344d55&AC_ n'
    re.findall('s',match_str)
    re.findall('S',match_str)
    
    # 贪婪匹配
    # 贪婪 倾向于最大长度匹配
    # 非贪婪 倾向于最小长度匹配
    match_str = 'lemon12banana34pear56'
    re.findall('[a-z]{4,6}',match_str)  # ['lemon','banana','pear']
    re.findall('[a-z]{4,6}?',match_str)  # ['lemo','bana','pear']
    
    # 匹配次数
    # * 代表匹配前面的字符零次或多次  {0,}
    # + 代表匹配前面的字符一次或多次  {1,}
    # ? 代表匹配前面的字符零次或一次  {0,1}
    # 对于 ? 总结:
    # 1. 如果数量词后面有 ?,该 ? 代表非贪婪的关键字,倾向于取最小长度匹配
    # 2. 如果字符后面有 ?,该 ? 代表匹配前面字符 0次或1次
    
    match_str = 'abcdef 123456 abcdef 456 abc'
    re.findall('[a-z]{3,6}',match_str)  # ['abcdef','abcdef','abc']
    # 定位符
    # ^ 匹配字符串开始的位置
    # $ 匹配字符串结束的位置
    re.findall('^[a-z]{6}',match_str)  # ['abcdef']
    re.findall('[a-z]{3}$',match_str)  # ['abc']
    
    # 组的匹配
    match_str = 'lemonlemonlemonappleapplepearpear'
    re.findall('(lemon){3}',match_str)  # ['lemon']
    re.search('(lemon){3}',match_str)  # 
    # 组 与 字符集 的区别
    # (lemon)  匹配 lemon 这一组字符
    # [lemon]  匹配 括号中的任意一个字母
    
    # flags可选参数
    match_str = 'lemon LEMON'
    re.findall('lemon',match_str,re.I)  # ['lemon','LEMON']
    # .  匹配除 “n” 之外的任何单个字符
    match_str = 'n123 abcr'
    re.findall('.',match_str,re.S)  # 使用 re.S 可以让 . 也匹配 n
    match_str = 'lemonn LEMONn'
    re.findall('lemon.',match_str,re.I | re.S)  # ['lemonn', 'LEMONn']
    
    # match search
    match_str = 'a5678 lemon 1234'
    re.findall('d',match_str)  # ['5','6','7','8','1','2','3','4']
    re.match('d','5678 lemon 1234')  # 
    re.search('d',match_str)  # 
    r = re.search('d',match_str)  # 
    r.group()  # '5'
    
    # group 组的匹配
    # match_str = 'lemonlemonlemonappleapplepearpear'
    match_str = 'life is mostly happy,but sometimes sad'
    # is mostly  cheerful,but sometimes
    # is mostly cheerful  sometimes sad
    r = re.search('life(.*)sad',match_str)
    r  # 
    r.group(0)  # life is mostly happy,but sometimes sad
    r.group(1)  #  is mostly happy,but sometimes 
    r1 = re.search('left(.*)but(.*)sad',match_str)
    r1  # 
    r1.group(1)  #  is mostly happy,
    r1.group(2)  #  sometimes 
    r1.group()  # (' is mostly happy,',' sometimes ')
    
    # 正则替换
    match_str = 'lemon apple 123456789 lemon lemon'
    re.sub('lemon','a',match_str,count=0)  # 'a apple 123456789 a lemaon'
    re.sub('lemon','a',match_str,count=1)  # 'a apple 123456789 lemon lemon'
    re.sub('lemon','a',match_str,count=2)  # 'a apple 123456789 a lemon'
    # 需求:数字小于 7 的,都转为 0,数字大于等于 7 的,都转为 10
    def tranform(value):
      pass  # pass为站位操作
    re.sub('d',tranform,match_str,count=0)  # 'lemon apple  lemon lemon'
    def tranform(value):
      print(value)
    re.sub('d',tranform,match_str,count=0)
    # 
    # 
    # 
    # 
    # 
    # 
    # 
    # 
    # 
    def tranform(value):
      match_num = value.group()
      print(match_num)
      if int(match_num) < 7:
        return '0'
      return '10'
    re.sub('d',tranform,match_str,count=0)  # 'lemon apple 000000101010 lemon lemon'
    
    

    正则表达式全集:

    字符 描述
    将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“n”匹配一个换行符。串行“”匹配“”而“(”则匹配“(”。
    匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“n”或“r”之后的位置。
    $ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“n”或“r”之前的位置。
    * 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
    + 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
    ? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
    {n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
    {n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
    {n,m} m和n均为非负整数,其中n

    x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
    [xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
    [^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。
    [a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
    [^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
    b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“erb”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
    B 匹配非单词边界。“erB”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
    cx 匹配由x指明的控制字符。例如,cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
    d 匹配一个数字字符。等价于[0-9]。
    D 匹配一个非数字字符。等价于[^0-9]。
    f 匹配一个换页符。等价于x0c和cL。
    n 匹配一个换行符。等价于x0a和cJ。
    r 匹配一个回车符。等价于x0d和cM。
    s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ fnrtv]。
    S 匹配任何非空白字符。等价于[^ fnrtv]。
    t 匹配一个制表符。等价于x09和cI。
    v 匹配一个垂直制表符。等价于x0b和cK。
    w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”
    W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”
    xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“x41”匹配“A”。“x041”则等价于“x04&1”。正则表达式中可以使用ASCII编码。.
    num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)1”匹配两个连续的相同字符。
    n 标识一个八进制转义值或一个向后引用。如果n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
    nm 标识一个八进制转义值或一个向后引用。如果nm之前至少有nm个获得子表达式,则nm为向后引用。如果nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则nm将匹配八进制转义值nm。
    nml 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
    un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,u00A9匹配版权符号(©)。

    常用正则表达式

    字符 描述
    用户名 /^[a-z0-9_-]{3,16}$/
    密码 /^[a-z0-9_-]{6,18}$/
    十六进制值 /^#?([a-f0-9]{6}|[a-f0-9]{3})$/
    电子邮箱 /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})/或者/[a−zd]+([˙a−zd]+)∗@([da−z](−[da−z])?)+(1,2˙[a−z]+)+/ 或者 /^[a-zd]+(.[a-zd]+)*@([da-z](-[da-z])?)+(.{1,2}[a-z]+)+/或者/[a−zd]+([˙​a−zd]+)∗@([da−z](−[da−z])?)+(1,2˙​[a−z]+)+/
    URL /^(https?://)?([da-z.-]+).([a-z.]{2,6})([/w .-])/?$/
    IP 地址 /((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)/ 或者 /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
    HTML 标签 /^)$/
    删除代码注释 (?
    Unicode编码中的汉字范围 /^[u2E80-u9FFF]+$/

    2.22 Pycharm

    官网地址:www.jetbrains.com/pycharm/

    download:

    image.png

    image.png

    • 运行 Pycharm 需要绑定 Python 解释器
    • 找到 Python 的安装路径,如:D:toolspythonpython.exe
    • 打开 PyCharm =》 打开项目 =》 File =》 Setting =》 Project: =》 Python Interpreter (Python解释器) =》 将Python的安装路径添加进去即可

    2.23 Python 模块

  • 基本组织结构

    包(文件夹) =》 模块(文件) =》 变量、for循环、while循环、def、class

    创建一个包:打开项目 =》 右键 =》 New =》 Python Package =》 例如:libs =》 会生成一个 libs文件夹,在libs文件夹下面会生成一个 init.py ,init.py 声明了 libs 是一个包,如果没有 init.py 则说明 libs 只是一个文件夹不是一个包。

  • 在包里面可以创建很多模块,例如在 libs 下创建:p1.py、p2.py

    image.png

  • import 导入模块
  • p1.py、p2.py 两个模块在同一个包下面,根文件夹:右键 =》 Mark Directory as =》 Source Root
    libs/p1.py:

    a = 1
    b = 2
    c = 3
    

    libs/p2.py:

    import p1
    # import 模块名
    print(p1.a,p1.b,p1.c)
    # 也可以给p1取个别名: import p1 as t
    # print(t.a,t.b,t.c)
    

    跨包访问:

    main.py:

    import libs.p1 as t
    print(p1.a)
    print(p1.b)
    print(p1.c)
    
  • from import
    libs/p2.py:
  • from p1 import a,b,c
    # from p1 import *
    print(a)
    print(b)
    print(c)
    

    main.py:

    from libs.p1 import *
    print(a)
    print(b)
    print(c)
    

    设置哪些可以导入哪些不可以导入:

    libs/p1.py:

    __all__ = ['a','b']  # 这样在其他模块中就不能导入 c 了,只能导入 a、b
    a = 1
    b = 2
    c = 3
    
  • init.py
    • 声明一个文件夹为一个包
    • import 包 实际上导入的是这个包下面的 init.py
    • 该模块名为一个包名
    • 自定义选择哪些模块可以导入

    libs/init.py:

    print('This is libs.__init__.py')
    print(__name__)  # libs
    __all__ = ['p1']  # 自定义 libs 包下的p1模块可以呗导入,其他如p2不可被导入
    

    main.py

    import lib  # 导入的是 libs 下的 __init__.py
    from libs import p1
    

    libs/init.py:

    __all__ = ['p1']  # 自定义 libs 包下的p1模块可以呗导入,其他如p2不可被导入
    

    main.py

    from libs import *
    print(p1.a)
    print(p2.a)  # 报错
    
  • name
    libs/init.py:
  • print(__name__)
    

    libs/p1.py:

    def add(x,y):
      sum = x + y
      print(sum)
      return sum
    
    # 只有从当前模块去运行才会执行,如果在其他模块导入当前模块则不执行
    if __name__ == '__main__':
      add(3,4)
    

    main.py

    from libs.p1 import add
    add(5,5)
    

    2.24 迭代器、生成器、装饰器

  • 迭代器
    • 迭代器:可以理解为一个容器,每次从容器中取出一个数据,直到数据被取完为止
    • 自定义迭代器:
      • 以类为例:需要在类中,实现两个方法 iter 与 next
        其中:

      • iter 方法需要返回对象本身,它是for循环使用迭代器的要求;
      • next 方法用于返回容器中下一个元素,当容器中的数据取完时,需要引发 StopIteration 异常。
    # 需求:
    # 1. 自定义迭代器,通过传入最小值最大值,返回该范围所有数值的3次方
    # 2. 将返回的值,存入 num_list 列表中
    class Number():
      def __init__(self,min,max):
        self.min = min
        self.max = max
      def __iter__(self):
        return self
      def __next__(self):
        # 返回这个范围内所有数值的3次方
        num = self.min
        if self.min =y 返回 x+y
    # 如果 x =y:
        return x+y
      return x-y
    # 匿名函数与三元表达式搭配实现
    f = lambda x,y: x+y if x>=y else x-y
    f(3,4)  # -1
    f(5,4)  # 9
    
  • 三元表达式
  • # 三元表达式格式
    # 条件为真的结果 if 条件判断 else 条件为假的结果
    
    # 需求:
    # 输入一个单词
    # 如果是小写单词,则返回小写单词,否则都返回大写单词
    f = lambda x: x if x.islower() else x.upper()
    f('hello')
    f('Hello')
    
    
  • 高阶函数:map
  • # map 格式:
    map(func, *iterables)
    # func 代表可接收一个函数
    # iterables 代表可接收一个或多个可迭代的序列
    
    
    a = [1,2,3,4,5]
    # 需求:
    # 生成一个列表b,列表内的元素为a列表每个元素的三次方
    
    b = []
    for i in a:
      b.append(i ** 3)
    b  # [1,8,27,64,125]
    
    # 用map实现
    def f(x):
      return x ** 3
    b = map(f,a)
    b  # 
    list(b)  # [1,8,27,64,125]
    
    # 用 map 和 lambda 实现
    b = map(lambda x:x**3,a)
    list(b)  # [1,8,27,64,125]
    
    # 需求:将两个列表元素相加之后结果,存放在一个新列表c中
    a = [1,2,3,4,5]
    b = [1,2,3,4,5]
    c = map(lambda x,y:x+y,a,b)
    list(c)  # [2,4,6,8,10]
    # 长度不一样时
    a = [1,2,3]
    b = [1,2,3,4,5]
    c = map(lambda x,y:x+y,a,b)
    list(c)  # [2,4,6]
    
    
  • reduce
  • # reduce 格式
    from functools import reduce
    reduce(function, sequence[, initial])
    # function 接收一个函数
    # sequence 接收一个可迭代序列
    # initial 初始运算的值
    
    
    a = [1,2,3,4,5]
    # 需求:
    # 计算a列表各元素相乘之后的值
    num = reduce(lambda x,y:x*y,a)  # x、y会在a中寻找,最开始x是1,y是2,相乘以后为2;然后x是2,y是3,相乘以后为6;然后x是6,y是4,相乘以后是24,以此类推
    num  # 120
    num = reduce(lambda x,y:x*y,a,1000)  # 1000*1*2
    num  # 120000
    
    b = ['a','b','c']
    r = reduce(lambda x,y:x+y,b)
    r  # 'abc'
    r = reduce(lambda x,y:x+y,b,'???')
    r  # '???abc'
    
    # 连续计算:计算a列表各元素相加之后的值
    
    
    
    
  • filter
  • # filter 格式
    filter(function, iterable)
    # function 接收一个函数
    # iterable 接收一个可迭代序列
    # filter 返回结果必须是 True 或者 False
    # 适用场景:用于序列元素过滤
    
    a = [0,1,2,3,4,5]
    # 需求:将 a列表中非0的元素,保存到b列表中
    def f(x):
      if x!=0:
        return x
    b = filter(f,a)
    b  # 
    list(b)  # [1,2,3,4,5]
    
    c = filter(lambda x:True if x!=0 else False,a)
    list(c)  # [1,2,3,4,5]
    
    c = filter(lambda x:x,a)
    list(c)  # [1,2,3,4,5]
    
  • 列表推导式
  • # 基本格式:
    variable = [i for i in input_list if 条件判断]  # for i in input_list 是for循环,for i in input_list 中的i是一个循环变量名,每次遍历可迭代序列然后添加第一个变量i,if条件判断会对第一个i进行筛选
    # variable 列表名,可自定义
    # i 循环变量名
    # input_list 可迭代序列
    # if 条件判断,如果不写的话,默认所有条件都成立
    
    # 需求:如何快速生成一个 0-9 列表
    a = [i for i in range(10)]
    a  # [0,1,2,3,4,5,6,7,8,9]
    a = [i for i in range(10) if i>3]
    a  # [4,5,6,7,8,9]
    
    # 需求:生成一个列表,列表内的元素为a列表每个元素的三次方
    a = [1,2,3,4,5]
    # map lambda
    b = map(lambda x:x**3,a)
    list(b)  # [1,8,27,64,125]
    c = [i**3 for i in a]
    c  # [1,8,27,64,125]
    
    # 需求:将字典里面的键,保存到一个列表c中
    d = {'lemon':5,'apple':3,'pear':4}
    c = [i for i in d.keys()]
    c  # ['lemon','apple','pear']
    
    # 扩展:将字典里的键与值,进行替换
    e = {value:key for key,value in d.items()}
    e  # {5:'lemon',3:'apple',4:'pear'}
    
    

    2.26 文件和异常

  • 文件读取
    • open函数
      • open(file, mode='r',buffering=-1,encoding=None, errors=None, newline=None, closefd=True, opener=None)
      • 参数说明:
        • file:必需,文件路径(相对或绝对路径)
        • mode:可选,文件打开模式
        • encoding:一般使用utf-8
        • buffering:设置缓冲
        • errors:报错级别
        • newline:区分换行符
        • closefd:传入的file参数类型
      • mode 常用参数:
        • r : 以只读方式打开文件
        • w : 以只写方式打开文件
          • 如果改文件不存在,创建新文件
          • 如果改文件已存在,则覆盖原文件
        • a : 打开一个文件用于追加
          • 如果改文件已存在,则在最尾处追加写入
          • 如果改文件不存在,创建新文件进行写入
        • 更多mode参数说明,可访问:www.runoob.com/python/file…

    files/文本.txt

    Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
    Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
    Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
    Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。
    像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。
    现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。
    Python 2.7 被确定为最后一个 Python 2.x 版本,它除了支持 Python 2.x 语法外,还支持部分 Python 3.1 语法。
    

    main.py

    # 实现简单的文件读取操作
    # 文件的路径也可以用相对路径:files/文本.txt
    f = open('文本.txt 的绝对路径',mode='r',encoding='utf-8')
    data = f.read()
    print(data)
    f.close()  # 用open打开要用close将文件关闭
    
    # 为避免忘记close文件,可以用一下方式读取文件
    with open('files/文本.txt',mode='r',encoding='utf-8') as f:  # 用变量f来接收
      data = f.read()
      print(data)
    
    
  • 文件的读取格式
    • with open(file='file_path',mode='r',encoding='utf-8') as f:
      • data = f.read() # 返回整个文件数据,如果文件较大,不建议用这种方法
      • data1 = f.readline() # 返回一行数据
      • data2 = f.readlines() # 以列表格式,返回整个文件数据
  • 文件的写入格式
    • with open(file='file_path',mode='w',encoding='utf-8') as f:
      • file.write(str) # 将字符串写入文件
      • file.writeline(sequence) # 向文件写入一个序列字符串列表,如果需要换行则要自己加入换行符
  • 文件的写入
  • with open('files/文本.txt',mode='w',encoding='utf-8') as f:
      #f.write('hello lemonn hello world')
      f.writelines(['hello pycharmn','hello applen','hello'])
    
    with open('files/文本.txt',mode='a',encoding='utf-8') as f:
      f.write('hello lemonn hello world')
      f.writelines(['hello pycharmn','hello applen','hello'])
    
  • JSON与文件读写
    • (1)JSON(JavaScript Object Notation)特点:

      • 1)JSON 是一种轻量级的数据交换格式,易于人阅读和编写
      • 2)JSON 具有通用性,支持几乎所有的语言
      • 3)JSON 支持跨平台,支持 windows,Linux,Mac平台
    • (2)常用JSON函数

      • 1)json.dumps 将 Python 对象编码成 JSON 字符串
      • 2)json.loads 将 已编码的 JSON 字符串解码为 Python 对象
      • 3)json.dump 将 JSON 字符串数据写进文件
      • 4)json.load 读取 JSON 文件里面的数据
      • 5)python
        • {'python':1,'Java':2,'Hadoop':3}
        • {"python":1,"Java":2,"Hadoop":3}
      • 6)JSON
        • '{"python":1,"Java":2,"Hadoop":3}'
    • (3)Python 与 JSON 类型转换

      Python JSON
      dict object
      list, tuple array
      str string
      int, float number
      True true
      False false
      None null
      第一列文本居中 第二列文本居右
    import json
    
    def f1():
      '''
      对Python对象进行操作
      '''
    
      # json.dumps
      # 将 Python 对象编码成 JSON 字符串
      p_list = [
        {'lemon':True,'apple':6},
        {'pear':6,'banana':False},
      ]
      p_dict = {'python':1,'Java':2,'Hadoop':None}
      json_list = json.dumps(p_list)
      json_dict = json.dumps(p_dict)
    
    
    
      # json.loads
      # 将已编码的 JSON 字符串解码为 Python 对象
      list1 = json.loads(json_list)
      dict1 = json.loads(json_dict)
    
    
    
    def f2():
      '''
      文件的读写
      '''
    
      # 写入JSON文件
      p_dict = '{"python":1,"Java":2,"hadoop":null,"lemon":true,"banana":false}'
    
      with open('files/json_test.json','w',encoding='utf-8') as f:
        json.dump(p_dict,f)
    
    
      # 读取JSON文件
      with open('files/json_test.json','r',encoding='utf-8') as f:
        data = json.load(f)
        data1 = json.loads(data)
        print(data)
        print(data1)
    
    
    
    if __name__ == '__main__':
      f2()
    
  • try-except-finally捕捉异常
    • (1)什么是异常:
      • 1)异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
      • 2)一般情况下,在Python无法正常处理程序时就会发生一个异常
      • 3)异常是Python对象,表示一个错误
      • 4)当Python脚本发生异常时我们需要捕获处理,否则程序会终止执行
    • (2)捕获异常的基本格式
      try:
        语句一  # 检测语句一是否存在错误
      
      except 异常名称:
        语句二  # 若语句一存在错误,可以捕获错误
      
      finally:
        语句三  # 无论是否存在错误,都会执行finally内代码
        
      
    • (3)常见异常名称
      • BaseException: 所有异常错误
      • Exception: 常规异常错误
      • ZeroDivisionError: 除0异常错误
      • ValueError: 值类型异常错误
      • 更多异常错误,可查看:www.runoob.com/python/pyth…

    exception_demo.py

    def f(num):
      try:
        num / 0
      except ZeroDivisionError as e:
        print(e)
      finally:
        print('执行结束')
    
    def f1(num):
      try:
        return int(num)
      except ValueError as e:
        print(e)
      finally:
        print('执行结束')
    
    # 同时捕获多个异常
    def f2(num):
      try:
        return int(num)
      except ZeroDivisionError as e:
        print(e)
      except ValueError as e:
        print(e)
      finally:
        print('执行结束')
    
    # 同时捕获多个异常简写
    def f3(num):
      try:
        return int(num)
      except (ZeroDivisionError,ValueError) as e:
        print(e)
      finally:
        print('执行结束')
    
    def f4(num):
      try:
        return int(num)
      except BaseException as e:
        print(e)
      finally:
        print('执行结束')
    
    if __name__ == '__main__':
      # f(1)
      f1(a)
    
  • raise 与 asert
    • (1)raise 抛出异常
      • 除了使用 try-except-finally 格式来捕获异常
      • 也可以通过 raise 显示的引发异常
      • 一旦引发 raise 后面的异常,将终止程序运行
    • (2)assert 断言
      • assert 的异常参数,其实就是在断言表达式后添加字符串信息,用来解释断言并更好的知道是哪里出了问题
      • 基本格式:
        • assert expression [,arguments]
      • 如果 bool_expression 为 False,则会抛出 arguments 这个自定义异常信息
      • 如果 bool_expression 为 True,则不会抛出 arguments 这个自定义异常信息
    # 需求1:
    # 1. 传入一个参数,判断是否为整型类型,如果不是,则抛出异常,终止程序
    # 2. 判断是否大于等于5,如果小于5,则抛出异常,终止程序
    def f2(num):
      # if not isinstance(num,int):
      #   raise Exception('该参数不是一个整型类型')
      # if num =5,'该参数小于5'
    
    if __name__ == '__main__':
      f2('a')
    
    # 需求2:
    # 传入若干个参数,判断参数个数如果小于等于5,则抛出异常,终止程序
    def f3(*args):
      # if len(args)5,'该参数个数小于等于5'
    
    if __name__ == '__main__':
      f3(1,2,3,4,5)
    

    2.27 虚拟环境

  • 为什么要搭建虚拟环境
  •   项目A需要运行在Python2环境下,项目B需要运行在Python3环境下。
      项目A和项目B,使用同一个包,但是项目A需要使用该包的1.0版本,项目B需要使用该包的2.0版本
      那么创建虚拟环境,可以解决包管理的问题
    
  • 搭建虚拟环境
  •   pip install pipenv
      创建一个文件夹
      pipenv --three    会使用当前系统的Python3创建环境
      pipenv shell      激活虚拟环境
      pipenv --py       显示Python解释器信息
      exit              退出当前的虚拟环境
    
  • pipenv 常见操作
  •   (1)包下载
        下载包之前,将国外下载源,更改为国内源
        url = "https://pypi.tuna.tsinghua.edu.cn/simple"
        修改下载源在 Pipfile 文件中修改
        pipenv install requests
        pipenv install requests--2.21.0
      (2)查看当前下载包情况
        pip list
      (3)查看当前包依赖情况
        pipenv graph
      (4)更新包
        pipenv update requests  # 更新requests
        pipenv update           # 更新所有包
      (5)卸载包
        pipenv uninstall requests # 卸载requests包
        pipenv uninstall --all    # 卸载全部包并从Pipfile中移除
      (6)其他操作
        pipenv check  # 检查安全漏洞
    

    2.28 简单爬虫实战

  • HTML简单介绍
  • 超文本标记语言(HyperText Markup Language),是网页制作必备的变成语言。
    超文本,可以包含文字、图片、链接,甚至音乐、程序等元素
    
    超文本标记语言的结构包括“头”部分(英语:Head)、和“主体”部分(英语:Body)
    其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容
    

    基本格式:

    
    
    
      
      
      Document
    
    
      
    
    
    
  • XPath获取数据
    XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。

    常用路径表达式:

    表达式 描述
    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
    @ 选取属性
  • files/index.html

    
    
    
      
      
      Document
    
    
      这是一级标题
      这是二级标题
      这是一段文字
      
      
        hello lemon
        hello world
      
    
      这是三级标题
      
        python
        Java
        Hadoop
      
    
    
    

    xpath_demo.py

    from lxml.html import fromstring
    # fromstring 可以将字符串类型转换为html格式
    
    with open('files/index.html','r',encoding='utf-8') as f:
      data = f.read()
      print(data)
      print(type(data))   # 
    
    selector = fromstring(data)
    print(type(selector))   # 
    h1 = selector.xpath('/html/body/h1/text()')[0]
    h1 = selector.xpath('//h1/text()')[0]
    p = selector.xpath('/html/body/p/text()')[0]
    p = selector.xpath('//body/p/text()')[0]
    div_ul = selector.xpath('//div/ul/text()')
    div_p = selector.xpath('//div/p/text()')
    div_p = selector.xpath('//div[@id="list"]/p/text()')
    div_p = selector.xpath('//div[@id="list"]/p[last()]/text()')
    div_p = selector.xpath('//div[@id="list"]/p[@class="Hadoop"]/text()')
    
  • 爬虫原则
    • (1)明确爬取的内容
    • (2)分析网页结构,找到目标的标签
    • (3)分析目标标签,获取目标数据
    • (4)数据入库
  • 简单爬虫实战
  • (1)明确爬取的内容
      正在上映的电影
    (2)分析网页结构,找到目标的标签
      div[@id="nowplaying"]/div[@class="mod-bd"]/ul/li
    (3)分析目标标签,获取目标数据
      电影名称、电影评分、电影评分人数
      电影时长、上映年份、地区、导演、主要演员
    (4)数据入库
      写入到json文件里面
    
  • 断点调试
  •   Mac:      fn + f6   单步调试
                fn + f8   跳到下一个断点
      Window:   f6   单步调试
                f8   跳到下一个断点
    
    import requests   # requests 这个包的将目标网站拉取下来
    from lxml.html import fromstring
    import json
    
    class SpiderDouban():
      def __init__(self,url):
        self.url = url
        self.header = {
          'Accept': '',
          'Accept-Encoding': '',
          'Accept-Language': '',
          'Host': '',
          'Referer': '',
          'User-Agent': '',
          '': '',
        }
      def get_data(self):
        r = requests.get(url=self.url,headers=self.headers)
        data = fromstring(r.text)
        selector = data.xpath('//div[@id="nowplaying"]/div[@class="mod-bd"]/ul/li')
        for i in selector:
          title = i.xpath('@data-title')
          score = i.xpath('@data-score')
          votecount = i.xpath('@data-votecount')
          duration = i.xpath('@data-duration')
          ralease = i.xpath('@data-ralease')
          region = i.xpath('@data-region')
          director = i.xpath('@data-director')
          actors = i.xpath('@data-actors')
    
          print(title)
    
          movie_data.append({
            'title': title if title else '',
            'score': score if score else '',
            'votecount': votecount if votecount else '',
            'duration': duration if duration else '',
            'ralease': ralease if ralease else '',
            'region': region if region else '',
            'director': director if director else '',
            'actors': actors if actors else '',
          })
        with open('files/movie_data.json','w',encoding='utf-8') as f:
          json.dump(movie_data,f,indent=1,ensure_ascii=False)
    
    if __name__ == '__main__':
      s = SpiderDouban('https://movie.douban.com/...')
      s.get_data()
    

    3 Python 可深入的方向

    爬虫工程师:
      相关爬虫工具:Scrapy 爬虫框架、Selerium
      反爬策略(ip代理池、随机更换 User-Agent、Cookie禁用、自动限速等方法)
      数据库知识(如:Mysql  Oracle 等)
    Web开发工程师:
      相关框架:Django Flask
      前端知识:JavaScript CSS HTML
      数据库知识
    数据分析师:
      初级数据分析:
        数据库相关知识:Mysql  Oracle  MongoDB  Redis
      中高级数据分析:
        Python 数据科学常见包:Numpy  Pandas  Matplotlib  Scipy
        统计学知识:线性代数
        机器学习常见算法:线性回归法、梯度下降法、PCA、SW、决策树、随机森林等
    大数据方向:
      相关工具:Spark  Hadoop
      其他语言基础:Java SE
      Linux 相关知识
    人工智能方向:
      相关框架:TensorFlow (一个完全开源的人工智能框架)、Keras
      相关工具:Matplotlib 、 Numpy、TensorBoard
      Linux 相关知识
    

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论