自学 python 中的异步编程 asyncio:实战(一)爬虫

1 先过一遍代码

  • 以下是一个简单的异步爬虫示例代码,它演示了如何使用asyncioaiohttp库实现异步爬虫:
import asyncio
from datetime import datetime

import aiohttp
import logging
from bs4 import BeautifulSoup

# 首先通过调用 basicConfig 方法进行配置,指定了日志级别为 INFO,输出格式为 "[时间] [级别] [消息]"
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')


# 利用“漂亮汤”解析出电影标题
def parse(response):
    soup = BeautifulSoup(response, 'lxml')
    print(soup.select("#content > h1 > span:nth-child(1)")[0].get_text())

    
async def fetch(url, session):
    # 简单设置了请求头来防止反扒,不同情况要根据具体网站设置
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299",
        "Referer": "https://www.google.com/"
    }
    
	# 异步请求指定 url,并返回响应文本内容
    async with session.get(url, headers=headers) as response:
        # 在这里添加打印日志的功能,使用 logging 模块进行打印
        logging.info(f'[{datetime.now()}] Crawled {url}, Response code: {response.status}')
        return await response.text()


async def crawl(urls):
    # 创建一个 aiohttp 的 ClientSession,它是异步上下文管理器,负责与 HTTP 服务器进行通信
    async with aiohttp.ClientSession() as session:
        tasks = []
        for url in urls:
            logging.info(f'Start crawling {url}')
            # 创建一个 asyncio 的协程任务,使用 ensure_future 或者 create_task 方法都可以
            task = asyncio.ensure_future(fetch(url, session))
            tasks.append(task)

        # 如果没有传入任何链接,即 tasks 列表为空,我们输出一个警告日志,提示用户当前没有链接需要爬取。
        if not tasks:
            logging.warning('No links to crawl.')
            return []

        # 并发运行多个协程任务,gather 方法接收一个可迭代对象,将其所有的协程任务加入事件循环中,并等待它们全部完成
        responses = await asyncio.gather(*tasks)

        # 返回所有协程任务的响应结果列表
        return responses


if __name__ == '__main__':
    # urls = [...]  # 待爬取的 URL 列表
    urls = ["https://movie.douban.com/subject/1292052/", "https://movie.douban.com/subject/1291546/"]
    
    new_loop = asyncio.new_event_loop()
    asyncio.set_event_loop(new_loop)
    
    responses = new_loop.run_until_complete(crawl(urls))
    
    # 对 responses 进行处理
    for res in responses:
        parse(res)

2 简答解析一下代码

  • 这是一个我写的爬取豆瓣 top3 电影名字的爬虫
  • 当然本篇重点不是爬什么东西,而是理解怎么利用协程来写爬虫
  • 代码主要分为两个部分:
  1. fetch函数:该函数使用aiohttp库向给定的URL发送HTTP GET请求,并返回响应文本
  2. crawl函数:该函数使用aiohttp库建立异步HTTP会话,然后使用asyncio.gather()方法并发发送HTTP请求,最终将所有响应文本集中返回
  • 在主程序中,我们可以使用asyncio.new_event_loop()方法获取一个异步事件循环对象
  • 然后通过调用loop.run_until_complete()方法运行异步协程crawl()
  • crawl()函数将异步执行网络请求,并在完成后返回响应文本
  • 我们可以在主程序中进一步处理 parse 这些响应

3 运行结果

2023-05-01 15:49:47,705 INFO Start crawling https://movie.douban.com/subject/1292052/
2023-05-01 15:49:47,706 INFO Start crawling https://movie.douban.com/subject/1291546/
2023-05-01 15:49:47,706 INFO Start crawling https://movie.douban.com/subject/1292720/
2023-05-01 15:49:48,915 INFO [2023-05-01 15:49:48.915036] Crawled https://movie.douban.com/subject/1292052/, Response code: 200
2023-05-01 15:49:49,011 INFO [2023-05-01 15:49:49.011986] Crawled https://movie.douban.com/subject/1291546/, Response code: 200
2023-05-01 15:49:49,379 INFO [2023-05-01 15:49:49.379012] Crawled https://movie.douban.com/subject/1292720/, Response code: 200
肖申克的救赎 The Shawshank Redemption
霸王别姬
阿甘正传 Forrest Gump

进程已结束,退出代码0

总的来说,这个异步爬虫示例代码简单易懂,使用了asyncioaiohttp库,使得异步爬取数据更加高效

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值