(转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)
1. 利用 CURLOPT_WRITEFUNCTION 设置回调函数, 利用 CURLOPT_WRITEDATA 获取数据指针
官网文档如下
CALLBACK OPTIONS
CURLOPT_WRITEFUNCTION
Pass a pointer to a function that matches the following prototype: size_t function( char *ptr, size_t size, size_t nmemb, void *userdata); This function gets called by libcurl as soon as there is data received that needs to be saved. The size of the data pointed to by ptr is size multiplied with nmemb, it will not be zero terminated. Return the number of bytes actually taken care of. If that amount differs from the amount passed to your function, it'll signal an error to the library. This will abort the transfer and return CURLE_WRITE_ERROR.
From 7.18.0, the function can return CURL_WRITEFUNC_PAUSE which then will cause writing to this connection to become paused. See curl_easy_pause(3) for further details.
This function may be called with zero bytes data if the transferred file is empty.
Set this option to NULL to get the internal default function. The internal default function will write the data to the FILE * given with CURLOPT_WRITEDATA.
Set the userdata argument with the CURLOPT_WRITEDATA option.
The callback function will be passed as much data as possible in all invokes, but you cannot possibly make any assumptions. It may be one byte, it may be thousands. The maximum amount of body data that can be passed to the write callback is defined in the curl.h header file: CURL_MAX_WRITE_SIZE (the usual default is 16K). If you however have CURLOPT_HEADER set, which sends header data to the write callback, you can get up to CURL_MAX_HTTP_HEADER bytes of header data passed into it. This usually means 100K.
CURLOPT_WRITEDATA
Data pointer to pass to the file write function. If you use the CURLOPT_WRITEFUNCTION option, this is the pointer you'll get as input. If you don't use a callback, you must pass a 'FILE *' (cast to 'void *') as libcurl will pass this to fwrite() when writing data. By default, the value of this parameter is unspecified.
The internal CURLOPT_WRITEFUNCTION will write the data to the FILE * given with this option, or to stdout if this option hasn't been set.
If you're using libcurl as a win32 DLL, you MUST use the CURLOPT_WRITEFUNCTION if you set this option or you will experience crashes.
This option is also known with the older name CURLOPT_FILE, the name CURLOPT_WRITEDATA was introduced in 7.9.7.
2. 完整代码如下:
点击(此处)折叠或打开
- /*------------------------------------------------------------------------------------------
- 名称: http_sina_curl_callbak.c
- 功能: 利用libcurl的回调机制实现sina股票接口. http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
- http://hq.sinajs.cn/list=sz150013
- http://hq.sinajs.cn/list=sh601318
- #libcurl的调试信息
- * About to connect() to hq.sinajs.cn port 80 (#0)
- * Trying 219.142.78.242...
- * connected
- * Connected to hq.sinajs.cn (219.142.78.242) port 80 (#0)
- > GET /list=sz150001 HTTP/1.1
- Host: hq.sinajs.cn
- Accept: * *
- < HTTP/1.1 200 OK
- < Cache-Control: no-cache
- < Content-Length: 250
- < Connection: Keep-Alive
- < Content-Type: application/x-javascript; charset=GBK
- <
- * Connection #0 to host hq.sinajs.cn left intact
- * Closing connection #0
- #运行结果:
- root@OpenWrt:/xutest# ./http_sina_stock
- sz150001: dq = 0.724, jg = 0.730, jd = 0.722, jk = 0.729
- sz150013: dq = 0.886, jg = 0.893, jd = 0.885, jk = 0.889
- sz150100: dq = 0.981, jg = 0.982, jd = 0.979, jk = 0.980
- sz150152: dq = 0.964, jg = 0.967, jd = 0.964, jk = 0.965
- sz150018: dq = 0.958, jg = 0.960, jd = 0.957, jk = 0.960
- root@OpenWrt:/xutest#
- -------------------------------------------------------------------------------------------*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <curl/curl.h>
- #include <assert.h>
- #define HTTP_GET "GET"
- #define HTTP_PUT "PUT"
- #define HTTP_HEAD "HEAD"
- #define HTTP_POST "POST"
- #define HTTP_DELETE "DELETE"
- #define HTTP_RET_OK "HTTP/1.1 200 OK\r\n"
- #define SINA_HOST "hq.sinajs.cn"
- #define SINA_PORT 80
- #define ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0]))
- typedef struct {
- float price_dq; //当前价, 取拼音的首字母
- float price_zs; //昨收价
- float price_jk; //今开价
- float price_jg; //今高价
- float price_jd; //今低价
- } stock_info_t;
- #define DBG //printf
- #define CURL_DBG (0) //1=开启curl的调试
- //-----------------------------------------------------------------------------------------
- static void delay_ms(int msec)
- {
- struct timeval timeout;
- memset(&timeout, 0, sizeof(struct timeval));
- timeout.tv_sec = msec / 1000;
- timeout.tv_usec = (msec % 1000) * 1000;
- select(0, NULL, NULL, NULL, &timeout);
- }
- size_t callback_get_head(void *ptr, size_t size, size_t nmemb, void *userp)
- {
- strcat(userp, ptr);
- return size * nmemb; //必须返回这个大小, 否则只回调一次
- }
- static char connect_cloud(char *pc_ret, const char *host_addr, const int portno,
- const char *pc_method, struct curl_slist *http_headers)
- {
- CURL *curl;
- CURLcode res = CURLE_GOT_NOTHING;
- assert((pc_ret != NULL) && (host_addr != NULL) && (pc_method != NULL));
- //curl_global_init(CURL_GLOBAL_DEFAULT);
- curl = curl_easy_init();
- if (!curl) {
- fprintf(stderr, "--- curl init Error!\n");
- return 0;
- }
- curl_easy_setopt(curl, CURLOPT_URL, host_addr);
- curl_easy_setopt(curl, CURL_HTTP_VERSION_1_1, 1L); //HTTP 1.1
- curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); //设置超时, 单位为秒.
- curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); //屏蔽其它信号, makes libcurl NOT ask the system to ignore SIGPIPE signals
- curl_easy_setopt(curl, CURLOPT_HEADER, 1L); //下载数据包括HTTP头部, The default value for this parameter is 0.
- //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); //The default value for this parameter is 1
- #if (CURL_DBG == 1)
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //调试用: 显示交互明细,
- //curl_easy_setopt(curl, CURLOPT_HEADER, 1L); //调试用: 只显示头行的返回
- #endif
- #if 1
- curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, pc_method);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_get_head); //下载数据的回调函数
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, pc_ret); //下载数据的指针
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers); //多行的HTTP头部
- #endif
- res = curl_easy_perform(curl);
- if(res != CURLE_OK)
- fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
- curl_easy_cleanup(curl);
- return 1;
- }
- int sina_get_stock(char *pc_ret, const char *pc_stockid)
- {
- char pc_url[200], ret;
- //组织请求头部, 自动末尾添加'\r\n'
- struct curl_slist *http_headers = NULL;
- http_headers = curl_slist_append(http_headers, "Accept: */*");
- //http_headers = curl_slist_append(http_headers, "Connection: Close");
- //发送请求, 再判断返回值
- //url = hq.sinajs.cn/list=sz150013
- sprintf(pc_url, "%s/list=%s", SINA_HOST, pc_stockid);
- ret = connect_cloud(pc_ret, pc_url, SINA_PORT, HTTP_GET, http_headers);
- //DBG("cloud ret = %s\n", pc_ret);
- //释放 http_headers资源
- curl_slist_free_all(http_headers);
- return(ret);
- }
- #if 0
- /*字符串不同含义的数据用逗号隔开了,按照程序员的思路,顺序号从0开始。
- 0:”大秦铁路”,股票名字;
- 1:”27.55″,今日开盘价;
- 2:”27.25″,昨日收盘价;
- 3:”26.91″,当前价格;
- 4:”27.55″,今日最高价;
- 5:”26.20″,今日最低价;
- 6:”26.91″,竞买价,即“买一”报价;
- 7:”26.92″,竞卖价,即“卖一”报价;
- 8:”22114263″,成交的股票数,由于股票交易以一百股为基本单位,所以在使用时,通常把该值除以一百;
- 9:”589824680″,成交金额,单位为“元”,为了一目了然,通常以“万元”为成交金额的单位,所以通常把该值除以一万;
- 10:”4695″,“买一”申请4695股,即47手;
- 11:”26.91″,“买一”报价;
- 12:”57590″,“买二”
- 13:”26.90″,“买二”
- 14:”14700″,“买三”
- 15:”26.89″,“买三”
- 16:”14300″,“买四”
- 17:”26.88″,“买四”
- 18:”15100″,“买五”
- 19:”26.87″,“买五”
- 20:”3100″,“卖一”申报3100股,即31手;
- 21:”26.92″,“卖一”报价
- (22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
- 30:”2008-01-11″,日期;
- 31:”15:05:32″,时间;*/
- #endif
- void stock_parse(stock_info_t *stock, const char *pc_data)
- {
- char *pc_str, *pc_str1;
- int i;
- assert((stock != NULL) &&(pc_data != NULL));
- //DBG("data = %s\n", pc_data);
- pc_str = strstr(pc_data, HTTP_RET_OK);
- if (pc_str) {
- pc_str += strlen(HTTP_RET_OK);
- pc_str = strstr(pc_str, "\r\n\r\n");
- pc_str += 4;
- DBG("valid str = %s\n", pc_str);
- //解析数据, var hq_str_sz150013="???B,0.899,0.906,0.897,0.903,0.895,0.897,0.898,9739979,8751058.780,2200,0.897,143548,0.896,572900,0.895,625300,0.894,167300,0.893,9800,0.898,60000,0.899,362300,0.900,162500,0.901,217000,0.902,2013-11-06,10:38:44,00";
- pc_str = strchr(pc_str, ',');
- pc_str ++;
- for (i=0; i<5; i++) {
- pc_str1 = strchr(pc_str, ',');
- if (pc_str1) {
- *pc_str1 = '\0';
- switch(i) {
- case 0: stock->price_jk = atof(pc_str); break; //今开
- case 1: stock->price_zs = atof(pc_str); break; //昨收
- case 2: stock->price_dq = atof(pc_str); break; //当前
- case 3: stock->price_jg = atof(pc_str); break; //今高
- case 4: stock->price_jd = atof(pc_str); break; //今低
- }
- pc_str = pc_str1 + 1; //指向下个有效数据
- }
- else break;
- }
- }
- }
- //-------------------------------------------------------------------------------
- int main(void)
- {
- char pc_ret[1000];
- int i, max;
- stock_info_t stock;
- char *stock_array[] = {"sz150001", "sz150013", "sz150100", "sz150152", "sz150018"}; //改成自己的
- max = ARRAY_COUNT(stock_array);
- for(i=0; i<max; i++) {
- memset(pc_ret, 0x00, sizeof(pc_ret));
- sina_get_stock(pc_ret, stock_array[i]);
- DBG("sina ret OK = %s\n", pc_ret);
- stock_parse(&stock, pc_ret);
- printf("%s: dq = %.3f, jg = %.3f, jd = %.3f, jk = %.3f\n",
- stock_array[i], stock.price_dq, stock.price_jg, stock.price_jd ,stock.price_jk);
- }
- return 1;
- }
3. Makefile:
点击(此处)折叠或打开
- OPENWRT = 1
- ifeq ($(OPENWRT), 1)
- CC = ~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc
- CFLAGS += -I ~/openwrt-lib/include -L ~/openwrt-lib/lib
- LFLAGS += -lcurl -lcrypto -lz -lssl
- else
- CC = gcc
- LFLAGS += -lcurl
- endif
- CFLAGS += -Wall -O2
- #CFLAGS += -g
- #可执行文件名和相关的obj文件
- APP_BINARY = http_sina_stock
- SRCS += http_sina_curl_callback.c
- OBJS = $(SRCS:.c=.o)
- all: APP_FILE
- APP_FILE: $(OBJS)
- $(CC) $(CFLAGS) $(OBJS) -o $(APP_BINARY) $(LFLAGS)
- .PHONY: clean
- clean:
- @echo "cleanning project"
- $(RM) *.a $(OBJS) *~ *.so *.lo $(APP_BINARY)
- @echo "clean completed"
4. openwrt下运行结果如下
root@OpenWrt:/xutest# ./http_sina_stock
sz150001: dq = 0.724, jg = 0.730, jd = 0.722, jk = 0.729
sz150013: dq = 0.886, jg = 0.893, jd = 0.885, jk = 0.889
sz150100: dq = 0.981, jg = 0.982, jd = 0.979, jk = 0.980
sz150152: dq = 0.964, jg = 0.967, jd = 0.964, jk = 0.965
sz150018: dq = 0.958, jg = 0.960, jd = 0.957, jk = 0.960
root@OpenWrt:/xutest#
(转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)的更多相关文章
- curl实例-通过新浪股票接口获取股票信息
在学习curl的过程中,我们知道curl是相当于一个简单的浏览器,通过往对应的服务上面发送数据信息,返回服务器的响应结果,这个在Java里面主要是使用封装好的httpclient来进行操作,但是自己认 ...
- 新浪股票接口AndroidSDK
昨天想到一个点子,需要访问股票行情.于是在网上搜了一下免费的股市行情的接口.发现新浪股票的数据接口比较稳定,于是就用它了. 网上对于新浪股票的数据接口介绍比较详细,并且实现也很简单,所以花了一下午就基 ...
- js获取新浪天气接口
<!doctype html> <html class="no-js fixed-layout"> <head> <meta charse ...
- [threeJs][新浪股票api][css3]3D新浪财经数据-最近A股涨的也太疯了......
使用threeJS搭配新浪股票财经API 在线: http://wangxinsheng.herokuapp.com/stock 截图: A股涨幅榜[一片红10%] 检索[单击添加到自选内,自选使用l ...
- Python如何调用新浪api接口的问题
前言:这些天在研究如何调用新浪开放平台的api分析新浪微博用户的数据 成果:成功调用了新浪api获取了用户的一些个人信息和无数条公共微博 不足:新浪开放平台访问有限制,返回的数据着实有限,不足以分析问 ...
- [iOS微博项目 - 2.1] - 获得新浪授权接口
A.如何获得新浪的授权接口 登陆新浪的开放平台 注册新浪账号 创建应用 获得应用id和请求地址 查阅相关API 关联需要进行测试的账号 1.登陆开放平台 http://open.weibo.com ...
- 新浪 股票 API
新浪期货数据接口 [例子]http://hq.sinajs.cn/list=M0豆粕连续 M0 返回值如下:var hq_str_M0="豆粕连续,145958,3170,3190,3145 ...
- 如何利用php+android+新浪sae服务器做一个app下载应用
功能简介:提供一个app下载的平台,类似于appstore,上面有很多app可供下载 实现基本思路:利用android,在手机桌面建立一个图标,点击该图标不是打开app应用,而是跳转到一个web页面, ...
- 利用新浪js接口根据ip地址获取实际地址
1.核心:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=192.152.3.25 把这句话直接输入到浏览器 ...
随机推荐
- 关于CryptoJS中md5加密以及aes加密的随笔
最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- Asp.net Core中使用Session
前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...
- 【探索】在 JavaScript 中使用 C 程序
JavaScript 是个灵活的脚本语言,能方便的处理业务逻辑.当需要传输通信时,我们大多选择 JSON 或 XML 格式. 但在数据长度非常苛刻的情况下,文本协议的效率就非常低了,这时不得不使用二进 ...
- JS里面Data日期格式转换
var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i ...
- ASP.NET Core的路由[2]:路由系统的核心对象——Router
ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路由参数的形式解析出来供后续请求处理流 ...
- Android 剪贴板详解
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Clipboard 如本文有助于你理解 Android 剪贴板,不妨给我一个 Star.对于码农而言, ...
- Impress.js上手 - 抛开PPT、制作Web 3D幻灯片放映
前言: 如果你已经厌倦了使用PPT设置路径.设置时间.设置动画方式来制作动画特效.那么Impress.js将是你一个非常好的选择. 用它制作的PPT将更加直观.效果也是嗷嗷美观的. 当然,如果用它来装 ...
- windows 7(32/64位)GHO安装指南(序篇)~
大家好,本人是高三刚毕业,即将踏入校园的程序猿~我写这篇文章呢,主要是想巩固一下之前对于电脑的基础知识理论,也希望能帮助没有电脑基础的同学能维护一下自己的电脑,要是能帮助女生修电脑那就是更好啦~~哈哈 ...
- HP服务器 hp 360g5 centos7安装问题
HP服务器 hp 360g5 centos7安装问题 一 :启动盘无法识别硬盘 1.进入安装光盘,用上下键选择安装centos--Install Centos7(注意不可按Enter键),如图: 2 ...