2020年6月21日,我国大部分地区可观察到日食甚至日环食的奇景。
本人作为一名天文爱好者,自然也站在了凑热闹的人群之中。装备早就准备好了:去年买的天文望远镜,附赠巴德膜终于能排上用场了!另外,还某宝花了15大元,淘了两副纸框墨镜。
万事俱备,只差日月的交辉了!哦,等等时间呢?虽然网站上有本地区大概的日食的时间范围,但是我所在坐标的最佳观测时间似乎还没有精确到具体的分秒。冲着观看“食甚”去的话,总得算个精确点的数。
于是,6月21日的前夜,我做了一件这样的事情……
在NASA公众号介绍6.21日食的文章中找到计算精确日食时间的网址:
写了个web类似爬虫的工具,负责提交数据并抓取查询结果。为啥不直接用人家的界面功能呢?原因有两个:第一,这个界面实在太丑了(我可以负责人的说做这个页面的朋友不懂html。咳咳,吐槽归吐槽,我还是十分感谢这哥们提供的数据!);第二,我后面还需要做一个微信工作号的应用,因此需要借此解决跨域的问题。
OK, here is my code :
var url = \"http://almanac.pmo.ac.cn/cgi/seclany/seclany20200621/seclany.cgi\";
var postData = Request.QueryString.ToString();
WebClient webClient = new WebClient();
webClient.Headers.Add(\"Content-Type\", \"application/x-www-form-urlencoded\");
byte[] postBy = Encoding.Default.GetBytes(postData);
webClient.Headers.Add(\"ContentLength\", postBy.Length.ToString());
byte[] responseData = webClient.UploadData(url, \"POST\", postBy);
string html = Encoding.GetEncoding(\"GBK\").GetString(responseData);
string[] arrTypes = new string[] {\"初亏\",\"食甚\",\"复圆\", \"环食始\",\"环食终\"};
StringBuilder sb = new StringBuilder();
if(html.IndexOf(\"不可见日食\") != -1)
{
sb.Append(\"<p>不可见日食</p>\");
}
else if(html.IndexOf(\"可见日偏食\") != -1)
{
string str1 = @\"<table border=\"\"1\"\" width=\"\"67%\"\" id=\"\"table1\"\">\";
string str2 = \"</table>\";
html = SubStr(html, str1, str2);
html = SubStr(html, str1, str2);
html = html.Replace(\"</tr><tr>\", \"\\r\
\").Replace(@\"<p align=\"\"center\"\">\", \"\");
string ptn = @\"<td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td><td(.*)>(.*)</td>\";
var list= MatchStringsAll(ptn, html);
sb.AppendLine(\"<table class=\\\"ui_table\\\">\");
sb.AppendLine(\"<thead><tr><th>状态</th><th>时间</th><th>角度</th></tr></thead>\");
sb.AppendLine(\"<tbody>\");
foreach (var it in list)
{
var t = it[2].Trim();
var month = it[4].Trim();
var day = it[6].Trim();
var hour = it[8].Trim();
var min = it[10].Trim();
var sec = it[12].Trim();
var d1 = it[20].Trim();
var d2 = it[22].Trim();
if (Array.IndexOf(arrTypes, t) != -1)
{
sb.AppendLine(string.Format(\"<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>\",
t, month + \"月\" + day + \"日\" + hour + \"时\" + min + \"分\" + sec + \"秒\", d1 + \",\" + d2));
}
}
sb.AppendLine(\"</tbody>\");
sb.AppendLine(\"</table>\");
}
Response.Write(sb.ToString());
- 最后弄了个微信公众号应用 http://demo.chenreal.com/tony/eclipse.html 功能其实很简单,借用微信jssdk获取移动设备的定位坐标,然后换算出查询日食信息所需要的参数,通过代理工具查询得到结果,并呈现出来。
技术点在于利用微信获取设备定位坐标:
wx.getLocation({type : 'wgs84', success : function(res) {
setLocation(res.latitude,res.longitude); //纬度,经度
}});
当然,在调用getLocation之前,还要获取公众号的signature才行。
4.最后,当然是把应用上传到服务器,然后copy连接分享给朋友。所谓“独观日食乐不若与众”。