9

我决定从 Google 的 Weather API 中提取信息——我在下面使用的代码运行良好。

            XmlDocument widge = new XmlDocument();
            widge.Load("https://www.google.com/ig/api?weather=Brisbane/dET7zIp38kGFSFJeOpWUZS3-");
            var weathlist = widge.GetElementsByTagName("current_conditions");
            foreach (XmlNode node in weathlist)
            {

                City.Text = ("Brisbane");
                CurCond.Text = (node.SelectSingleNode("condition").Attributes["data"].Value);
                Wimage.ImageUrl = ("http://www.google.com/" + node.SelectSingleNode("icon").Attributes["data"].Value);
                Temp.Text = (node.SelectSingleNode("temp_c").Attributes["data"].Value + "°C");
        }
     }

正如我所说,我能够从 XML 文件中提取所需的数据并显示它,但是如果页面被刷新或当前会话仍然处于活动状态,我会收到以下错误:

用户代码未处理 WebException - 远程服务器返回错误:403 Forbidden Exception。

我想知道这是否与对该特定 XML 文件的访问权限的某种访问限制有关?

进一步研究和调整建议

如下所述,这绝不是最佳实践,但我已经包含了我现在用于异常的 catch。我在 Page_Load 上运行此代码,所以我只是回发到页面。从那以后我没有注意到任何问题。性能方面我并不过分担心 - 我没有注意到加载时间有任何增加,而且这个解决方案是暂时的,因为这都是为了测试目的。我仍在使用 Yahoo 的 Weather API。

        try
        {
            XmlDocument widge = new XmlDocument();
            widge.Load("https://www.google.com/ig/api?weather=Brisbane/dET7zIp38kGFSFJeOpWUZS3-");
            var list2 = widge.GetElementsByTagName("current_conditions");
            foreach (XmlNode node in list2)
            {

                City.Text = ("Brisbane");
                CurCond.Text = (node.SelectSingleNode("condition").Attributes["data"].Value);
                Wimage.ImageUrl = ("http://www.google.com/" + node.SelectSingleNode("icon").Attributes["data"].Value);
                Temp.Text = (node.SelectSingleNode("temp_c").Attributes["data"].Value + "°C");

            }
        }
        catch (WebException exp)
        {
            if (exp.Status == WebExceptionStatus.ProtocolError &&
                exp.Response != null)
            {
                var webres = (HttpWebResponse)exp.Response;
                if (webres.StatusCode == HttpStatusCode.Forbidden)
                {
                    Response.Redirect(ithwidgedev.aspx);
                }

            }
        }

说明 API 错误处理的 Google 文章

Google API 处理错误

谢谢:

https://stackoverflow.com/a/12011819/1302173(捕获 403 并召回)

https://stackoverflow.com/a/11883388/1302173(错误处理和一般 Google API 信息)

https://stackoverflow.com/a/12000806/1302173(响应处理/json缓存-未来计划)

选择

我最近发现了这个很棒的开源替代品

OpenWeatherMap - 免费的天气数据和预报 API

4

4 回答 4

12

这与服务的更改/中断有关。请参阅:http ://status-dashboard.com/32226/47728

在此处输入图像描述

一年多来,我一直在使用 Google 的 Weather API 来提供电话服务器,以便 PolyCom 电话接收天气页面。它已经运行了一年多没有错误。截至 2012 年 8 月 7 日,经常出现间歇性 403 错误。

我每小时使用一次服务(一直如此),所以我认为请求的频率不是问题。403 的间歇性更可能与 Google 部分推出配置更改或 CDN 更改有关。

Google Weather API 并不是真正的已发布 API。这是一项显然是为在 iGoogle 上使用而设计的内部服务,因此支持程度尚不确定。我昨天在 googleapis 上发了推文,但没有收到任何回复。

切换到升级的天气 API 可能会更好,例如: WUnderground WeatherYahoo Weather

我昨天自己添加了以下“除非定义”错误处理 perl 代码来解决这个问题,但如果问题仍然存在,我将切换到更全面支持的服务:

my $url = "http://www.google.com/ig/api?weather=" . $ZipCode ;

my $tpp = XML::TreePP->new();
my $tree = $tpp->parsehttp( GET => $url );

my $city = $tree->{xml_api_reply}->{weather}->{forecast_information}->{city}->{"-data"};

unless (defined($city)) {
    print "The weather service is currently unavailable. \n";
    open (MYFILE, '>/home/swarmp/public_html/status/polyweather.xhtml');
    print MYFILE qq(<?xml version="1.0" encoding="utf-8"?>\n);
    print MYFILE qq(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">\n);
    print MYFILE qq(<html xmlns="http://www.w3.org/1999/xhtml">\n);
    print MYFILE qq(<head><title>Weather is Unavailable!</title></head>\n);
    print MYFILE qq(<body>\n);
    print MYFILE qq(<p>\n);
    print MYFILE qq(The weather service is currently unavailable from the data vendor.\n);
    print MYFILE qq(</p>\n);
    print MYFILE qq(</body>\n);
    print MYFILE qq(</html>\n);
    close MYFILE;
    exit(0);
}...
于 2012-08-09T12:23:56.577 回答
1

这和我们发现的一样。

比较错误请求和工作请求中的请求标头。工作请求包括 cookie。但他们来自哪里?

从谷歌删除所有浏览器 cookie。天气 api 调用将不再在您的浏览器中运行。浏览至 google.com,然后浏览至天气 api,它将再次运行。

Google 检查 cookie 以阻止多个 api 调用。在处理所有天气 api 请求之前获取一次 cookie 将解决问题。Cookie 将在一年后过期。我假设您将更频繁地重新启动您的应用程序,而不是每年一次。这样你就会得到一个新的。为每个请求获取 cookie 将导致相同的问题:太多不同的请求。

一个提示:天气不经常变化,所以缓存 json 信息(可能一个小时)。这将减少作为请求的耗时操作!

于 2012-08-17T06:30:36.193 回答
1

这绝不是最佳实践,但我在一些 WP7 和 Metro 应用程序中大量使用此 API。我通过捕获异常(大多数情况下是 403)并简单地在 catch 内重新调用服务来处理这个问题,如果 Google 端出现错误,它通常是短暂的,只会导致 1 或 2 次额外调用。

于 2012-08-17T19:11:29.687 回答
0

我发现如果您在干净的浏览器中尝试请求(例如 chrome 上的新窗口隐身模式),则谷歌天气服务可以工作。cookie 的可能问题?

于 2012-08-16T09:00:28.063 回答