0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用AioHttp异步抓取火星图片

马哥Linux运维 来源:Python编程学习圈 作者:Python编程学习圈 2022-03-16 09:58 次阅读

创建aiohttp应用程序

让我们从一个简单的应用程序开始,只是为了启动和运行aiohttp。首先,创建一个新的virtualenv。建议使用Python 3.5以后版本,因为我们将使用asyncio提供的async defawait语法。如果您想进一步开发该项目并利用异步理解的优势,则可以使用Python 3.6(本例使用python版本)。

接下来,安装aiohttp:

pip install aiohttp

现在创建一个python文件(称为nasa.py),并将一些代码放入其中:

from aiohttp import web

async def get_mars_photo(request):
    return web.Response(text='A photo of Mars')

app = web.Application()
app.router.add_get('/', get_mars_photo, name='mars_photo')

如果您不熟悉aiohttp,则可能需要说明以下几点:

  • get_mars_photo协程是一个请求处理程序;它以HTTP请求作为唯一参数,并负责返回HTTP响应(或引发异常)

  • app是高级服务器;它支持路由器,中间件和信号(对于该程序,我们将仅使用路由器)

  • app.router.add_get在HTTP GET方法和'/'路径上注册请求处理程序

注意:请求处理程序不必一定是协程,它们可以是常规函数。但是我们将使用asyncio的功能,因此程序中的大多数函数都将使用进行定义async def

运行应用程序

要运行您的应用程序,您可以在文件末尾添加以下行:

web.run_app(app, host='127.0.0.1', port=8080)

然后像运行其他任何Python脚本一样运行它:

python nasa.py

但是有更好的方法。在许多第三方库中,您可以找到aiohttp-devtools。它提供了一个很好的runserver命令,可以自动检测您的应用并支持实时重载:
pip install aiohttp-devtools
adev runserver -p 8080 nasa.py

在如果您访问localhost:8080,则应该在浏览器中看到"A photo of mars"的字样。

使用NASA API

当然,这还没有结束。如果您是一位敏锐的观察者,您会注意到我们没有得到实际的图像,而是一些文本。现在让我们解决这个问题。

要从火星获取照片,我们将使用NASA API。每个火星探路者(rover)都有自己的URL(对于好奇号,它url是https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos)。我们必须为每个请求至少提供2个参数:

  • sol:火星轮转或拍摄照片的日期,从探路者的着陆日期开始算起(最大值可以rover/max_sol在响应的一部分中找到)

  • API_KEY:由美国航天局提供的API密钥(你可以使用默认的:DEMO_KEY

响应数据里我们将获得一张照片列表,每张照片均带有URL,相机信息和探路者信息。

修改nasa.py文件,如下所示:

import random

from aiohttp import web, ClientSession
from aiohttp.web import HTTPFound

NASA_API_KEY = 'DEMO_KEY'
ROVER_URL = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos'


async def get_mars_image_url_from_nasa():
    while True:
        sol = random.randint(0, 1722)
        params = {'sol': sol, 'api_key': NASA_API_KEY}
        async with ClientSession() as session:
            async with session.get(ROVER_URL, params=params) as resp:
                resp_dict = await resp.json()
        if 'photos' not in resp_dict:
            raise Exception
        photos = resp_dict['photos']
        if not photos:
            continue
        return random.choice(photos)['img_src']


async def get_mars_photo(request):
    url = await get_mars_image_url_from_nasa()
    return HTTPFound(url)

到底发生了什么事?

  • 我们选择一个随机拍摄日期(对于“好奇心”max_sol,在撰写本文时,其值为1722)

  • ClientSession创建一个会话,我们可以使用该会话从NASA API获取响应

  • 我们使用获取JSON响应resp.json()

  • 我们检查响应中是否存在“照片”键;如果没有,我们已经达到了每小时请求数量的上限,我们需要稍等片刻

  • 如果当天没有照片,我们会再次检查是否有其他拍摄时间

  • 然后,我们使用HTTPFound响应重定向到找到的照片

获取NASA API密钥

DEMO_KEYNASA提供的默认设置可以正常工作,但是您很快就会达到每小时API调用的限制。我建议您获取自己的API密钥。您可以在此处进行操作(注册过程非常简单快捷)。

现在,当您运行该应用程序时,您将直接从火星重定向到一个漂亮的图像:


好吧,这不完全是我的意思...

验证图像

您刚刚看到的图像并不让人受到启发。事实证明,漫游者拍摄了很多非常无聊的照片。我想看看马克·沃特尼(Mark Watney)在他不可思议的旅程中所看到的,但这还不够好。让我们找到一种解决方法。

我们将需要对图像进行某种形式的验证。在指定筛选条件前,我们可以修改代码:

async def get_mars_photo_bytes():
    while True:
        image_url = await get_mars_image_url_from_nasa()
        async with ClientSession() as session:
            async with session.get(image_url) as resp:
                image_bytes = await resp.read()
        if await validate_image(image_bytes):
            break
    return image_bytes


async def get_mars_photo(request):
    image = await get_mars_photo_bytes()
    return web.Response(body=image, content_type='image/jpeg')

这里发生了一些新的事情:

  • 我们使用先前定义的函数获取URL,然后使用读取图像中的原始字节resp.read()

  • 我们检查我们的图片是否足够好;如果没有,我们一直在寻找

  • 一旦有了令人满意的照片,我们会将其放入响应中(注意,我们仍然使用与web.Response以前相同的照片,但是这次我们指定body而不是text,同时了定义content_type

注意:在此代码中,我们删除了重定向(HTTPFound),因此现在我们可以轻松地刷新页面以获取另一个图像。

现在我们需要弄清楚如何验证照片。我们可以很容易做到的一件事就是检查图像尺寸否足够大。这不是一个完美的验证,但现在应该这样做。要处理图像,我们将需要python的图片库Pillow。

pip install pillow

我们的验证函数可能如下所示:

import io
from PIL import Image

async def validate_image(image_bytes):
    image = Image.open(io.BytesIO(image_bytes))
    return image.width >= 1024 and image.height >= 1024

现在刷新浏览器,应该可以看到火星大图了。

现在我们可以更进一步,拒绝灰度图像:

async def validate_image(image_bytes):
    image = Image.open(io.BytesIO(image_bytes))
    return image.width >= 1024 and image.height >= 1024 and image.mode != 'L'

在我们的程序开始返回更多鼓舞人心的照片:

尔还能看到机器人自拍:

总结

我们整个程序如下所示:

import random
import io

from aiohttp import web, ClientSession

from PIL import Image

NASA_API_KEY = 'DEMO_KEY'
ROVER_URL = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos'


async def validate_image(image_bytes):
    image = Image.open(io.BytesIO(image_bytes))
    return image.width >= 1024 and image.height >= 1024 and image.mode != 'L'


async def get_mars_image_url_from_nasa():
    while True:
        sol = random.randint(0, 1722)
        params = {'sol': sol, 'api_key': NASA_API_KEY}
        async with ClientSession() as session:
            async with session.get(ROVER_URL, params=params) as resp:
                resp_dict = await resp.json()
        if 'photos' not in resp_dict:
            raise Exception
        photos = resp_dict['photos']
        if not photos:
            continue
        return random.choice(photos)['img_src']


async def get_mars_photo_bytes():
    while True:
        image_url = await get_mars_image_url_from_nasa()
        async with ClientSession() as session:
            async with session.get(image_url) as resp:
                image_bytes = await resp.read()
        if await validate_image(image_bytes):
            break
    return image_bytes


async def get_mars_photo(request):
    image = await get_mars_photo_bytes()
    return web.Response(body=image, content_type='image/jpeg')


app = web.Application()
app.router.add_get('/', get_mars_photo, name='mars_photo')

我们还可以改善很多事情(例如max_sol从API中获取价值,传递流动站的名称,缓存URL),但是现在它已经完成了工作:我们可以得到一张随机的,鼓舞人心的火星照片,并觉得我们确实在那里。

原文标题:Python | AioHttp 异步抓取火星图片

文章出处:【微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 文件
    +关注

    关注

    1

    文章

    561

    浏览量

    24693
  • 程序
    +关注

    关注

    116

    文章

    3773

    浏览量

    80835
  • python
    +关注

    关注

    56

    文章

    4781

    浏览量

    84441

原文标题:Python | AioHttp 异步抓取火星图片

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ADI AD6645转换器帮助捕捉令人惊叹的高清晰火星图片

    ADI公司的转换器技术正在波尔航天的高分辨率成像科学实验 (HiRISE) 相机内工作,帮助科学家获得有史以来最为精细的火星图片
    发表于 08-23 10:47 1064次阅读

    “钻木取火”才能点亮的台灯

    `现在电子产品千奇百怪,好的创意才会让人眼前一亮,就比如这款“钻木取火”的台灯。就很有意思,所以想给大家介绍一下,希望各位以后在创新电子产品的时候也能够有好的点子。关于人类最开始是怎么制造出了火
    发表于 02-15 15:39

    异步电动机图片

    `异步电动机图片`
    发表于 04-15 15:54

    labview如何做到到指定文件夹下抓取图片

    labview如何做到到指定文件夹下抓取图片
    发表于 08-20 20:37

    为好奇号火星探测器提供视野

    夏普山(Mount Sharp)和火星地理的其它特性。下一发现将是什么尚不清楚,但无论好奇号发现什么,我们将一路跟随。若您有兴趣了解更多关于好奇号探测器的信息,最好先访问美国航天局为这任务建立的网站,它还包括由这探测器上的科学摄像机拍摄的完整的图片集。
    发表于 11-01 08:59

    数据抓取问题

    新人想做一个装置,用于抓取水质监测数据,假设现在水质监测系统已经建成,但是想通过数据抓取装置获取水质数据,类似图片的形式,请问大佬们可以怎么实现
    发表于 11-02 11:18

    ADI转换器帮助捕捉令人惊叹的高清晰火星图片

    在距离地球数百万英里的火星轨道上,Analog Devices, Inc.(ADI)公司的转换器技术正在波尔航太的高解析度成像科学实验 (HiRISE) 相机内工作,帮助科学家获得有史以来最为精细的火星
    发表于 08-24 09:23 954次阅读

    C#教程之抓取整站图片

    C#教程之抓取整站图片,很好的C#资料,快来学习吧。
    发表于 04-20 11:13 5次下载

    C#教程之抓取左上角图片

    C#教程之抓取左上角图片,很好的C#资料,快来学习吧。
    发表于 04-20 11:13 3次下载

    基于嵌入式的卫星图像处理系统的研究

    随着科技的不断进步,我国发射的功能专一的商业卫星数量越来越多,卫星图像数据内容也越来越丰富。以往的图像处理系统日渐达不到设备的小型化便携式需求,所以我们提出基于嵌入式的单幅卫星图片影像处理系统的方案
    发表于 01-30 14:04 0次下载

    火星探测器什么时候登陆火星_火星探测器飞行速度是多少

    火星探测器,是一种用来探测火星的人造航天器,包括从火星附近掠过的太空船、环绕火星运行的人造卫星、登陆火星表面的着陆器、可在
    发表于 12-14 15:08 1.1w次阅读

    如何通过html+css样式和js的方式实现星星图的效果

    在浏览一些图片网站的时候,经常会看到很多的漂亮的星空图,比如,下面的图片。其实这种星星图片的效果,也可以通过html+css样式和js的方式来实现。今天教大家如何实现星星图的效果。
    的头像 发表于 12-24 18:13 1815次阅读

    美国“毅力号”火星车成功登陆火星

    当地时间2月18日下午,美国“毅力号”火星车成功登陆火星,成为美国国家航空航天局(NASA)第5个成功登陆的火星车。 据悉,本次“毅力号”将在火星采集样本并试图寻找生命存在的证据。 N
    的头像 发表于 02-19 09:27 2548次阅读

    美国毅力号火星车成功登陆火星

    当地时间2月18日下午,美国“毅力号”火星车成功登陆火星,成为美国国家航空航天局(NASA)第5个成功登陆的火星车。
    的头像 发表于 02-19 09:39 4727次阅读

    用来细致观察火星的“火眼金睛”是如何“炼”成的

    “高分辨率相机是火星探测器的重要载荷。”高分辨率相机主任设计师董吉洪说,此次探测任务的工程目标是实现火星环绕探测和巡视探测,获取火星探测科学数据,而高分辨率相机搭载在环绕器上,主要用于对火星
    的头像 发表于 03-09 14:24 1555次阅读