65.9K
CodeProject 正在变化。 阅读更多。
Home

APOD - 获取每日天文图片

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (3投票s)

2009 年 9 月 16 日

GPL3

4分钟阅读

viewsIcon

23914

downloadIcon

493

检索每日天文图片

wearesnapshot.png

引言

NASA 每天分享的太空相关图片总是让我惊叹不已 (参见 http://antwrp.gsfc.nasa.gov/apod/astropix.html)。我经常访问该网站,而且经常(如果不是总是)将图片下载到我的电脑上以便离线查看(我们还没有一个随时在线的世界——至少不是一个经济实惠的世界)。此外,我经常想要下载多张图片(一个月的所有图片),而手动点击下载非常繁琐。

因此,我开发了自己的自动化软件!

此处分享的软件和教程包括:

  • 向 APOD 网站发起 HTTP 请求(针对选定的日期)
  • 检索和处理 HTML 代码
  • 识别并检索 HTML 中包含的 JPG 图片(目前仅支持 JPG)
  • 将 JPG 图片存储在可执行文件所在的目录中。图片存储为 <年><月><日>.jpg

此外,我尝试开发一个用户友好的窗口。不过,目前仅允许选择日期。

背景

不需要任何特定背景知识,只需具备 C#(或其他任何面向对象语言和原则)以及 Microsoft Visual Studio 的基本知识即可。

请注意,代码比较“粗糙”,因此文档和代码的整洁度不足。

Using the Code

程序很简单。用户目前可以选择一个特定日期。然后允许执行三个命令:

  1. 获取图片
  2. 获取所选月份的所有图片(日期早于所选日期)
  3. 退出

正如我稍后会解释的那样,2 实际上是 1 的扩展。1 完成了最复杂的工作。

但在我开始之前,我们需要了解 APOD 中的信息和页面的结构——一种非常简单直观的方式:

APOD 的基本 URL 是:

  • http://antwrp.gsfc.nasa.gov/

运行该网站的人员既聪明又善良,他们提供了一个庞大的免费图片库(包括当前和过去的图片),可以通过以下方式访问:

  • http://antwrp.gsfc.nasa.gov/apod/ap<2位年份><2位月份><2位日期>.html

例如,2009 年 09 月 09 日的图片可以通过以下 URL 访问:

  • http://antwrp.gsfc.nasa.gov/apod/ap090916.html

因此,知道了获取任意给定日期页面的规则,就可以开始使用漂亮的 C#、.NET 和 HTTP 技术了。

开始吧!

实际上,当用户按下“GET!”按钮时,操作就开始了。点击事件调用以下代码:

private void buttonGET_Click(object sender, EventArgs e)
{ 
    GetAPODImage(dateTimePicker.Value); 
} 

GetAPODimage 方法执行主要工作。

首先,我们根据上面解释的规则生成所选日期的 URL。

string url = GenerateAPOD_URL(“http://antwrp.gsfc.nasa.gov/apod/ap”,date);

此方法构建 URL 的方式如下:

private string GenerateAPOD_URL(string rootURL, System.DateTime date)
{
    return rootURL
            + Get2DigitYear(date)
            + Get2DigitNumberAsString(date.Month)
            + Get2DigitNumberAsString(date.Day)
            + “.html”;
}

请注意,Get2DigitNumberAsString 返回一个两位数的 string。例如,如果选定的日期是 1,它返回‘01’。

接下来,我们将检索 HTML 页面。

GetHTTP(url,5000,ref resultHTML); 

GetHTTP 方法将从“url”获取 HTML 页面并将其存储到“resultHTML”中。请注意,我们传递了“5000”(即 5 秒),这表示等待获取页面的超时时间——这对于防止长时间等待页面非常重要。

GetHTTP 的代码如下:

// create HTTP request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = timeout;
req.ReadWriteTimeout = timeout;

// get response
WebResponse resp = req.GetResponse();

// we will read data via the response stream
Stream resStream = resp.GetResponseStream();

int    count      = 0;
byte[] buf = new byte[8192];

resultHTML = "";

do
{
    // fill the buffer with data
    count = resStream.Read(buf, 0, buf.Length);

    // make sure we read some data
    if (count != 0)
    {
        // translate from bytes to ASCII text
        resultHTML += Encoding.ASCII.GetString(buf, 0, count);
    }
}
while (count > 0); // any more data to read
    resp.Close(); 

很简单。好的——现在,如果没有发生异常,我们就必须解析‘resultHTML’并查找‘JPG’(即我们希望下载的精美图片):

GetHTTPFilesByTypeSuffix(resultHTML, ‘.JPG’, ref list); 

我不会在这个函数中过多详细介绍,除了这项工作是查找‘href=’并获取引用的文件。它仅在是‘.JPG’时才认为是有效的。
例如:如果变量‘resultHTML’包含“<a href="image/0909/tarantula_gleason.jpg">”,那么 image/0909/tarantula_gleason.jpg 将被添加到列表中(变量‘list’)。

既然我们有了图片文件,就应该将它们下载并存储到磁盘(请看粗体代码):

try 
{
    ....
    //get and save images 
    foreach (string file in list) 
    {
        String source = “http://antwrp.gsfc.nasa.gov/apod/”+file;
        string dest = GetYYYYMMDD(date)+’.JPG’;
        WebClient Client = new WebClient();
        Client.DownloadFile(source, dest); 
        pictureBox.Image = Image.FromFile(dest);
    }

}//end try
catch (Exception ex)
{
    Console.WriteLine("An exception occurred: " + ex.Message);
    pictureBox.Image = Properties.Resources.g_close;
}

请注意

  • 图片存储后,我会在pictureBox(主窗口中)显示它。
  • 如果发生错误,pictureBox 会显示一个错误图片。

最后,如何获取所选月份(日期早于所选日期)的所有图片?很简单。

private void buttonGETMONTH_Click(object sender, EventArgs e)
{ 
    DateTime date = dateTimePicker.Value;
    for (int i = 1; date.Month == dateTimePicker.Value.Month; i++ )
    {
        GetAPODImage(date);
        date = dateTimePicker.Value.AddDays(-i);
    }
}

诀窍是初始化一个临时日期变量为所选日期,然后递减天数,直到月份发生变化。

就是这样!希望您喜欢这篇文章。

最后的 remarks

您可以下载 win32 二进制文件并直接运行(需要 .NET 3.5 Framework)。如果您打开解决方案,您会注意到它依赖于 WeAreUtils(也包含在内)。这个库实际上包含了文章中提到的许多实用工具。然而,我决定提供一个简化版本,以便更容易理解。

如果您喜欢这款软件,您可以在 SourceForge 上找到它(http://sourceforge.net/projects/weareapod/)!加入该项目!

历史

  • 2009 年 9 月 16 日:初始帖子
© . All rights reserved.