• 售前

  • 售后

热门帖子
入门百科

python 基于AioHttp 异步抓取火星图片

[复制链接]
王胜军 显示全部楼层 发表于 2021-10-26 12:53:05 |阅读模式 打印 上一主题 下一主题
目次


  • 创建aiohttp应用程序

    • 运行应用程序

  • 使用NASA API

    • 获取NASA API密钥

  • 验证图像
  • 总结
  1. 翻译:大江狗
  2. 原文链接:https://pfertyk.me/2017/06/getting-mars-photos-from-nasa-using-aiohttp/
复制代码
小编注:aiohttp是基于asyncio实现的异步http框架。
本文案例也可以使用异步django实现。
我是Andy Weir写的《火星人》一书的老实粉丝。阅读时,我想知道马克·沃特尼(Mark Watney)绕着赤色星球走的感觉怎样。近来,多亏了 Twilio的这篇博文, 我发现NASA提供了一个公共API,可以提供火星环游者拍摄的照片。但是,由于不是MMS的老实附和者,我决定编写本身的应用程序,以将具有开导性的图像直接转达到我的浏览器中。

创建aiohttp应用程序


让我们从一个简单的应用程序开始,只是为了启动和运行aiohttp。首先,创建一个新的virtualenv。发起使用Python 3.5以后版本,由于我们将使用asyncio提供的async def和await语法。假如您想进一步开辟该项目并使用异步理解的优势,则可以使用Python 3.6(本例使用python版本)。接下来,安装aiohttp:
  1. pip install aiohttp
复制代码
如今创建一个python文件(称为nasa.py),并将一些代码放入此中:
  1. from aiohttp import web
  2. async def get_mars_photo(request):
  3. return web.Response(text='A photo of Mars')
  4. app = web.Application()
  5. 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。

运行应用程序


要运行您的应用程序,您可以在文件末尾添加以下行:
  1. web.run_app(app, host='127.0.0.1', port=8080)
复制代码
然后像运行其他任何Python脚本一样运行它:
  1. python nasa.py
复制代码
但是有更好的方法。在许多第三方库中,您可以找到aiohttp-devtools。它提供了一个很好的runserver下令,可以自动检测您的应用并支持及时重载:
  1. pip install aiohttp-devtools
  2. 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文件,如下所示:
  1. import random
  2. from aiohttp import web, ClientSession
  3. from aiohttp.web import HTTPFound
  4. NASA_API_KEY = 'DEMO_KEY'
  5. ROVER_URL = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos'
  6. async def get_mars_image_url_from_nasa():
  7. while True:
  8.   sol = random.randint(0, 1722)
  9.   params = {'sol': sol, 'api_key': NASA_API_KEY}
  10.   async with ClientSession() as session:
  11.    async with session.get(ROVER_URL, params=params) as resp:
  12.     resp_dict = await resp.json()
  13.   if 'photos' not in resp_dict:
  14.    raise Exception
  15.   photos = resp_dict['photos']
  16.   if not photos:
  17.    continue
  18.   return random.choice(photos)['img_src']
  19. async def get_mars_photo(request):
  20. url = await get_mars_image_url_from_nasa()
  21. return HTTPFound(url)
复制代码
到底发生了什么事?
      
  • 我们选择一个随机拍摄日期(对于“好奇心” max_sol,在撰写本文时,其值为1722)  
  • ClientSession 创建一个会话,我们可以使用该会话从NASA API获取相应  
  • 我们使用获取JSON相应 resp.json()  
  • 我们查抄相应中是否存在“照片”键;假如没有,我们已经到达了每小时哀求数目的上限,我们必要稍等半晌  
  • 假如当天没有照片,我们会再次查抄是否有其他拍摄时间  
  • 然后,我们使用HTTPFound相应重定向到找到的照片

获取NASA API密钥


DEMO_KEYNASA提供的默认设置可以正常工作,但是您很快就会到达每小时API调用的限制。我发起您获取本身的API密钥。您可以在此处举行操纵 (注册过程非常简单快捷)。
如今,当您运行该应用程序时,您将直接从火星重定向到一个美丽的图像:

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

验证图像


您刚刚看到的图像并不让人受到开导。毕竟证实,环游者拍摄了很多非常无聊的照片。我想看看马克·沃特尼(Mark Watney)在他不可思议的旅程中所看到的,但这还不敷好。让我们找到一种办理方法。
我们将必要对图像举行某种情势的验证。在指定筛选条件前,我们可以修改代码:
  1. async def get_mars_photo_bytes():
  2. while True:
  3.   image_url = await get_mars_image_url_from_nasa()
  4.   async with ClientSession() as session:
  5.    async with session.get(image_url) as resp:
  6.     image_bytes = await resp.read()
  7.   if await validate_image(image_bytes):
  8.    break
  9. return image_bytes
  10. async def get_mars_photo(request):
  11. image = await get_mars_photo_bytes()
  12. return web.Response(body=image, content_type='image/jpeg')
复制代码
这里发生了一些新的事变:
      
  • 我们使用先前定义的函数获取URL,然后使用读取图像中的原始字节 resp.read()  
  • 我们查抄我们的图片是否足够好;假如没有,我们不停在寻找  
  • 一旦有了令人满意的照片,我们会将其放入相应中(留意,我们仍然使用与web.Response以前雷同的照片,但是这次我们指定body 而不是text,同时了定义content_type
留意:在此代码中,我们删除了重定向(HTTPFound),因此如今我们可以轻松地革新页面以获取另一个图像。
如今我们必要弄清楚怎样验证照片。我们可以很轻易做到的一件事就是查抄图像尺寸否足够大。这不是一个完善的验证,但如今应该这样做。要处理处罚图像,我们将必要python的图片库Pillow。
  1. pip install pillow
复制代码
我们的验证函数大概如下所示:
  1. import io
  2. from PIL import Image
  3. async def validate_image(image_bytes):
  4. image = Image.open(io.BytesIO(image_bytes))
  5. return image.width >= 1024 and image.height >= 1024
复制代码
如今革新浏览器,应该可以看到火星大图了。

如今我们可以更进一步,拒绝灰度图像:
  1. async def validate_image(image_bytes):
  2. image = Image.open(io.BytesIO(image_bytes))
  3. return image.width >= 1024 and image.height >= 1024 and image.mode != 'L'
复制代码
如今我们的程序开始返回更多鼓舞民气的照片:

偶然还能看到呆板人自拍:


总结

我们整个程序如下所示:
  1. import randomimport iofrom aiohttp import web, ClientSessionfrom PIL import ImageNASA_API_KEY = 'DEMO_KEY'ROVER_URL = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos'async def validate_image(image_bytes):
  2. image = Image.open(io.BytesIO(image_bytes))
  3. 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():
  4. while True:
  5.   image_url = await get_mars_image_url_from_nasa()
  6.   async with ClientSession() as session:
  7.    async with session.get(image_url) as resp:
  8.     image_bytes = await resp.read()
  9.   if await validate_image(image_bytes):
  10.    break
  11. return image_bytes
  12. async def get_mars_photo(request):
  13. image = await get_mars_photo_bytes()
  14. 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 异步抓取火星图片的详细内容,更多关于python AioHttp 抓取火星图片的资料请关注草根技术分享其它相干文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作