Python 通常 + マルチスレッド (プロキシ) + スレッド プール + コルーチン

正規表現

一般的なメタキャラクター

. は改行を除く任意の文字に一致します

\w はサブタイトル、数字、アンダースコアと一致します

\s は任意の空白文字に一致します

\d は数字と一致します

\n は改行文字と一致します

\t はタブ文字と一致します

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

\W は英数字以外またはアンダースコアと一致します

\D は数字以外に一致します

\S は空白以外の文字に一致します

a|b は文字 a または b と一致します

() は括弧で囲まれた式と一致し、グループを示します

[…] 文字グループ内の文字と一致します

[^…] は文字グループ内の文字を除くすべての文字に一致します。**[ ] の ^** は「not」を意味します

数量詞

* 	 重复0次或更多次
+ 	 重复1次或更多次
? 	 重复0次或1{
    
    n}	 重复n次
{
    
    n,} 重复n次或更多次
{
    
    n,m}重复n到m次

貪欲なマッチング、クローラーによってよく使用されます

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

Python-re

import re
# findall:匹配字符串中所有正则内容
lst = re.findall(r"\d+", "我的电话是10086,我孩子的电话是10010")
print(lst)
['10086', '10010']
# finditer:匹配字符串中所有的内容【返回是迭代器】,从迭代器中拿到内容需要.group()
# 最常用,效率高
it = re.finditer(r"\d+", "我的电话是10086,我孩子的电话是10010")
for i in it:
    print(i.group())
    
10086
10010
# search:返回的是match对象,拿数据需要.group()
# 找到一个结果就返回,不找了
# 常用
s = re.search(r"\d+", "我的电话是10086,我孩子的电话是10010")
print(s.group())

10086
# match:从头匹配,拿数据需要.group()
s = re.match(r"\d+", "10000我的电话是10086,我孩子的电话是10010")
print(s.group())

10000
# 预加载正则,后面没有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']

s = """
<div class='red'><span id='1'>西游记</span></div>
<div class='green'><span id='2'>三国演义</span></div>
<div class='blue'><span id='3'>水浒</span></div>
<div class='yellow'><span id='4'>红楼666</span></div>
"""
obj = re.compile(r"<div class='.*?'><span id='\d+'>.*?</span></div>", re.S)
obj2 = re.compile(r"<div class='.*?'><span id='\d+'>(?P<wahaha>.*?)</span></div>", re.S)

# re.S  让.能匹配换行符
# (?P<分组名字>正则)  可以从正则匹配的内容中提取一部分
result = obj2.finditer(s)
for it in result:
    print(it.group("wahaha"))

演技

# 设置代理
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 つのスレッドがあり、プログラムを開始します。デフォルトでメインスレッドがあります。

方法 1:

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)

方法 2:

# 传参时,定义构造函数,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)
# 多进程使用,创建多进程资源远远大于多线程
# 写法跟线程一模一样,降低开发者记忆成本,资源使用完全不一样

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 つの実装を作成し、それをスレッド プールに入れることです。

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)

コルーチン

プログラムが 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())

クローラービデオ処理

一般的な動画サイトはどうなっているのでしょうか?

ユーザーアップロード -> トランスコーディング (ビデオを 2k、1080、SD に作成) -> スライス処理 (個々のファイルを分割) 60

ユーザーがプログレスバーを引っ張っているときの処理方法

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

記録するファイルが必要です: 1. ビデオ再生シーケンス。2. ビデオが保存されるパス。

M3U8 txt json => テキスト

ビデオを取得するには:

  1. m3u8 を見つける (さまざまな方法で)

  2. m3u8経由でtsファイルにダウンロード

  3. ts ファイルは、さまざまな手段 (プログラミング手段に限定されない) で 1 つの mp4 ファイルに結合できます。

おすすめ

転載: blog.csdn.net/u013080870/article/details/131773060