python异步协程爬虫的简单案例

1.协程初步

协程就是一个函数,但是满足以下特征:
1.有I/O依赖的操作,
2.可以在进行I/O操作时暂停,
3.无法直接执行
它的作用就是对有大量I/O操作的程序进行加速
Python协程属于可等待对象,可以在其他协程中被等待。
说白了,就是在一个有I/O操作的线程等待I/O执行时,去切换下一个线程运行。
小栗子

import asyncio
# async 标记函数是异步函数
async def net():
    return 11

async def main():
    # net() 没办法直接调用
    res = await net()
    print(res)

asyncio.run(main())

在这里插入图片描述
用睡眠模仿异步I/O操作

"""
用睡眠模仿异步I/O函数
"""
import asyncio

async def hello(i):
    print("Hello ", i)
    # 不能使用常规的睡眠机制
    await asyncio.sleep(3)
    print("World ", i)

if __name__ == '__main__':
    tasks = []	#创建一个任务列表
    for i in range(4):
        tasks.append(hello(i))
    # 获取事件循环
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
2.使用异步协程来爬取笑话大全
import asyncio
import aiohttp
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.13'
                  '0 Safari/537.36'
}


# http://xiaohua.zol.com.cn/lengxiaohua/
async def crawl(i):
    url = "http://xiaohua.zol.com.cn/lengxiaohua/{}.html".format(str(i))
    print("正在爬取。。。", i)
    async with aiohttp.ClientSession(headers=headers) as session:
        async with session.get(url) as resp:
            print(resp.status)
            text = await resp.text()

    soup = BeautifulSoup(text, 'lxml')
    list = soup.select('.article-list .article-title a')
    for li in list:
        print(li.get_text())


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    tasks = [crawl(i) for i in range(1, 10)]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()

3.使用线程池的异步操作
"""
使用requests的异步
"""
import asyncio,requests
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.13'
                  '0 Safari/537.36'
}
def crawl(i):
    print("正在执行",i)
    url = "http://xiaohua.zol.com.cn/lengxiaohua/{}.html".format(i)
    html = requests.get(url,headers=headers)
    print(html.status_code)
    soup = BeautifulSoup(html.text,'lxml')
    list = soup.select('.article-list .article-title a')
    for li in list:
        print(li.get_text())


async def main():
    loop = asyncio.get_event_loop()
    tasks = []
    with ThreadPoolExecutor(max_workers=10) as t:
        for i in range(1,10):
            tasks.append(loop.run_in_executor(
                t,	# 线程池执行器
                crawl,	# 要执行的方法,
                i		#传入的参数
            ))
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()
4.分布式Celery的简单操作

分布式计算思想:
将大任务分散成几个小任务,交给分布式网络中的计算机去完成。
在分布式计算的环境中,必须保证网络中计算机的可用性(避免网络延迟,非预知的崩溃等)。
所以就需要可以可持续的监控框架。
有一个分布式系统基础特征产生的问题:网络由不同操作系统的计算机组成,很多互不兼容。
所以有了兼容不同环境的框架,比如Celery。
说白了,Celery就是将提交的高并发量的任务,转交给其余服务端来处理。
在这里插入图片描述
分布式爬取笑话大全的一个小栗子

# 服务端
from celery import Celery
import requests
from bs4 import BeautifulSoup
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.13'
                  '0 Safari/537.36'
}
app = Celery(
    'tasks',
    backend='redis://127.0.0.1:6379/0',   # Celery处理完结果后存储到哪里
    broker='redis://127.0.0.1:6379/1'     # broker 消息代理分发器,分发任务
)

# 装饰器,表明这是一个Celery的任务 ,这里只定义了一个任务
@app.task
def get_html():
    print("正在执行")
    url = "http://xiaohua.zol.com.cn/lengxiaohua/1.html"
    html = requests.get(url, headers=headers)
    print(html.status_code)
    soup = BeautifulSoup(html.text, 'lxml')
    list = soup.select('.article-list .article-title a')
    result = ''     #任务返回的结果
    for li in list:
        print(li.get_text())
        result += li.get_text()
    return result
# 客户端
from server import get_html
from celery.result import AsyncResult

tasks = []

for i in range(10):
    task = get_html.delay() # 这是celery获取结果的ID
    tasks.append(task)      # 将这些ID存储起来,为了以后能找到相应结果

for t in tasks:
    print(AsyncResult(t.get()))

这里只是一个小栗子。了解一下Celery。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
异步协程爬虫是利用Python中的异步编程和协程机制来实现高效的网络爬虫。通过使用异步协程,可以在一个线程中同时处理多个网络请求,提高爬取数据的效率。 在Python中,可以使用asyncio库来实现异步协程爬虫。下面是一个简单异步协程爬虫示例代码: ```python import asyncio import aiohttp async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(): urls = ['http://example.com', 'http://example.org', 'http://example.net'] async with aiohttp.ClientSession() as session: tasks = [] for url in urls: task = asyncio.create_task(fetch(session, url)) tasks.append(task) responses = await asyncio.gather(*tasks) for response in responses: print(response) if __name__ == '__main__': asyncio.run(main()) ``` 在上面的代码中,我们首先定义了一个`fetch`函数,用于发送异步HTTP请求并返回响应的内容。然后,在`main`函数中,我们创建了一个异步的`ClientSession`对象,用于发送并发的HTTP请求。接着,我们使用`asyncio.create_task`函数创建了多个任务,并将其添加到任务列表中。最后,使用`asyncio.gather`函数等待所有任务完成,并打印每个响应的内容。 通过使用异步协程爬虫,可以实现高效的并发请求,从而加快爬取数据的速度。同时,由于使用了异步编程的机制,还可以避免阻塞主线程,提高整个程序的运行效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值