• python正则+多线程(代理)+线程池+协程


    正则表达式

    常用元字符

    . 匹配除换行符以外的任意字符

    \w 匹配字幕或数字或下划线

    \s 匹配任意空白字符

    \d 匹配数字

    \n 匹配一个换行符

    \t 匹配一个制表符

    ^	匹配字符串的开始 # 开发常用
    $	匹配字符串的结尾
    
    • 1
    • 2

    \W 匹配非字母或数字或下划线

    \D 匹配非数字

    \S 匹配非空白符

    a|b 匹配字符a或b

    () 匹配括号内的表达式,也表示一个组

    […] 匹配字符组中的字符

    [^…] 匹配除字符组中字符的所有字符,**[ ]中的^**表示“非”

    量词

    * 	 重复0次或更多次
    + 	 重复1次或更多次
    ? 	 重复0次或1{n}	 重复n次
    {n,} 重复n次或更多次
    {n,m}重复n到m次
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    贪婪匹配,爬虫常用

    .*	 贪婪匹配
    .*?	 惰性匹配,尽可能间隔少的匹配
    
    • 1
    • 2

    python-re

    import re
    # findall:匹配字符串中所有正则内容
    lst = re.findall(r"\d+", "我的电话是10086,我孩子的电话是10010")
    print(lst)
    ['10086', '10010']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # finditer:匹配字符串中所有的内容【返回是迭代器】,从迭代器中拿到内容需要.group()
    # 最常用,效率高
    it = re.finditer(r"\d+", "我的电话是10086,我孩子的电话是10010")
    for i in it:
        print(i.group())
        
    10086
    10010
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    # search:返回的是match对象,拿数据需要.group()
    # 找到一个结果就返回,不找了
    # 常用
    s = re.search(r"\d+", "我的电话是10086,我孩子的电话是10010")
    print(s.group())
    
    10086
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    # match:从头匹配,拿数据需要.group()
    s = re.match(r"\d+", "10000我的电话是10086,我孩子的电话是10010")
    print(s.group())
    
    10000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 预加载正则,后面没有r''
    obj = re.compile(r"\d+")
    ret = obj.finditer("我的电话是10086,我孩子的电话是10010")
    for j in ret:
        print(j.group())
    # 可以反复用
    bhq = obj.findall("疑是银河落九天,为啥不还10000000")
    print(bhq)
    
    10086
    10010
    ['10000000']
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    s = """
    
    西游记
    三国演义
    水浒
    红楼666
    """
    obj = re.compile(r"
    .*?
    "
    , re.S) obj2 = re.compile(r"
    (?P.*?)
    "
    , re.S) # re.S 让.能匹配换行符 # (?P<分组名字>正则) 可以从正则匹配的内容中提取一部分 result = obj2.finditer(s) for it in result: print(it.group("wahaha"))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    代理

    # 设置代理
    proxies = {
        "https": "https://210.60.8.83:3129"
    }
    # 添加代理
    resp = requests.get("https://www.baidu.com", proxies =proxies)
    resp.encoding = 'utf-8'
    print(resp.text)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    多线程

    进程 - 资源单位

    线程 - 执行单位

    每个进程里至少一个线程,启动一个程序,默认都有一个主线程

    方法一:

    from threading import Thread
    
    def func():
        for i in range(1000):
            print("func", i)
    
    if __name__ == '__main__':
        t = Thread(target=func)  # 目标线程
        t.start()  # 多线程状态为开始工作状态,具体执行时间由cpu决定
    
        for i in range(1000):
            print("main", i)
            
    # 传参
    def func(name):
        for i in range(1000):
            print(name, i)
    if __name__ == '__main__':
        t = Thread(target=func, args=("周杰伦",))  # 目标线程,,args参数必须是 元组 传参
        t.start()  # 多线程状态为开始工作状态,具体执行时间由cpu决定
    
        for i in range(1000):
            print("main", i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    方法二:

    # 传参时,定义构造函数,def __init__(self):
    class myThread(Thread):
        def run(self):
            for i in range(1000): # 固定的 - > 当线程被执行的时候,被执行的就是run()
                print("子线程", i)
    
    if __name__ == '__main__':
        t = myThread()
        # t.run() # 此为方法的调用 - >仍然单线程进行
        t.start()  # 开启线程
    
        for i in range(1000):
            print("主线程", i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    # 多进程使用,创建多进程资源远远大于多线程
    # 写法跟线程一模一样,降低开发者记忆成本,资源使用完全不一样
    
    from multiprocessing import Process 
    def func():
        for i in range(1000):
            print("func", i)
    
    if __name__ == '__main__':
        p = Process(target=func)  # 目标线程
        p.start()  # 多线程状态为开始工作状态,具体执行时间由cpu决定
    
        for i in range(1000):
            print("main", i)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    线程池

    一般思路,先写单个实现,然后放到线程池

    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    def func(name):
        for i in range(1000):
            print(name, i)
    
    if __name__ == '__main__':
        # 创建线程池
        with ThreadPoolExecutor(50) as t:
            for i in range(100):
                # t.submit(func, name=f"线程-{i}")
                t.submit(func, name="changjiang")
        # 等待线程池中的任务全部执行完毕,才能继续执行(守护)
        print(123)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    协程

    当程序处于IO操作时,线程都会处于阻塞状态,cpu不为我工作

    例如:input(),sleep() ,request.get(),等等

    协程:当程序预见IO操作时,可以选择切换到其他任务上,为我工作!把cpu绑在我的程序上

    在微观上,是一个任务一个任务的进行切换,切换条件一般就是IO操作

    在宏观上,我们能看到其实是多个任务一起执行,多任务异步操作

    # @desc : 写爬虫的模板,协程应用,效率极高,相当于单线程
    
    import asyncio
    
    async  def download(url):
        print("准备开始下载")
        await asyncio.sleep(2)  # 网络请求; # requests.get() 是不行的
        print("下载完成")
    
    async def main():
        urls = [
            "http://www.baidu/com",
            "http://www.bilibili.com",
            "http://www.163.com"
        ]
        tasks = []
        for url in urls:
            # d = download(url) # python3.11之后会被干掉
            d = asyncio.create_task(download(url))  # python3.8之后的写法
            tasks.append(d)
        await asyncio.wait(tasks)
    
    if __name__ == '__main__':
        asyncio.run(main())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    爬虫视频处理

    一般的视频网站怎么做的?

    用户上传 -> 转码(把视频做成,2k,1080,标清) -> 切片处理(把单个的文件进行拆分) 60

    用户在进行拉动进度条时候,处理方式

    ==================

    需要一个文件记录:1.视频播放顺序。2.视频存放的路径。

    M3U8 txt json =>文本

    想要抓取一个视频:

    1. 找到m3u8(各种手段)

    2. 通过m3u8下载到ts文件

    3. 可以通过各种手段(不限于编程手段)把ts文件合并成一个mp4文件

  • 相关阅读:
    什么是架构
    Vue——ref/reactive、toRefs、计算属性、监视、Vue3响应式原理、Vue3生命周期
    SpringBoot+Vue实现前后端分离的大学生志愿者管理系统
    Oracle-单行函数大全
    C:sizeof运算符的一个陷阱
    视频监控/安防监控/AI视频分析/边缘计算/TSINGSEE青犀AI算法智慧仓储解决方案
    大学生游戏静态HTML网页设计 (HTML+CSS+JS仿英雄联盟网站15页)
    【跟学C++】C++映射类——map/multimap类(Study17)
    vue相关面试题
    【全志T113-S3_100ask】11-2编写驱动采集dht11数据(cdev、中断、锁)
  • 原文地址:https://blog.csdn.net/u013080870/article/details/131773060