python爬虫绘制具体某一日的星图
老妈最近因为某些事情去档案处查了自己的资料,发现真实出生时间和身份证上的不一样。刚好最近临近她的生日,想自己做一些礼物送给她,就在网上查了一下她出生日的星图,准备做一个她出生那天的星图变化的小视频送给她。
实践
在网上找了星图的网站,发现这个网站 https://www.heavens-above.com/能查到每日的星图,估计是根据时间计算了轨道之类的,天文方面我一窍不通。下面是实现步骤。
- 星图
heavensabove这个网站有实时交互星图。但是具体到过去的某一日的星图我选择的是它的skychart,也就是“天文”目录下的“星图”。星图的几个选项就是年月日,左上角有可以更新地点的选项。 - python爬虫
(1)视频准备用长度为100s的生日歌,为了不出现卡顿,所以至少得有1000张星图的照片。生成星图后复制图片地址到新标签页,右键可以保存,png格式,url里面出现ashx。去百度搜了一下ashx,是一般处理程序。html、ashx和web界面(aspx) [1] 这篇文章基本上解决了我的问题。 (2)使用python的request库进行爬虫,会发现返回的text是乱码,后来乱研究了一通才发现返回的text里有一个"\PNG"的头,验证了一下数据是爬对了。 (3)requests里面的url解释一下:size是大小;ecl和cb是黄道和星座分界是否打开,默认是打开的,这里调为0,个人审美;time指时间,是一个较大的数字,增加1就是增加了1天,需要哪天的星图就用网页更新,打开图片地址看看url获得时间上下限就可以了;lat、lng、alt分别是观测点的纬度、经度、高度,默认北纬东经为正,南纬西经为负。
import requests
r = requests.get('https://www.heavens-above.com/wholeskychart.ashx?lat=40&lng=115&alt=100&tz=ChST&size=800&SL=1&SN=1&BW=0&ecl=0&cb=0&time='+str(num))
- 处理获得的图片
(1)用python内置的opencv库cv2处理图片,参考自文章Python 使用字节流读取图片并转换成图片格式显示[2]。网上查到opencv默认的读取是BGR,所以代码里有一句RGB2BGR。 ( 2)在图片上加上时间,使用cv2的putText[3]函数,写入硬盘即可。参数查阅opencv document。
import cv2
import numpy as np
from PIL import Image
from io import BytesIO
if r.status_code == 200:
r_byte = r.content
bytes_stream = Image.open(bytes_stream)
img = Image.open(bytes_stream)
img = cv2.cvtColor(np.asarray(img,cv2.COLOR_RGB2BGR)
cv2.putText(img,"time",(650,50),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1,cv2.LINE_AA,False)
cv2.imwrite('../../test/'+str(i)+'.png',img)
- 生成视频
这一步我用的是pr,就按照逐帧动画来就可以了。用ffmpeg应该也可以,未尝试,估计会快一些。 pr的批量导入需要按照名字顺序排列图片,所以在写入硬盘时命名最好是规范的相同数位的格式,否则会出现1.png 10.png 100.png这样的导入顺序。
完整代码
import requests
import cv2
from io import BytesIO
from PIL import Image
import numpy as np
num = 40500.666
gap = round(1/1440,5)
for i in range(0,1440):
num = num + 0.00069
r = requests.get('https://www.heavens-above.com/wholeskychart.ashx?lat=40&lng=130&alt=100&size=800&SL=1&SN=1&BW=0&ecl=0&cb=0&time='+str(num))
if r.status_code == 200:
r_byte = r.content
bytes_stream = BytesIO(r_byte)
img = Image.open(bytes_stream)
img = cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
hh = i//60
mm = i%60
cv2.putText(img,"10.3 "+str(hh)+":"+str(mm),(650,50),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),1,cv2.LINE_AA,False)
cv2.imwrite('../test/'+str(i)+'.png',img)
else:
print("pic " +str(i)+ " get no result")
视频样例
尚未解决的问题
1.用python访问heavensabove没有生成中文的星图,试了试在url里加lan=ch没成功 2.如果python能一键生成逐帧视频并压制配乐就更好了,一份代码解决所有问题
最后
欢迎在此进行技术讨论。拒绝任何未经授权的转载。
|