JSON 数据来自 api

JSON Data from api

我想从以下 url 中提取一些 JSON 数据: http://weather.news24.com/sa/johannesburg

我使用了 Google 开发人员工具,它给了我一些 JSON 并且当我尝试一些在线 JSON 验证器时,它在日期上以某种方式失败。无论如何我可以解决这个问题并正确获取所选城市 JSON 数据吗?

如有任何帮助,我们将不胜感激。

如果站点不提供 RESful 服务,那么您可能需要询问他们是否要抓取他们的页面。网页抓取非常乏味,网站的 DOM 结构随时可能发生变化。没有保证。


页面抓取

您可以抓取页面并将 table 数据转换为 JSON 对象。我复制了网页的DOM作为这个实现的基础。

如果您生成以下结果,则以下响应应位于底部。

{
  "windSpeed": "13km/h",
  "windDirection": "NW",
  "humidity": "35%",
  "dewPoint": "14",
  "comfortLevel": "30°C",
  "chanceOfRain": "10%",
  "sunrise": "5:57AM",
  "sunset": "6:45PM",
  "moonrise": "6:34PM",
  "moonset": "5:30AM",
  "moonPhase": "Full moon"
}

示例

// jQuery Plugins
(function($) {
    $.reduce = function(arr, fnReduce, valueInitial) {
        if (Array.prototype.reduce) {
            return Array.prototype.reduce.call(arr, fnReduce, valueInitial);
        }
        $.each(arr, function(index, value) {
            valueInitial = fnReduce.call(null, valueInitial, value, index, arr);
        });
        return valueInitial;
    };
})(jQuery);

// Used to convert a sequence of words to camelCase.
function camelCase(input) { 
    return input.toLowerCase().replace(/\s(.)/g, function(match, group1) {
        return group1.toUpperCase();
    });
}

// Main
$(function() {
  // Replace relative links with absolute.
  $('img').each(function() {
    $(this).attr('src', 'http://weather.news24.com/' + $(this).attr('src'));
  });

  // Find all table rows and grab the key-value pairs.
  var data = $.reduce($('#forecastContent tr'), function(map, tr) {
    var td = $(tr).find('td'), key, value;
    if (td.length === 2) {
      key = $(td.get(0)).text();
      value = $(td.get(1)).text();
    } else if (td.length === 3) {
      key = $(td.get(1)).text();
      value = $(td.get(2)).text();
    }
    if (key != null && key.trim().length > 0) {
     map[camelCase(key)] = value;
    }
    return map;
  }, {});

  $('#response').html(JSON.stringify(data, null, 2));
});
body {
  background: #FFF;
}
.bold {
  font-weight: bold;
}
.currentConditionsHeader {
  color: #1F38B7;
  font-weight: bold;
}
.forecast7DayBlockEmbedded {
  width: 80px;
  height: 70px;
  border: 1px solid #EAEFF2;
  text-align: center;
  padding-top: 10px;
  float: left;
  white-space: nowrap;
  margin-left: 13px;
  margin-top: 5px;
  margin-bottom: 15px;
  font-family: Verdana;
  font-size: 10px;
  font-weight: bold;
}
.forecastHeading {
  color: #000000;
  background-color: #D6F1FC;
  font-weight: bold;
  padding: 3px;
}
#response {
  background: #EEE;
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="forecastContent">
  <table cellpadding="0" celspacing="0" border="0">
    <tbody>
      <tr>
        <td>
          <div id="divCurrentOne" class="currentConditionsOneTable" style="white-space:nowrap;">
            <div class="float-l">
              <table cellpadding="2" cellspacing="2" border="0" class="currentConditionsOneTable">
                <tbody>
                  <tr>
                    <td colspan="2" class="currentConditionsHeader" style="vertical-align:middle;"> <img tyle="vertical-align:middle;" src="/Images/Icons/Forecasts/2.gif">LOW 17°C &nbsp;&nbsp; HIGH 24°C </td>
                  </tr>
                  <!-- Provide space and set column widths -->
                  <tr>
                    <td style="width:110px;">&nbsp;</td>
                    <td style="width:110px;">&nbsp;</td>
                  </tr>
                  <!-- end spacer and width definition row -->
                  <tr>
                    <td>Wind Speed</td>
                    <td class="bold">13km/h</td>
                  </tr>
                  <tr>
                    <td>Wind Direction</td>
                    <td class="bold">NW</td>
                  </tr>
                  <tr>
                    <td>Humidity</td>
                    <td class="bold">35%</td>
                  </tr>
                  <tr>
                    <td>Dew Point</td>
                    <td class="bold">14</td>
                  </tr>
                  <tr>
                    <td>Comfort Level</td>
                    <td class="bold">30°C</td>
                  </tr>
                  <tr>
                    <td>Chance of Rain</td>
                    <td class="bold">10%</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </td>
        <td>
          <div id="divAstronomy" class="currentConditionsAstronomyTable" style="white-space:nowrap;">
            <div class="float-l">
              <table cellpadding="2" cellspacing="2" border="0" class="currentConditionsAstronomyTable">
                <tbody>
                  <tr>
                    <td colspan="3">&nbsp;</td>
                  </tr>
                  <!-- Provide space and set column widths -->
                  <tr>
                    <td>&nbsp;</td>
                    <td>&nbsp;</td>
                    <td style="width:100%;">&nbsp;</td>
                  </tr>
                  <!-- end spacer and width definition row -->
                  <tr>
                    <td>&nbsp;</td>
                    <td>Sunrise</td>
                    <td class="bold">5:57AM</td>
                  </tr>
                  <tr>
                    <td>&nbsp;</td>
                    <td>Sunset</td>
                    <td class="bold">6:45PM</td>
                  </tr>
                  <tr>
                    <td>&nbsp;</td>
                    <td>&nbsp;</td>
                    <td class="bold">&nbsp;</td>
                  </tr>
                  <tr>
                    <td rowspan="2" class="currentConditionsMoonImage"><img src="/Images/Icons/Moon/cw_full_moon.gif"></td>
                    <td>Moonrise</td>
                    <td class="bold">6:34PM</td>
                  </tr>
                  <tr>
                    <td>Moonset</td>
                    <td class="bold">5:30AM</td>
                  </tr>
                  <tr>
                    <td>&nbsp;</td>
                    <td>Moon Phase</td>
                    <td class="bold">Full moon</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </td>
      </tr>
      <tr>
        <td colspan="2" id="div7DayForecast" style="width:100%;white-space:nowrap;">
          <div class="forecast7DayEmbeddedContainer">
            <div class="forecast7DayContainer">
              <br>
              <br>
              <div id="7dayforecast" class="forecastHeading">7 Day Forecast</div>
              <div class="forecast7DayBlockEmbedded"> Tuesday
                <br> <img src="/Images/Icons/Forecasts/2.gif">
                <br> 17°C - 27°C </div>
              <div class="forecast7DayBlockEmbedded"> Wednesday
                <br> <img src="/Images/Icons/Forecasts/33.gif">
                <br> 17°C - 28°C </div>
              <div class="forecast7DayBlockEmbedded"> Thursday
                <br> <img src="/Images/Icons/Forecasts/33.gif">
                <br> 16°C - 29°C </div>
              <div class="forecast7DayBlockEmbedded"> Friday
                <br> <img src="/Images/Icons/Forecasts/33.gif">
                <br> 17°C - 28°C </div>
              <div class="forecast7DayBlockEmbedded"> Saturday
                <br> <img src="/Images/Icons/Forecasts/4.gif">
                <br> 16°C - 27°C </div>
              <div class="forecast7DayBlockEmbedded"> Sunday
                <br> <img src="/Images/Icons/Forecasts/22.gif">
                <br> 16°C - 26°C </div>
              <div class="forecast7DayBlockEmbedded"> Monday
                <br> <img src="/Images/Icons/Forecasts/4.gif">
                <br> 15°C - 27°C </div>
            </div>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<hr />
<h2>Response</h2>
<pre>
  <code id="response"></code>
</pre>


RESTful 选项

有免费的 REST APIs return JSON 天气数据。您需要做的就是注册并获得密钥。

OpenWeatherMap

API: http://openweathermap.org/api

请求: http://api.openweathermap.org/data/2.5/weather?q=johannesburg,za&appid=YOUR_KEY

回复
{
    coord: {
        lon: 28.04,
        lat: -26.2
    },
    weather: [{
        id: 801,
        main: "Clouds",
        description: "few clouds",
        icon: "02d"
    }],
    base: "cmc stations",
    main: {
        temp: 304.367,
        pressure: 852.81,
        humidity: 26,
        temp_min: 304.367,
        temp_max: 304.367,
        sea_level: 1022.08,
        grnd_level: 852.81
    },
    wind: {
        speed: 2.51,
        deg: 296.507
    },
    clouds: {
        all: 20
    },
    dt: 1456147770,
    sys: {
        message: 0.0116,
        country: "ZA",
        sunrise: 1456113434,
        sunset: 1456159501
    },
    id: 993800,
    name: "Johannesburg",
    cod: 200
}

地下天气

API: https://www.wunderground.com/weather/api/

要求: http://api.wunderground.com/api/YOUR_KEY/conditions/q/ZA/Johannesburg.json

回复
{
    response: {
        version: "0.1",
        termsofService: "http://www.wunderground.com/weather/api/d/terms.html",
        features: {
            conditions: 1
        }
    },
    current_observation: {
        image: {
            url: "http://icons.wxug.com/graphics/wu2/logo_130x80.png",
            title: "Weather Underground",
            link: "http://www.wunderground.com"
        },
        display_location: {
            full: "Johannesburg, South Africa",
            city: "Johannesburg",
            state: "",
            state_name: "South Africa",
            country: "ZA",
            country_iso3166: "ZA",
            zip: "00000",
            magic: "1",
            wmo: "68368",
            latitude: "-26.12999916",
            longitude: "28.22999954",
            elevation: "1700.00000000"
        },
        observation_location: {
            full: "Johannesburg, ",
            city: "Johannesburg",
            state: "",
            country: "ZA",
            country_iso3166: "ZA",
            latitude: "-26.13077927",
            longitude: "28.24378967",
            elevation: "5643 ft"
        },
        estimated: {},
        station_id: "FAOR",
        observation_time: "Last Updated on February 22, 3:30 PM SAST",
        observation_time_rfc822: "Mon, 22 Feb 2016 15:30:00 +0200",
        observation_epoch: "1456147800",
        local_time_rfc822: "Mon, 22 Feb 2016 15:44:41 +0200",
        local_epoch: "1456148681",
        local_tz_short: "SAST",
        local_tz_long: "Africa/Johannesburg",
        local_tz_offset: "+0200",
        weather: "Scattered Clouds",
        temperature_string: "84 F (29 C)",
        temp_f: 84,
        temp_c: 29,
        relative_humidity: "29%",
        wind_string: "From the WNW at 10 MPH",
        wind_dir: "WNW",
        wind_degrees: 290,
        wind_mph: 10,
        wind_gust_mph: 0,
        wind_kph: 17,
        wind_gust_kph: 0,
        pressure_mb: "1020",
        pressure_in: "30.12",
        pressure_trend: "0",
        dewpoint_string: "48 F (9 C)",
        dewpoint_f: 48,
        dewpoint_c: 9,
        heat_index_string: "NA",
        heat_index_f: "NA",
        heat_index_c: "NA",
        windchill_string: "NA",
        windchill_f: "NA",
        windchill_c: "NA",
        feelslike_string: "84 F (29 C)",
        feelslike_f: "84",
        feelslike_c: "29",
        visibility_mi: "6.2",
        visibility_km: "10.0",
        solarradiation: "--",
        UV: "6",
        precip_1hr_string: "-9999.00 in (-9999.00 mm)",
        precip_1hr_in: "-9999.00",
        precip_1hr_metric: "--",
        precip_today_string: "0.00 in (0.0 mm)",
        precip_today_in: "0.00",
        precip_today_metric: "0.0",
        icon: "partlycloudy",
        icon_url: "http://icons.wxug.com/i/c/k/partlycloudy.gif",
        forecast_url: "http://www.wunderground.com/global/stations/68368.html",
        history_url: "http://www.wunderground.com/history/airport/FAOR/2016/2/22/DailyHistory.html",
        ob_url: "http://www.wunderground.com/cgi-bin/findweather/getForecast?query=-26.13077927,28.24378967",
        nowcast: ""
    }
}