0
点赞
收藏
分享

微信扫一扫

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

金牛豆豆 2023-07-19 阅读 72

正则表达式

常用元字符

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

量词

* 	 重复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)

多线程

方法一:

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)

方法二:

# 传参时,定义构造函数,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)

线程池

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)

协程

# @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())

爬虫视频处理

举报

相关推荐

0 条评论