Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90576
  • 博文数量: 51
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 255
  • 用 户 组: 普通用户
  • 注册时间: 2020-12-30 16:49
文章分类
文章存档

2021年(48)

2020年(3)

我的朋友

分类: Python/Ruby

2021-01-04 14:49:00

线程池概念:
线程池可以理解为一个装载多线程的池子,池中放置了指定数量的线程,当我们提交的任务超过线程池的数量时,多余的任务会进行排队等待,待其他任务执行完毕后,再将队列中的任务提交到线程执行,线程池的好处是,能同时执行多个任务,复用线程资源,减少线程的创建和销毁,更节约系统资源。
1.普通代码,理论是在一个线程执行任务,和其他语言类似,代码从上至下依次执行。
import time


>本期推送整理了初学者可能会用到的Python资料,含有书籍/视频/在线文档和编辑器/源
代码,关于`Python`的安装qun:850973621


def test_data(index):
    time.sleep(5)
    if index % 2 == 0:
        print(f'{index}执行错误。')
        raise Exception('我报错了')
    print(f'{index}执行完毕。')


for i in range(1, 50):
    test_data(i)
复制代码


输出:




1执行完毕。
Traceback (most recent call last):
  File "/Users/peakchao/Code/Py/ReptileForPython/pool_test.py", line 15, in
    test_data(i)
  File "/Users/peakchao/Code/Py/ReptileForPython/pool_test.py", line 11, in test_data
    raise Exception('我报错了')
Exception: 我报错了
2执行错误。
复制代码
分析:循环调用test_data方法,test_data方法中睡眠5秒后对传入的值进行取余,如果余数为0,则抛出异常,当i=1时,程序正常执行,在第二次循环时,i==2,取余等于0,抛出异常,程序崩溃退出。




注意:此时每过5秒才能打印依次。


2.多线程代码,理论是多个线程同时执行任务,线程池在不同语言中都有相似的实现。
import time
from concurrent.futures import ThreadPoolExecutor


pool = ThreadPoolExecutor(max_workers=2)




def test_data(index):
    time.sleep(5)
    if index % 2 == 0:
        print(f'{index}执行错误。')
        raise Exception('我报错了')
    print(f'{index}执行完毕。')




for i in range(0, 50):
    pool.submit(test_data, i)
复制代码


输出:




1执行完毕。0执行错误。


3执行完毕。
2执行错误。
4执行错误。
5执行完毕。
6执行错误。
7执行完毕。
复制代码
分析:同一时刻有2个打印,说明有2个任务在并行,如果我们把线程池数量改为n,那么他的执行效率是单线程的n倍。


请求伪装:
有时我们抓取网站数据时,服务器会返回错误,而我们使用浏览器访问却又能正常打开,是因为服务器分析了我们的请求数据,判断出我们是爬虫,所以终止了正常响应,当我们频繁抓取某个网站数据时,即使设置了请求伪装也会偶有失败,是因为请求信息固定,且有规律所以被拦截。
USER_AGENTS = [
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15',
    'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
    'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
    'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36'
]




def get_request_headers():
    headers = {
        'User-Agent': random.choice(USER_AGENTS),
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-language': 'zh-CN,zh;q=0.9',
        'Accept-Encoding': 'gzip, deflate,br',
        'Connection': 'keep-alive',
    }
    return headers
复制代码自定义异常:
往往系统定义的异常不能满足需求,为了抛出更明确的错误,以及后续对自己想要的错误进行拦截处理,我们需要自定义异常。
class BaseException(Exception):
    def __init__(self, msg):
        self.msg = msg


    def __str__(self):
        print(self.msg)




try:
    input_data = input('请输入:')
    if len(input_data) > 0:
        raise BaseException('哈哈,不允许输入任何文字哦~')
    print('执行完毕')
except BaseException as err:
    print(f'捕捉到自定义异常:{err}')
复制代码


输出:




请输入:666
哈哈,不允许输入任何文字哦~
哈哈,不允许输入任何文字哦~
Traceback (most recent call last):
  File "/Users/peakchao/Code/Py/ReptileForPython/pool_test.py", line 30, in
    raise BaseException('哈哈,不允许输入任何文字哦~')
__main__.BaseException:


During handling of the above exception, another exception occurred:


Traceback (most recent call last):
  File "/Users/peakchao/Code/Py/ReptileForPython/pool_test.py", line 33, in
    print(f'捕捉到自定义异常:{err}')
TypeError: __str__ returned non-string (type NoneType)


Process finished with exit code 1




作者:peakchao
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
阅读(15756) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~