python3-python中的多任务处理利器-协程的使用(二),aiohttp与aiofiles模块的使用

【提升效率】学会使用aiofiles模块,让Python文件操作更高效! aiofiles是一个Python库,它提供了异步文件操作的功能,基于Python的asyncio库。通过使用aiofiles,我们可以在异步程序中进行文件的读取、写入和操作,而不会阻塞事件循环。这对于需要处理大量文件或需要与其他异步操作结合的场景非常有用。aiofiles模块为异步文件操作提供了便利的功能,使得在异步环境中处理文件变得更加简单和高效。通过使用aiofiles,我们可以在异步程序中轻松地进行文件的读取、写入和操作,而不会阻塞事件循环。 阅读详情

一、aiohttp的使用

1、安装与使用

pip install aiohttp 

2、简单实例使用

aiohttp的自我介绍中就包含了客户端和服务器端,所以我们分别来看下客户端和服务器端的简单实例代码。

  • 客户端:
import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()


async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, "http://httpbin.org/headers")
        print(html)

asyncio.run(main())


"""输出结果:
{
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "Python/3.7 aiohttp/3.6.2"
  }
}
"""

这个代码是不是很简单,一个函数用来发起请求,另外一个函数用来下载网页。

3、入门

  • 简单示范

首先是学习客户端,也就是用来发送http请求的用法。首先看一段代码,会在代码中讲述需要注意的地方:

import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://httpbin.org/get') as resp:
            print(resp.status)
            print(await resp.text())

asyncio.run(main())
  • 代码解释:

在网络请求中,一个请求就是一个会话,然后aiohttp使用的是ClientSession来管理会话,所以第一个重点,看一下ClientSession:

class ClientSession:
    """First-class interface for making HTTP requests."""

在源码中,这个类的注释是使用HTTP请求接口的第一个类。然后上面的代码就是实例化一个ClientSession类然后命名为session,然后用session去发送请求。这里有一个坑,那就是ClientSession.get()协程的必需参数只能是str类和yarl.URL的实例。

当然这只是get请求,其他的请求都是支持的:

session.post('http://httpbin.org/post', data='data')
session.get('http://httpbin.org/get')

4、在URL中传递参数

有时候在发起网络请求的时候需要附加一些参数到url中,这一点也是支持的。

import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession() as session:
        params = {'key1': 'value1', 'key2': 'value2'}
        async with session.get('http://httpbin.org/get',
                               params=params) as resp:
            print(resp.url)

asyncio.run(main())

我们可以通过params参数来指定要传递的参数,

同时如果需要指定一个键对应多个值的参数,那么MultiDict就在这个时候起作用了。你可以传递两个元祖列表来作为参数:

import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession() as session:
        params = [('key', 'value1'), ('key', 'value2')]

        async with session.get('http://httpbin.org/get',
                               params=params) as r:
            expect = 'http://httpbin.org/get?key=value2&key=value1'
            # assert str(r.url) == expect
            print(r.url)
asyncio.run(main())

5、读取响应内容

我们可以读取到服务器的响应状态和响应内容,这也是使用请求的一个很重要的部分。通过status来获取响应状态码,text()来获取到响应内容,当然也可以之计指明编码格式为你想要的编码格式:

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://httpbin.org/get') as resp:
            print(resp.status)
            print(await resp.text(encoding=utf-8))
            
"""输出结果:
200
<!doctype html>
<html lang="zh-CN">
<head>
......

"""

6、非文本内容格式

对于网络请求,有时候是去访问一张图片,这种返回值是二进制的也是可以读取到的:

await resp.read()

将text()方法换成read()方法就好。

7、请求的自定义

ClientResponse(客户端响应)对象含有request_info(请求信息),主要是url和headers信息。 raise_for_status结构体上的信息会被复制给ClientResponseError实例。

(1) 自定义Headers

有时候做请求的时候需要自定义headers,主要是为了让服务器认为我们是一个浏览器。然后就需要我们自己来定义一个headers:

headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko)"
                      " Chrome/78.0.3904.108 Safari/537.36"
    }
await session.post(url, headers=headers)
(2) 如果出现ssl验证失败的处理
import aiohttp
import asyncio
from aiohttp import TCPConnector


async def main():
    async with aiohttp.ClientSession(connector=TCPConnector(ssl=False)) as session:
		pass
asyncio.run(main())
(3) 自定义cookie

发送你自己的cookies给服务器,你可以为ClientSession对象指定cookies参数:

url = 'http://httpbin.org/cookies'
cookies = {'cookies_are': 'working'}
async with ClientSession(cookies=cookies) as session:
    async with session.get(url) as resp:
        assert await resp.json() == {
           "cookies": {"cookies_are": "working"}}
(4) 使用代理

有时候在写爬虫的时候需要使用到代理,所以aiohttp也是支持使用代理的,我们可以在发起请求的时候使用代理,只需要使用关键字proxy来指明就好,但是有一个很难受的地方就是它只支持http代理,不支持HTTPS代理。使用起来大概是这样:

proxy = "http://127.0.0.1:10809
async with aiohttp.ClientSession(headers=headers) as session:
  async with session.get(url=login_url, proxy=proxy) as response:
    resu = await response.text()

使用起来大概是这样,然后代理记得改成自己的。

二、aiofiles文件读写

1 aiofiles的安装

pip install aiofiles

这个插件的使用和python原生open 一致,而且可以支持异步迭代

2 概述

平常使用的file操作模式为同步,并且为线程阻塞。当程序I/O并发次数高的时候,CPU被阻塞,形成闲置。

线程开启文件读取异步模式

用线程(Thread)方式来解决。硬盘缓存可以被多个线程访问,因此通过不同线程访问文件可以部分解决。但此方案涉及线程开启关闭的开销,而且不同线程间数据交互比较麻烦。

from threading import Thread
for file in list_file:
     tr = Thread(target=file.write, args=(data,))
     tr.start()

使用已编写好的第三方插件-aiofiles,支持异步模式

使用aio插件来开启文件的非阻塞异步模式。

3 举例

  • 打开文件
import asyncio
import aiofiles

async def main():
    async with aiofiles.open('first.m3u8', mode='r') as f:
        contents = await f.read()
        print(contents)

if __name__ == '__main__':
    asyncio.run(main())
  • 迭代
import asyncio
import aiofiles

async def main():
    async with aiofiles.open('filename') as f:
        async for line in f:
            print(line)

if __name__ == '__main__':
    asyncio.run(main())

三、并发控制

  • semaphore,控制并发
semaphore = asyncio.Semaphore(10) 
  • 实例
#!/usr/bin/python

import asyncio
import os
import aiofiles
import aiohttp
import requests
from bs4 import BeautifulSoup


def get_page_source(web):
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'
    }
    response = requests.get(web, headers=headers)
    response.encoding = 'utf-8'
    return response.text


def parse_page_source(html):
    book_list = []
    soup = BeautifulSoup(html, 'html.parser')
    a_list = soup.find_all('div', attrs={'class': 'mulu-list quanji'})
    for a in a_list:
        a_list = a.find_all('a')
        for href in a_list:
            chapter_url = href['href']
            book_list.append(chapter_url)
    return book_list


def get_book_name(book_page):
    book_number = book_page.split('/')[-1].split('.')[0]
    book_chapter_name = book_page.split('/')[-2]
    return book_number, book_chapter_name


async def aio_download_one(chapter_url, signal):
    number, c_name = get_book_name(chapter_url)
    for c in range(10):
        try:
            async with signal:
                async with aiohttp.ClientSession() as session:
                    async with session.get(chapter_url) as resp:
                        page_source = await resp.text()
                        soup = BeautifulSoup(page_source, 'html.parser')
                        chapter_name = soup.find('h1').text
                        p_content = soup.find('div', attrs={'class': 'neirong'}).find_all('p')
                        content = [p.text + '\n' for p in p_content]
                        chapter_content = '\n'.join(content)
                        if not os.path.exists(f'{book_name}/{c_name}'):
                            os.makedirs(f'{book_name}/{c_name}')
                        async with aiofiles.open(f'{book_name}/{c_name}/{number}_{chapter_name}.txt', mode="w",
                                                 encoding='utf-8') as f:
                            await f.write(chapter_content)
                        print(chapter_url, "下载完毕!")
                        return ""
        except Exception as e:
            print(e)
            print(chapter_url, "下载失败!, 重新下载. ")
    return chapter_url


async def aio_download(url_list):
    tasks = []
    semaphore = asyncio.Semaphore(10)
    for h in url_list:
        tasks.append(asyncio.create_task(aio_download_one(h, semaphore)))
    await asyncio.wait(tasks)


def test:
    url = 'https://www.51shucheng.net/daomu/guichuideng'
    book_name = '鬼吹灯'
    if not os.path.exists(book_name):
        os.makedirs(book_name)
    source = get_page_source(url)
    href_list = parse_page_source(source)
    loop = asyncio.get_event_loop()
    loop.run_until_complete(aio_download(href_list))
    loop.close()

if __name__ == '__main__':
    test()

协程就介绍到这里。

python使用aiofiles进行异步文件操作 Python是一种非常流行的编程语言,它在文件操作方面也有很好的支持。但是,当需要进行大量文件操作时,传统的同步方式可能会导致程序变得非常缓慢。这时,异步文件操作就成为了一个非常好的选择。在Python中,我们可以使用aiofiles库来进行异步文件操作。 阅读详情

相关推荐

Python异步编程:使用`aiofiles`进行异步文件操作

Python异步编程:使用`aiofiles`进行异步文件操作

engchina的专栏 1513

python 异步模式操作文件 aiofiles库 简介

目录 线程开启文件读取异步模式 使用已编写好的第三方插件-aiofiles,支持异步模式 安装方法 打开文件 迭代,Asynchronous iteration 插件可支持的属性 参考: 平常使用的file操作模式为同步,并且为线程阻塞。当程序I/O并发次数高的时候,CPU被阻塞,形成闲置。现在我总结下目前python3.6以后的异步使用文件解决方案: 线程开启文件读取异步模式 用线程(Thread)方式来解决。硬盘缓存可以被多个线程访问,因此通过不同线程访问文件可以部分解决。但此方

whatday的专栏 6986

高效编程——协程

asyncio模块是python3.4版本引入的标准库,直接内置了对异步IO的操作编程模式是一个消息循环,我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO说明到目前为止实现协程的不仅仅只有asyncio,tornado和gevent都实现了类似功能关键字的说明关键字说明event_loop消息循环,程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数coroutine。

m0_74653634的博客 1077

aiofiles,一个超酷的 Python 异步编程库!

在异步编程中,文件操作是一项常见且重要的任务。Python提供了asyncio库来支持异步编程,但是在处理文件时,标准库中的文件操作函数并不支持异步操作。为了解决这个问题,出现了aiofiles库。本文将深入探讨aiofiles库的各个方面,包括其基本概念、功能、使用方法、应用场景以及示例代码。

m0_67847535的博客 1860

python项目实战——多协程下载美女图片

I/O 密集型任务(I/O-bound task)是指那些在执行过程中主要受限于输入/输出(I/O)操作性能的任务。这类任务的执行效率往往取决于数据的读写速度,而不是 CPU 处理能力。I/O 密集型任务是在执行中高度依赖于数据交换和处理速度的任务。理解 I/O 密集型任务的概念有助于在设计和优化系统时选择合适的编程模型和架构。因为爬虫主要就是和网络进行交互,不太消耗我们自己电脑的CPU,负责接收网路返回的数据,是一种写入操作,就是适合爬虫。

FZ51111的博客 1425

2024 高级爬虫笔记(四)协程、selenium

asyncio模块是python3.4版本引入的标准库,直接内置了对异步IO的操作- 编程模式是一个消息循环,我们从asyncio模块中直接获取一个EventLoop的引用然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO- 说明到目前为止实现协程的不仅仅只有asyncio,tornado和gevent都实现了类似功能- 关键字的说明| event_loop | 消息循环,程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数 |

小陈工的博客 2094

python3 异步 asyncio aiohttp aiohttp-requests aiofiles 使用

asyncio asyncio 是用来编写并发代码的库,使用async/await语法。 asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。 asyncio 往往是构建 IO 密集型和高层级结构化网络代码的最佳选择。 aiohttp aiohttp是一个为Python提供异步HTTP 客户端/服务端编程,基于asyncio(Python用于支持异步编程的标准库)的异步库。在爬虫时提供异步网络请求,而常用到的req...

whatday的专栏 3381

掌握Python异步编程:aiohttp与aiofiles的使用

本文深入探讨了如何在Python中使用异步I/O进行高效网络和文件操作。通过aiohttp库实现非阻塞的网络请求,以及利用aiofiles库进行异步文件读写,读者可以了解如何在保持程序响应性的同时,处理大量I/O密集型任务。文章还涵盖了错误处理和异步编程的优势,为开发者提供了高效处理并发任务的实用工具和策略。

weixin_36078669的博客 591

python中的异步编程:asyncio 和aiohttp 的结合使用(aiohttp-requests、aiofiles)

asyncio asyncio 是用来编写并发代码的库,使用async/await语法。 asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。 asyncio 往往是构建 IO 密集型和高层级结构化网络代码的最佳选择。 aiohttp aiohttp是一个为Python提供异步HTTP 客户端/服务端编程...

西门大盗 捉虫专家 4934

Bode图、ABCD矩阵与EET结合:三步搞定复杂电路传递函数分析

在模拟电路与电源控制设计中,传递函数和频率响应是衡量系统稳定性的核心指标。Bode图以直观的幅频/相频曲线揭示带宽与相位裕度,ABCD二端口矩阵可将级联网络结构化表达,而EET额外元素定理则针对寄生电容、负载效应等局部修正提供显式公式。三者互补,组合成一套从整体拓扑到局部寄生修正的完整分析方法:先用ABCD搭建主体网络,再用EET快速加入额外元件,最后用Bode图验证传递函数和稳定裕度。该方法适用于滤波器设计、电源环路补偿、运放稳定性分析等线性小信号场景,支持Python/SciPy和SPICE交叉验证,显

weixin_32496547的博客 362

PaddleOCR实战:从零开始训练自己的OCR模型(附完整代码与数据集处理技巧)

本文提供了一份详尽的PaddleOCR实战指南,手把手教你从零开始训练专属的OCR模型。内容涵盖高质量训练数据的准备与标注技巧、预训练模型的选型对比、关键参数调优策略,并附有完整的代码示例。通过遵循本文的步骤,开发者可以高效构建并优化贴合自身业务场景的高精度OCR模型,实现从数据到部署的全流程掌握。

weixin_29263201的博客 570

python协程万字详解!!!

asyncio模块是python3.4版本引入的标准库,直接内置了对异步IO的操作编程模式是一个消息循环,我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO说明到目前为止实现协程的不仅仅只有asyncio,tornado和gevent都实现了类似功能关键字的说明关键字说明event_loop消息循环,程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数coroutine。

墨城的博客 1126

基于深度学习的UWB门禁检测

针对基于UWB技术智能门禁管理系统,由于测距误差或非视距原因导致门禁产生不合理动作的现象。分析如何采用基于深度学习的方法,通过对TWR测距数据、TWR监听数据、到达角度差(PDOA)、信道脉冲响应(CIR)等数据维度进行深度学习,利用 TensorFlow建立相应的推导模型,对卡片姿态进行更加精准可靠的检测,从而更好完成闸机开合控制。

tenth_quadrant的博客 2026

Python 异步协程:asyncio、async/await、aiohttp

Windows GUI 主线程消息循环是典型。

freeking101的博客 4390

c++ mysql_init 返回无效指针_C++操作MYSQL遇到的一些问题

首先 我使用的是 vcpkg上面是我装的一些库《大大安利vcpkg 安装时一定要使用powershell进行编译装上vcpkg后装ligmariadb这个库,这个对Mysql操作还是挺方便的,然后说一下 在装库时碰到的一些问题1.网络问题1.参考了一下 github上的答案 将下载失败的url拷下来 自己下 然后再重新开始安装《vcpkg在安装时每一个需要下载的 都会提供url-仔细找,2.这个问...

weixin_32176627的博客 680

详解AUTOSAR:专栏总述

本专栏系统介绍AUTOSAR规范及车用控制器软件开发,内容覆盖基础架构、SWC/RTE、通信栈、诊断、存储、安全、看门狗、工具链、环境配置与项目实战,并持续更新各模块的集成机制与工程要点。

不脱发的程序猿 3916

9.爬虫必备基础(协程)

asyncio模块是python3.4版本引入的标准库,直接内置了对异步IO的操作编程模式是一个消息循环,我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO说明到目前为止实现协程的不仅仅只有asyncio,tornado和gevent都实现了类似功能关键字的说明关键字说明event_loop消息循环,程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数coroutine。

歌颂平凡的博客 1056

Google antigravity 不支持你所在地区?手把手教你把账号改成支持地区

Google antigravity功能火爆,但国内老账号根本用不了🤬本文分享几种有效的账号国家地区切换方法,最快几分钟就能让antigravity直接亮起🔥

XiaoqiangClub的博客 2万+

python爬虫之协程知识点记录

ClientResponse(客户端响应)对象含有request_info(请求信息),主要是url和headers信息。结构体上的信息会被复制给ClientResponseError实例。有时候做请求的时候需要自定义headers,主要是为了让服务器认为我们是一个浏览器。然后就需要我们自己来定义一个headers:Win64;x64) "平常使用的file操作模式为同步,并且为线程阻塞。当程序I/O并发次数高的时候,CPU被阻塞,形成闲置。线程开启文件读取异步模式。

jolinoy的博客 1062

全国青少年信息素养大赛图形化(Scratch)编程考点总结

全国青少年信息素养大赛图形化(Scratch)编程考点总结

伶俐角少儿编程 380

DeepSeek+Cline:开启自动化编程新纪元

随着 AI 技术不断进步,编程领域迎来效率变革。DeepSeek 与 Cline 的结合,成为自动化编程的强大工具。DeepSeek 凭借先进的自然语言处理能力,能精准理解编程需求;Cline 作为 VSCode 插件,可实现代码生成、调试、注释等功能的无缝衔接。本文详细阐述二者安装配置、实战操作流程,涵盖从基础代码生成到复杂项目开发的应用技巧,同时解答常见问题,帮助开发者快速掌握这对 “智能搭档”,提升编程效率,解锁自动化编程的无限可能。

邓邓子的博客 6254

Python中aiohttp和aiofiles模块的安装

Python中aiohttp和aiofiles模块的安装

Gaara01193的博客 2331

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Python爬虫之协程

后,内部代码是不会执行的,只是得到了一个协程对象,如果想要运行协程对象,则必须将其交给事件循环来处理。包裹的协程任务遇到阻塞时会自动从当前任务切换到另一个任务中,以节省时间和内存。与python中常用的with open操作类似,并且支持异步操作,且与。关键字后面可以定义可等待对象,例如协程对象,Future,Task对象。:接受一个任务集合作为参数,并等待所有任务完成。:接受一个任务集合作为参数,并等待所有任务完成。:执行单个任务,返回每个任务的实际返回值。此处的可等待对象其实就是I/O阻塞,当。

AZURE060606的博客 2192

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

asyncio+aiohttp+aiofiles实现异步下载妹子图片

因为不熟悉的缘故,总觉得写的不好,一种异步代码与同步代码参杂着的感觉,希望能够得到指点。 import os import re import aiofiles import aiohttp import asyncio from lxml import etree # 发请求获取html文本 async def fetch(session, url): async with ses...

weixin_34186128的博客 5288

Python异步爬虫之协程抓取妹子图片(aiohttp、aiofiles)

本文主要介绍使用协程进行异步爬虫,提高爬取效率以及资源的最大化利用率

xuxiaoka1的博客 1290

Python-协程

所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。如果我想在执行 A 函数的时候,可以随时中断,去执行 B 函数,然后中断B函数,继续执行 A 函数 (可以自动切换),但这一过程并不是函数调用(没有调用语句),过程很像多线程,然而协程只有一个线程在执行。通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,切换的次数以及什么时候再切换到原来的函数都由开发者自己确定。

weixin_45203607的博客 921
上一篇: python3-python中的多任务处理利器-协程的使用(一),asyncio模块的使用
下一篇: python3-python使用代理进行数据的请求,代理服务器。
liranke
博客等级 码龄20年 4939粉丝 594原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值