新浪天气API的使用方法:

  API地址:http://php.weather.sina.com.cn/xml.php?city=%B1%B1%BE%A9&password=DJOYnieT8234jlsK&day=0

  红色标记为城市代码(也就是城市的中文转为GB2312的十六进制代码,比如北京对应的GB2312十六进制代码为B1B1BEA9),实际上需要查哪个城市就把红色标记改为对应城市代码即可.而实际上打开此url后对应的是一个xml文件,里面包括了此城市的天气信息.

<?xml version="1.0" encoding="UTF-8"?>
<!-- published at 2014-10-31 17:08:03 -->
<Profiles>
<Weather>
<city>北京</city>
<status1>小雨</status1>
<status2>多云</status2>
<figure1>xiaoyu</figure1>
<figure2>duoyun</figure2>
<direction1>无持续风向</direction1>
<direction2>无持续风向</direction2>
<power1>≤3</power1>
<power2>≤3</power2>
<temperature1>14</temperature1>
<temperature2>9</temperature2>
<ssd>5</ssd>
<tgd1>16</tgd1>
<tgd2>16</tgd2>
<zwx>2</zwx>
<ktk>6</ktk>
<pollution>3</pollution>
<xcz></xcz>
<zho></zho>
<diy></diy>
<fas></fas>
<chy>4</chy>
<zho_shuoming>暂无</zho_shuoming>
<diy_shuoming>暂无</diy_shuoming>
<fas_shuoming>暂无</fas_shuoming>
<chy_shuoming>套装、夹衣、风衣、夹克衫、西服套装、马甲衬衫配长裤</chy_shuoming>
<pollution_l>轻度</pollution_l>
<zwx_l>弱</zwx_l>
<ssd_l>略凉</ssd_l>
<fas_l>暂无</fas_l>
<zho_l>暂无</zho_l>
<chy_l>夹衣类</chy_l>
<ktk_l>适宜开启(制热)</ktk_l>
<xcz_l>暂无</xcz_l>
<diy_l>暂无</diy_l>
<pollution_s>对空气污染物扩散无明显影响</pollution_s>
<zwx_s>紫外线弱</zwx_s>
<ssd_s>感觉有些凉,但是凉意微薄,不影响户外活动的开展。</ssd_s>
<ktk_s>适宜开启空调</ktk_s>
<xcz_s>暂无</xcz_s>
<gm>2</gm>
<gm_l>易发期</gm_l>
<gm_s>天气很凉,季节转换的气候,慎重增加衣服;较易引起感冒;</gm_s>
<yd>5</yd>
<yd_l>不适宜</yd_l>
<yd_s>虽然晴空万里,但是天气较凉,多数人不适宜户外运动;</yd_s>
<savedate_weather>2014-10-31</savedate_weather>
<savedate_life>2014-10-31</savedate_life>
<savedate_zhishu>2014-10-31</savedate_zhishu>
</Weather>
</Profiles>

  现在我们的工作就是使用curl打开这个xml文件并且将其转换为我们需要的数据结构.

  先看看我们自定义的数据结构,用于存放天气信息(感觉还有更好的定义方法):

#ifndef __SINA_WEATHER__
#define __SINA_WEATHER__ #include <stdio.h> #define FALSE (0)
#define TRUE (!0) #define SINA_WEATHER_URL_HEAD "http://php.weather.sina.com.cn/xml.php?city="
#define SINA_WEATHER_URL_TAIL "&password=DJOYnieT8234jlsK&day=0" struct date {
short year;
short month;
short day;
}; struct weather_info {
char * city; //天气情况(中文)
char * status1;
char * status2; //天气情况(拼音)
char * figure1;
char * figure2; //风向
char * direction1;
char * direction2; //风级
char * power1;
char * power2; //温度
int temperature1;
int temperature2; //体感指数数值
int ssd;
//体感度指数
char * ssd_l;
//体感度指数说明
char * ssd_s; //体感温度
int tgd1;
int tgd2; //紫外线指数数值
int zwx;
//紫外线指数
char * zwx_l;
//紫外线指数说明
char * zwx_s; //空调指数数值
int ktk;
//空调指数
char * ktk_l;
//空调指数说明
char * ktk_s; //污染指数数值
int pollution;
//污染扩散条件
char * pollution_l;
//污染指数说明
char * pollution_s; //穿衣指数数值
int chy;
//穿衣指数
char * chy_l;
//穿衣说明
char * chy_shuoming; //洗车指数数值
int xcz;
//洗车指数
char * xcz_l;
//洗车指数说明
char * xcz_s; //感冒指数数值
int gm;
//感冒指数
char * gm_l;
//感冒指数说明
char * gm_s; //运动指数数值
int yd;
//运动指数
char * yd_l;
//运动指数说明
char * yd_s; struct date weather_date;
struct date life_date;
struct date zhishu_date;
}; struct weather_info * get_weather_info_from_sina (const char * city_name); #endif

  

  先说一下流程,首先设计想法是就定义一个接口,调用时只需要输入一个城市名称,则自动返回此城市的天气信息结构体,而在内部,分别执行了UTF-8转GB2312格式, curl初始化, 获取天气XML信息, 填充struct weather_info结构体.

  流程图:

代码(sina_weather.c):

#include <stdio.h>
#include <curl/curl.h>
#include <iconv.h> #include "sina_weather.h"

//根据key获取xml中对应的值
char * get_xml_key_value (const char * xml, char * key)
{
char * head;
char * tail;
char stamp[];
char * value; sprintf(stamp, "<%s>", key);
if ((head = strstr (xml, stamp)) == NULL)
return NULL; head = head + strlen (stamp);
while (isspace (head[]))
head ++; sprintf(stamp, "</%s>", key); if ((tail = strstr (head, stamp)) == NULL)
return NULL; while (isspace(tail[-]) && (tail > head))
tail --; if (tail > head){
value = calloc (tail - head + , );
memcpy (value, head, tail - head);
value[tail - head] = 0x00;
} return value;
} //UTF-8转GB2312
int utf8_to_gb2312 (const char * src, char * dest_buf)
{
iconv_t con;
int src_length = strlen (src); if( (con = iconv_open ("gb2312", "utf-8")) == )
return FALSE; memset (dest_buf, , src_length); if(- == iconv (con, &src, &src_length, &dest_buf, &src_length))
return FALSE;
iconv_close (con); return TRUE;
}

//将一个GB2312字符串转换为它的十六进制字符串(每个字符用%隔开)
char * str_convert_to_gb2312_hex (const char * src)
{
if (src == NULL)
return NULL; int length = strlen (src) - ;
int index = ;
int num = ;
char * gb_str = calloc (((length) + ), );
char * hex_str = calloc ((length * ) + , ); utf8_to_gb2312 (src, gb_str);
while ((index / ) < length) {
hex_str[index] = '%';
sprintf (&hex_str[index + ], "%02X", gb_str[index / ] & 0xff);
index = index + ;
}
hex_str[length * ] = '\0';
return hex_str;
} void convert_to_gb2312_clean (char * str)
{
free (str);
}

//curl下载时的回调函数,当下载到数据时会调用此函数进行操作
size_t down_data_callback (void * ptr, size_t size, size_t nmemb, void * user_buf)
{
strcat (user_buf, ptr);
return size * nmemb;
} uint64_t curl_get_content (const char * url, char * content)
{
if ((url == NULL) || (content == NULL))
return; CURL * curl = curl_easy_init ();
curl_easy_setopt (curl, CURLOPT_URL, url); //设置curl的目标url地址
curl_easy_setopt (curl, CURLOPT_TIMEOUT, ); //下载超时时间
curl_easy_setopt (curl, CURLOPT_NOSIGNAL, ); //屏蔽其他信号
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, down_data_callback); //设置下载回调函数
curl_easy_setopt (curl, CURLOPT_WRITEDATA, content); //设置下载数据保存缓冲区(此参数会传到down_data_callback的user_buf) CURLcode retval = curl_easy_perform (curl);
if (retval == CURLE_OK) {
double down_length = ;
curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &down_length);
curl_easy_cleanup (curl);
return (uint64_t)down_length;
}
curl_easy_cleanup (curl);
return ;
} struct weather_info * weather_info_get_from_xml (const char * xml, struct weather_info * w_info)
{
if ((xml == NULL) || (w_info == NULL))
return w_info; char * str_data = NULL; w_info->city = get_xml_key_value (xml, "city");
w_info->status1 = get_xml_key_value (xml, "status1");
w_info->status1 = get_xml_key_value (xml, "status1");
str_data = get_xml_key_value (xml, "temperature1");
w_info->temperature1 = (int) atoi (str_data);
free (str_data);
str_data = get_xml_key_value (xml, "temperature2");
w_info->temperature2 = (int) atoi (str_data);
free (str_data);
  //此处省略N多,基本都同上操作.
} struct weather_info * get_weather_info_from_sina (const char * city_name)
{
if (city_name == NULL)
return NULL; CURL * curl = NULL;
CURLcode retval = ;
char xml_data[];
char url[] = SINA_WEATHER_URL_HEAD;
char * city_hex = str_convert_to_gb2312_hex (city_name);
struct weather_info * sina_w_info = calloc (sizeof (struct weather_info), ); strcat (url, city_hex);
strcat (url, SINA_WEATHER_URL_TAIL); convert_to_gb2312_clean (city_hex); uint64_t down_size = curl_get_content (url, xml_data); if (down_size == ) {
free (sina_w_info);
return NULL;
} weather_info_get_from_xml (xml_data, sina_w_info);
return sina_w_info;
}

  

CURL:

  或许有些同学不太清楚怎么在c中使用curl库,其实使用的方法很简单,就简单说明一下,在ubuntu下安装curl库命令

# apt-get install libcurl-nss-dev

  在编译时需要加入的选项:

-lcurl

  使用curl下载时常规的代码顺序为:


CURL * curl = curl_easy_init (); //初始化
curl_easy_setopt (curl, CURLOPT_URL, url); //具体设置代表的意思在http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
curl_easy_setopt (curl, CURLOPT_TIMEOUT, );
curl_easy_setopt (curl, CURLOPT_NOSIGNAL, );
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, down_data_callback);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, content);
CURLcode retval = curl_easy_perform (curl); //执行操作
if (retval == CURLE_OK) {
    //添加所需要处理的代码
   ........
}
curl_easy_cleanup (curl); //清空

  在使用curl下载时,会设置CURLOPT_WRITEFUNCTION,此设置主要是为了在下载有数据过来时,调用down_data_callback这个回调函数,并将数据保存到content这个缓冲区中.

curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, down_data_callback);
curl_easy_setopt (curl, CURLOPT_WRITEDATA, content); size_t down_data_callback (void * ptr, size_t size, size_t nmemb, void * user_buf)
{
  strcat (user_buf, ptr);
  return size * nmemb;
}

附录(1代表白天,2代表晚上): 

<status>

<figure>

<direction>

<power>

<temperature>

<ssd>

<ssd_l>

<ssd_s>

<tgd>

<zwx>

<zwx_l>

<zwx_s>

<ktk>

<ktk_l>

<ktk_s>

<pollution>

<pollution_l>

<pollution_s>

<xcz>

<xcz_l>

<xcz_s>

<chy>

<chy_l>

<chy_shuoming>

<gm>

<gm_l>

<gm_s>

<yd>

<yd_l>

<yd_s>

<zho>

<zho_l>

<zho_shuoming>

<diy>

<diy_l>

<diy_shuoming>

<fas>

<fas_l>

<fas_shuoming>

<savedate_weather>

<savedate_life>

<savedate_zhishu>

天气情况中文

天气情况拼音

风向

风级

温度

体感指数数值

体感度指数

体感度指数说明

体感温度

紫外线指数数值

紫外线指数

紫外线指数说明

空调指数数值

空调指数

空调指数说明

污染指数数值

污染物扩散条件

污染指数说明

洗车指数数值

洗车指数

洗车指数说明

穿衣指数数值

穿衣指数

穿衣说明

感冒指数数值

感冒指数

感冒指数说明

运动指数数值

运动指数

运动指数说明

天气预报日期

生活日期

指数日期

linux - 使用curl实现新浪天气API应用的更多相关文章

  1. 根据新浪天气API获取各地天气状况(Java实现)

    原文出自 参考网址(重要) http://blog.csdn.net/cyxlzzs/article/details/7602469  新浪 http://blog.csdn.net/l_ch_g/a ...

  2. 新浪天气api

    package com.smartdot.dcu; /** * java获取新浪天气预报代码 */ import java.io.FileNotFoundException; import java. ...

  3. 获取新浪天气api显示天气情况(转)

    直接上一个html的demo <!doctype html> <html class="no-js fixed-layout"> <head> ...

  4. android WebView将新浪天气为我所用 ------>仅供娱乐

    新浪天气提供了一个网页     http://w.sina.com 浏览器访问: 这效果还可以了哦,直接用webview加载出来,效果也可以了哦,不过,这不是我要的.我不希望在我写的应用里到处铺满si ...

  5. 新浪新闻API

    新浪新闻API ustcmio 关注 2017.01.15 20:44* 字数 536 阅读 2479评论 2喜欢 7 新浪新闻的API:1.访问手机新浪网https://sina.cn/?from= ...

  6. scrapy新浪天气

    一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序: LX终端(LXTermin ...

  7. [threeJs][新浪股票api][css3]3D新浪财经数据-最近A股涨的也太疯了......

    使用threeJS搭配新浪股票财经API 在线: http://wangxinsheng.herokuapp.com/stock 截图: A股涨幅榜[一片红10%] 检索[单击添加到自选内,自选使用l ...

  8. 新浪通过API分享 实践

    注:如果集成了百度的Frontia和SinaCoreSDK, 那么SSO会出现包冲突 https://github.com/sinaweibosdk/weibo_android_sdk/issues/ ...

  9. 新浪 股票 API

    新浪期货数据接口 [例子]http://hq.sinajs.cn/list=M0豆粕连续 M0 返回值如下:var hq_str_M0="豆粕连续,145958,3170,3190,3145 ...

随机推荐

  1. wing IDE破解方法

    WingIDE是我接触到最好的一款Python编译器了.但其属于商业软件,注册需要一笔不小的费用.因此,这篇简短的文章主要介绍了破解WingIDE的方法.破解软件仅供学习或者教学使用,如果您是商业使用 ...

  2. udev/raw/asmlib/多路径 配置asm

    asmlib 是linux上面给磁盘/分区头上面打上asm的标记,供asm使用,而且当磁盘的盘符发生改变的时候,不会影响到asm disk,从效果上说,和udev没有本质区别,在redhat 4和5中 ...

  3. yhd日志分析(一)

    yhd日志分析(一) 依据yhd日志文件统计分析每日各时段的pv和uv 建hive表, 表列分隔符和文件保持一致 load数据到hive表 写hive sql统计pv和uv, 结果保存到hive表2 ...

  4. ios第三方分享到qq、微信、人人网、微博总结

    我们开发出来的APP通常要通过第三方分享到其他社交平台,如qq.微博微信 等.通过分享可以提高APP的传播效率,增加APP的曝光率,因此也算是APP功能 里的标配了吧.目前常用的第三方分享途径有qq. ...

  5. C# 将汉字转化成拼音

    本文来自http://www.cnblogs.com/yazdao/archive/2011/06/04/2072488.html 首先下载Visual Studio International Pa ...

  6. Android WebView代理设置方法(API10~21适用)

    最近碰到个需求需要在APP中加入代理,HttpClient的代理好解决,但是WebView碰到些问题,然后找到个API10~API21都通用的类,需要用的同学自己看吧,使用方法,直接调用类方法setP ...

  7. instanceof、==号、Objetc类

    1)instanceof: 判断某个对象是否为某个类的实例,注意多态的运用,一个父类引用指向子类的对象,根据继承,子类就是父类,所以子类也可以看做是父类的一个实例.  形式:引用 instanceof ...

  8. GNU make 总结 (三)

    一.makefile 变量 makefile中的变量名是大小写敏感的,例如”foo”和”Foo”是两个不同的变量.通常情况下,对于一般变量,我们可以使用小写形式,而对于参数变量,采用全大写形式.当我们 ...

  9. MVVMLight leaning note

    Learning Note For MvvmLight MvvmLight quitstart refer link1 : MVVMLight HelloWorld *** mc:Ignorable ...

  10. Entity Framework 泛型使用

    因为增删改查是我们常用到的方法,我们不可能每个数据模型都去完成增删改查,这样的办法太笨拙了.我们可以写个父类(包含增删改查),然后让所有的数据模型类继承该父类.那就要求我们的父类必须使用泛型来实现. ...