python常见的内置模块

内置模块

  • python内部提供的功能
  • 导入模块后,直接使用便可

1、 random

  • 随机数模块python

  • randint:获得一个随机数mysql

import random    # 导入一个模块 
v = random.randint(起始,终止)    # 获得一个随机数

#示例:生成随机验证码
import random     
def get_random_code(length=6):
    data = []
    for i in range(length):
        v = random.randint(65,90)
        data.append(chr(v))
    return  ''.join(data)

code = get_random_code()
print(code)
  • uniform:生成一个随机小数
  • choice:抽取一个对象
    • 应用:验证码、抽奖
  • sample:抽取多个对象
    • 应用:一个奖项抽取多我的
  • shuffle:打乱顺序
    • 应用:洗牌、算法

2、 hashlib

  • 摘要算法模块
    • 密文验证
    • 校验文件的一致性
  • md5
# 将指定的 “字符串” 进行 加密
import hashlib     # 导入一个模块
def get_md5(data):          # md5 加密函数  
    obj = hashlib.md5()
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result
val = get_md5('123')
print(val)

# 加盐
import hashlib
def get_md5(data):
    obj = hashlib.md5("sidrsdxff123ad".encode('utf-8'))            # 加盐
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result
val = get_md5('123')
print(val)
# 应用:用户注册+用户登陆
import hashlib
USER_LIST = []
def get_md5(data):                   # md5 加密函数 
    obj = hashlib.md5("12:;idrsicxwersdfsaersdfs123ad".encode('utf-8'))         # 加盐
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result

def register():                      # 用户注册函数
    print('**************用户注册**************')
    while True:
        user = input('请输入用户名:')
        if user == 'N':
            return
        pwd = input('请输入密码:')
        temp = {'username':user,'password':get_md5(pwd)}
        USER_LIST.append(temp)

def login():                          # 用户登陆函数
    print('**************用户登录**************')
    user = input('请输入用户名:')
    pwd = input('请输入密码:')
    for item in USER_LIST:
        if item['username'] == user and item['password'] == get_md5(pwd):
            return True

register()
result = login()
if result:
    print('登录成功')
else:
    print('登录失败')
  • sha程序员

    import hashlib
    md5 = hashlib.sha1('盐'.encode())
    md5.update(b'str')
    print(md5.hexdigest())

3、 getpass

  • 只能在终端运行web

  • getpass.getpass:输入密码时不显示正则表达式

import getpass        # 导入一个模块
pwd = getpass.getpass('请输入密码:')
if pwd == '123':
    print('输入正确')

4、 time

  • 时间模块redis

  • time.time:时间戳(从1970年到如今经历的秒数)算法

    # https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=4ZwIFHM6iw==&tip=1&r=-781028520&_=1555559189206
  • time.sleep:等待的秒数sql

  • time.timezonejson

  • 示例app

    # 计算函数执行时间
    import time
    def wrapper(func):
        def inner():
            start_time = time.time()
            v = func()
            end_time = time.time()
            print(end_time-start_time)
            return v
        return inner
    @wrapper
    def func1():
        time.sleep(2)
        print(123)   
    func1()

5、 datetime

  • 时间模块

  • datetime.now():当前本地时间

  • datetime.utcnow():当前UTC时间

    import time
    from datetime import datetime,timezone,timedelta
    # 获取datetime格式时间
    # 当前本地时间
    v1 = datetime.now() 
    
    # 当前东7区时间
    tz = timezone(timedelta(hours=7)) 
    v2 = datetime.now(tz)
    
    # 当前UTC时间
    v3 = datetime.utcnow() 
    print(v3)
  • 相互转换

    import time
    from datetime import datetime,timedelta
    # 1.datetime格式和字符串的相互转换
    # 把datetime格式转换成字符串:strftime
    v1 = datetime.now()
    val = v1.strftime("%Y-%m-%d %H:%M:%S")
    # 字符串转成datetime格式:strptime
    v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    
    # 2.datetime时间的加减
    v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    v2 = v1 - timedelta(days=140)
    # 再转换成字符串
    date = v2.strftime('%Y-%m-%d')
    
    # 3.时间戳和datetime的相互转换
    # 时间戳转换成datetime格式:fromtimestamp
    ctime = time.time()
    v1 = datetime.fromtimestamp(ctime)
    # datetime格式转换成时间戳:timestamp
    v1 = datetime.now()
    val = v1.timestamp()

6、 sys

  • python解释器相关数据

  • sys.getrefcount:获取一个值的应用计数

  • sys.getrecursionlimit:python默认支持的递归数量

  • sys.stdout.write:输入输出

    • 补充:\n:换行 \t:制表符 \r:回到当前行的起始位置

      import time
      for i in range(1,101):
          msg = "%s%%\r" %i
          print(msg,end='')
          time.sleep(0.05)
    • 示例:读取文件的进度条

    import os
    # 1. 读取文件大小(字节)
    file_size = os.stat('20190409_192149.mp4').st_size
    
    # 2.一点一点的读取文件
    read_size = 0
    with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2:
        while read_size < file_size:
            chunk = f1.read(1024) # 每次最多去读取1024字节
            f2.write(chunk)
            read_size += len(chunk)
            val = int(read_size / file_size * 100)
            print('%s%%\r' %val ,end='')
  • sys.argv:获取用户执行脚本时,传入的参数

    • 示例:让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删
    """
    让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删除。
    C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
    C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py
    """
    
    import sys
    # 获取用户执行脚本时,传入的参数。
    # C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
    # sys.argv = [D:/code/s21day14/7.模块传参.py, D:/test]
    path = sys.argv[1]
    
    # 删除目录
    import shutil
    shutil.rmtree(path)
  • sys.exit(0):程序终止,0表明正常终止

  • sys.path:默认python去导入模块时,会按照sys.path中的路径

    • 添加目录:sys.path.append('目录')
    import sys
    sys.path.append('D:\\')
  • sys.modules:存储了当前程序中用到的全部模块,反射本文件中的内容

7、 os

  • 和操做系统相关的数据

  • os.path.exists(path):若是path存在,返回True;若是path不存在,返回False

  • os.stat('文件路径').st_size:获取文件大小

  • os.path.abspath():获取一个文件的绝对路径

    import os
    v1 = os.path.abspath(path)
    print(v1)
  • os.path.dirname():获取路径的上级目录

    import os
    v = r"D:\code\s21day14\20190409_192149.mp4"
    print(os.path.dirname(v))
    • 补充:转义

      v1 = r"D:\code\s21day14\n1.mp4"  (推荐)
      v2 = "D:\\code\\s21day14\\n1.mp4"
  • os.path.join:路径的拼接

    import os
    path = "D:\code\s21day14" # user/index/inx/fasd/
    v = 'n.txt'
    result = os.path.join(path,v)
    print(result)
  • os.listdir:查看一个目录下全部的文件【第一层】

    import os
    result = os.listdir(r'D:\code\s21day14')
    for path in result:
        print(path)
  • os.walk:查看一个目录下全部的文件【全部层】

    import os
    result = os.walk(r'D:\code\s21day14')
    for a,b,c in result:
        # a,正在查看的目录 b,此目录下的文件夹  c,此目录下的文件
        for item in c:
            path = os.path.join(a,item)
            print(path)
  • os.makedir:建立目录,只能生产一层目录(基本不用这个)

  • os.makedirs:建立目录及其子目录(推荐使用)

    # 将内容写入指定文件中
    import os
    file_path = r'db\xx\xo\xxxxx.txt'
    file_folder = os.path.dirname(file_path)
    if not os.path.exists(file_folder):
        os.makedirs(file_folder)
    with open(file_path,mode='w',encoding='utf-8') as f:
        f.write('asdf')
  • os.rename:重命名

    # 将db重命名为sb
    import os
    os.rename('db','sb')
  • os.path.isdir:判断是不是文件夹

  • os.path.isfile:判断是不是文件

8、 shutil

  • 用途:删除、重命名、压缩、解压等

  • shutil.rmtree(path):删除目录

    # 删除目录
    import shutil
    shutil.rmtree(path)
  • shutil.move:重命名

    # 重命名
    import shutil
    shutil.move('test','ttt')
  • shutil.make_archive:压缩文件

    # 压缩文件
    import shutil
    shutil.make_archive('zzh','zip','D:\code\s21day16\lizhong')
  • shutil.unpack_archive:解压文件

    # 解压文件
    import shutil
    shutil.unpack_archive('zzh.zip',extract_dir=r'D:\code\xxxxxx\xxxx',format='zip')
  • 示例

    import os
    import shutil
    from datetime import datetime
    ctime = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    # 1.压缩lizhongwei文件夹 zip
    # 2.放到到 code 目录(默认不存在)
    # 3.将文件解压到D:\x1目录中。
    if not os.path.exists('code'):
        os.makedirs('code')
    shutil.make_archive(os.path.join('code',ctime),'zip','D:\code\s21day16\lizhongwei')
    
    file_path = os.path.join('code',ctime) + '.zip'
    shutil.unpack_archive(file_path,r'D:\x1','zip')

9、 json

  • json是一个特殊的字符串,长得像列表/字典/字符串/数字等嵌套
  • 序列化:把python中的值转化为json格式的字符串
  • 反序列化:将json格式的字符串转换成python的数据类型
  • json格式要求:
    • 只包含 int / float / str / list / dict
    • 最外层必须是 list / dict
    • 在json中,内部str必须是双引号
    • 存在字典字典的key只能是str
    • 不能连续load屡次
  • json.dumps():序列化

    • json只支持 dict / list / typle / str / int / float / True / False / None 序列化
    • 字典或列表中若是有中文,序列化时,若是想保留中文显示
    import json
    v = {'k1':'alex','k2':'李杰'}
    val = json.dumps(v,ensure_ascii = False)
  • json.loads():反序列化

    import json
    # 序列化,将python的值转换为json格式的字符串。
    v = [12,3,4,{'k1':'v1'},True,'asdf']
    v1 = json.dumps(v)
    print(v1)
    
    # 反序列化,将json格式的字符串转换成python的数据类型
    v2 = '["alex",123]'
    print(type(v2))
    v3 = json.loads(v2)
    print(v3,type(v3))
  • json.dump:打开文件,序列化后,写入文件

    import json
    v = {'k1':'alex','k2':'李杰'}
    f = open('x.txt',mode='w',encoding='utf-8')
    val = json.dump(v,f)
    print(val)
    f.close()
  • json.load:打开文件,读取文件内容

    import json
    v = {'k1':'alex','k2':'李杰'}
    f = open('x.txt',mode='r',encoding='utf-8')
    data = json.load(f)
    f.close()
    print(data,type(data))

10、 pickle

  • pickle与json的区别
    • json
      • 优势:全部语言通用
      • 缺点:只能序列化基本的数据类型 list/dict 等
    • pickle
      • 优势:python中全部的东西都能被他序列化(socket对象),支持连续load屡次
      • 缺点:序列化的内容只有python认识
  • pickle.dumps:序列化

    • 序列化后的东西不可读
  • pickle.loads:反序列化

    import pickle
    # 序列化
    v = {1,2,3,4}
    val = pickle.dumps(v)
    print(val)
    
    # 反序列化
    data = pickle.loads(val)
    print(data,type(data))
  • pickle.dump:写入文件(注意:mode='wb')

  • pickle.load:读取文件(注意:mode='rb')

    import pickle
    # 写入文件
    v = {1,2,3,4}
    f = open('x.txt',mode='wb')
    val = pickle.dump(v,f)
    f.close()
    
    # 读取文件
    f = open('x.txt',mode='rb')
    data = pickle.load(f)
    f.close()
    print(data)

11、 copy

  • 拷贝模块

  • copy.copy:浅拷贝

  • copy.deepcopy:深拷贝

    import copy 
    v1 = [1,2,3]      
    v2 = copy.copy(v1)             #浅拷贝
    v3 = copy.deepcopy(v1)         #深拷贝

12、 importlib

  • importlib.import_module:经过字符串的形式导入模块

    #示例一:
    import importlib
    # 用字符串的形式导入模块。
    redis = importlib.import_module('utils.redis')
    
    # 用字符串的形式去对象(模块)找到他的成员。
    getattr(redis,'func')()
    
    #示例二:
    import importlib
    middleware_classes = [
        'utils.redis.Redis',
        # 'utils.mysql.MySQL',
        'utils.mongo.Mongo'
    ]
    for path in middleware_classes:
        module_path,class_name = path.rsplit('.',maxsplit=1)
        module_object = importlib.import_module(module_path)# from utils import redis
        cls = getattr(module_object,class_name)
        obj = cls()
        obj.connect()

十3、 logging

  • 日志模块:记录日志的

    • 给用户看的:流水类,如银行流水
    • 给程序员看的:
      • 统计用的
      • 用来作故障排除的,debug
      • 用来记录错误,完成代码的优化
  • 日志处理本质:Logger / FileHandler / Formatter

  • 两种配置方式:

    • basicConfig

      • 优势:使用方便
      • 缺点:不能实现编码问题,不能同时向文件和屏幕上输出
    • logger对象

      • 优势:能实现编码问题,能同时向文件和屏幕上输出
      • 缺点:复杂
      • 示例:
      import logging
      # 建立一个logger对象
      logger = logging.getLogger()
      # 建立一个文件操做符
      fh = logging.FileHandler('log.log')
      # 建立一个屏幕操做符
      sh = logging.StreamHandler()
      # 给logger对象绑定 文件操做符
      logger.addHandler(fh)
      # 给logger对象绑定 屏幕操做符
      logger.addHandler(sh)
      # 建立一个格式
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      # 给文件操做符 设定格式
      fh.setFormatter(formatter)
      # 给屏幕操做符 设定格式
      sh.setFormatter(formatter)
      # 用logger对象来操做
      logger.warning('message')
  • 日志异常级别

    CRITICAL = 50       # 崩溃
    FATAL = CRITICAL
    ERROR = 40          # 错误
    WARNING = 30
    WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0
  • 推荐处理日志方式

    import logging
    
    file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    logging.error('你好')
  • 推荐处理日志方式 + 日志分割

    import time
    import logging
    from logging import handlers
    # file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
    file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8')
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    for i in range(1,100000):
        time.sleep(1)
        logging.error(str(i))

    注意事项:

    # 在应用日志时,若是想要保留异常的堆栈信息。
    import logging
    import requests
    
    logging.basicConfig(
        filename='wf.log',
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        level=logging.ERROR
    )
    
    try:
        requests.get('http://www.xxx.com')
    except Exception as e:
        msg = str(e) # 调用e.__str__方法
        logging.error(msg,exc_info=True)

十4、 collections

  • OrderedDict:有序字典

    from collections import OrderedDict
    odic = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    print(odic)
    for k in odic:
        print(k,odic[k])
  • defaultdict:默认字典

  • deque:双端队列

  • namedtuple:可命名元组

    # 建立一个类,这个类没有方法,全部属性的值都不能修改
    from collections import namedtuple       # 可命名元组
    Course = namedtuple('Course',['name','price','teacher'])
    python = Course('python',19800,'alex')
    print(python)
    print(python.name)
    print(python.price)

十5、 re

15.1 正则表达式

  • 定义

  • 定义:正则表达式是一种规则匹配字符串的规则
  • re模块自己只是用来操做正则表达式的,和正则自己不要紧
  • 为何要有正则表达式?
    • 匹配字符串
      • 一我的的电话号码
      • 一我的的身份证号
      • 一台机器的ip地址
    • 表单验证
      • 验证用户输入的信息是否准确
      • 银行卡号
    • 爬虫
      • 从网页源码中获取一些连接、重要数据
  • 正则规则

  • 第一条规则 : 自己是哪个字符,就匹配字符串中的哪个字符
  • 第二条规则 : 字符组[字符1字符2],一个字符组就表明匹配一个字符,只要这个字符出如今字符组里,那么就说明这个字符能匹配上
    • 字符组中还可使用范围
    • 全部的范围都必须遵循ascii码从下到大来指定
    • 经常使用:[0-9] [a-z] [A-Z]
  • 元字符

  • \d:表示全部的数字
    • \是转义符 转义符转义了d,让d可以匹配全部0-9之间的数
  • \w:表示大小写字母、数字、下划线
  • \s:表示空白、空格、换行符、制表符
  • \t:匹配制表符
  • \n:匹配换行符
  • \D:表示全部的非数字
  • \W:表示除数字、字母、下划线以外的全部字符
  • \S:表示非空白
  • . :表示除了换行符以外的任意内容
  • [] 字符组:只要在中括号内的全部字符都是符合规则的字符
  • [^ ]非字符组:只要在中括号内的全部字符都是不符合规则的字符
  • ^:表示一个字符的开始
  • $:表示一个字符的结束
  • |:表示或
    • 注意:若是两个规则有重叠部分,老是长的在前面,短的在后面
  • ():表示分组,给一部分正则规定为一组,|这个符号的做用域就能够缩小了
  • 特殊:
    • [\d]、[0-9]、\d:没有区别 都是要匹配一位数字
    • [\d\D]、[\W\w]、[\S\s] 匹配全部一切字符
  • 量词

  • {n}:表示只能出现n次
  • {n,}:表示至少出现n次
  • {n,m}:表示至少出现n次,至多出现m次
  • ?:表示匹配0次或1次,表示无关紧要,可是有只能有一个,好比小数点
  • +:表示匹配1次或屡次
  • *:表示匹配0次或屡次,表示无关紧要,可是有能够有多个好比小数点后n位
  • 匹配0次出现的状况:
    • 匹配任意的保留两位小数的数字
    • 匹配一个整数或者小数
  • 贪婪匹配

  • 默认贪婪匹配,老是会在符合量词条件的范围内尽可能多匹配
  • 非贪婪匹配 :惰性匹配
    • 老是匹配符合条件范围内尽可能小的字符串
    • 格式:元字符 量词 ? x
      • 表示按照元字符规则在量词范围内匹配,一旦遇到x就中止
      • 示例:.*?x 匹配任意的内容任意屡次遇到x就当即中止
  • 转义符:
  • 正则表达式中的转义符在python的字符串中也恰好有转移的做用
  • 可是正则表达式中的转义符和字符串中的转义符并不要紧,且还容易有冲突
  • 为了不这种冲突,咱们全部的正则都以在工具中的测试结果为结果
  • 而后只须要在正则和待匹配的字符串外面都加r便可

邮箱规则
@以前必须有内容且只能是字母(大小写)、数字、下划线(_)、减号(-)、点(.)
@和最后一个点(.)之间必须有内容且只能是字母(大小写)、数字、点(.)、减号(-),且两个点不能挨着
最后一个点(.)以后必须有内容且内容只能是字母(大小写)、数字且长度为大于等于2个字节,小于等于6个字节

邮箱验证的正则表达式:
^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$

15.2 正则模块

  • re.findall:会匹配字符串中全部符合规则的项,并返回一个列表,若是没匹配到,返回空列表

    import re
    ret = re.findall('\d+','alex83')
    print(ret)
    # findall 会匹配字符串中全部符合规则的项
    # 并返回一个列表
    # 若是未匹配到返回空列表
  • re.search:若是匹配到,返回一个对象,用group取值,若是没匹配到,返回None,不能用group

    import re
    ret = re.search('\d+','alex83')
    print(ret)                 # 若是能匹配上返回一个对象,若是不能匹配上返回None
    if ret:
        print(ret.group())     # 若是是对象,那么这个对象内部实现了group,因此能够取值
                               # 若是是None,那么这个对象不可能实现了group方法,因此报错
    # 会从头至尾从带匹配匹配字符串中取出第一个符合条件的项
    # 若是匹配到了,返回一个对象,用group取值
    # 若是没匹配到,返回None,不能用group
  • re.match:match = search + ^正则

    import re
    ret = re.match('\d','alex83') == re.match('^\d','alex83')
    print(ret)
    # 会从头匹配字符串,从第一个字符开始是否符合规则
    # 若是符合,就返回对象,用group取值
    # 若是不符合,就返回None
  • re.finditer:在查询的结果超过1个的状况下,可以有效的节省内存,下降空间复杂度,从而也下降了时间复杂度

    import re
    ret = re.finditer('\d','safhl02urhefy023908'*20000000)  # ret是迭代器
    for i in ret:    # 迭代出来的每一项都是一个对象
        print(i.group())  # 经过group取值便可
  • re.compile:在同一个正则表达式重复使用屡次的时候使用可以减小时间的开销

    import re
    ret = re.compile('\d+')
    r1 = ret.search('alex83')
    r2 = ret.findall('wusir74')
    r3 = ret.finditer('taibai40')
    for i in r3:
        print(i.group())
  • re.split:利用正则规则进行切割

    import re
    ret = re.split('\d(\d)','alex83wusir74taibai')  # 默认自动保留分组中的内容
    print(ret)
  • re.sub / re.subn:利用正则规则进行替换

    import re
    ret = re.sub('\d','D','alex83wusir74taibai',1)
    print(ret)      # 'alexD3wusir74taibai'
    
    ret = re.subn('\d','D','alex83wusir74taibai')
    print(ret)      # ('alexDDwusirDDtaibai', 4)
  • 分组和re模块

  • 关于group取值

    import re
    ret = re.search('<(\w+)>(.*?)</\w+>',s1)
    print(ret)
    print(ret.group(0))   # group参数默认为0 表示取整个正则匹配的结果
    print(ret.group(1))   # 取第一个分组中的内容
    print(ret.group(2))   # 取第二个分组中的内容
  • 分组命名:(?P <名字> 正则表达式)

    import re
    ret = re.search('<(?P<tag>\w+)>(?P<cont>.*?)</\w+>',s1)
    print(ret)
    print(ret.group('tag'))   # 取tag分组中的内容
    print(ret.group('cont'))   # 取cont分组中的内容
  • 引用分组:(?P=组名) 这个组中的内容必须彻底和以前已经存在的组匹配到的内容如出一辙

    import re
    # 方法一:
    s = '<h1>wahaha</h1>'
    ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',s)
    print(ret.group('tag'))      # 'h1'
    
    # 方法二:
    s = '<h1>wahaha</h1>'
    ret = re.search(r'<(\w+)>.*?</\1>',s)
    print(ret.group(1))          # 'h1'
  • 分组和findall:默认findall 优先显示分组内的内容,取消分组优先显示 :(?:正则)

    import re
    ret = re.findall('\d(\d)','aa1alex83')
    # findall遇到正则表达式中的分组,会优先显示分组中的内容
    print(ret)
    
    # 取消分组优先显示:
    ret = re.findall('\d+(?:\.\d+)?','1.234+2')
    print(ret)
  • 有的时候咱们想匹配的内容包含在不相匹配的内容当中,这个时候只须要把不想匹配的先匹配出来,再经过手段去掉

    import re
    ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret)       # ['1', '2', '60', '', '5', '4', '3']
    ret.remove('')
    print(ret)       # ['1', '2', '60', '5', '4', '3']
  • 爬虫示例

    # 方法一:
    import re
    import json
    import requests
    
    def parser_page(par,content):
        res = par.finditer(content)
        for i in res:
            yield {'id': i.group('id'),
                   'title': i.group('title'),
                   'score': i.group('score'),
                   'com_num': i.group('comment_num')}
    
    def get_page(url):
        ret = requests.get(url)
        return  ret.text
    
    
    pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \
                  '<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>'
    par = re.compile(pattern,flags=re.S)
    num = 0
    with open('movie_info',mode = 'w',encoding='utf-8') as f:
        for i in range(10):
            content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num)
            g = parser_page(par,content)
            for dic in g:
                f.write('%s\n'%json.dumps(dic,ensure_ascii=False))
            num += 25
    # 方法二:进阶
    import re
    import json
    import requests
    
    def parser_page(par,content):
        res = par.finditer(content)
        for i in res:
            yield {'id': i.group('id'),
                   'title': i.group('title'),
                   'score': i.group('score'),
                   'com_num': i.group('comment_num')}
    
    def get_page(url):
        ret = requests.get(url)
        return  ret.text
    
    def write_file(file_name):
        with open(file_name,mode = 'w',encoding='utf-8') as f:
            while True:
                dic = yield
                f.write('%s\n' % json.dumps(dic, ensure_ascii=False))
    
    pattern = '<div class="item">.*?<em class="">(?P<id>\d+)</em>.*?<span class="title">(?P<title>.*?)</span>.*?' \
                  '<span class="rating_num".*?>(?P<score>.*?)</span>.*?<span>(?P<comment_num>.*?)人评价</span>'
    par = re.compile(pattern,flags=re.S)
    num = 0
    f = write_file('move2')
    next(f)
    for i in range(10):
        content = get_page('https://movie.douban.com/top250?start=%s&filter=' % num)
        g = parser_page(par,content)
        for dic in g:
            f.send(dic)
        num += 25
    f.close()
相关文章
相关标签/搜索