利用acl_master的http库进行聚合天气预报信息的数据抓取

简介: 利用acl_master的http库进行聚合天气预报信息的数据抓取

1)acl_master是一个跨平台c/c++库,提供了网络通信库及服务器编程框架,同时提供更多的实用功能库及示例。

下载地址:Github: https://github.com/acl-dev/acl

2)聚合天气预报API接口注册

聚合数据的天气预报API接口其官网有提供,本人采用的是阿里云市场->API市场->生活服务栏下提供的,

*注册阿里云,有需要的阿里云产品通用代金券的可以点击下面链接进行领取:

https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pfb80n4a

阿里云提供聚合数据的天气预报API的类似描述

 该天气预报接口有多种套餐价格,是预购买使用,我们在聚合数据天气预报API接口需要用到APPCode,其API使用方式可以点击“全国天气预报”按键进入查看,页面涉及购买与使用介绍

3)acl http实现聚合数据天气预报信息的抓取

先定义了http抓取的一些参数

struct HttpApiArgWeather
{
    HttpApiArgWeather()
        : startTime(8)
        , endTime(8)
        , addr_("weather-ali.juheapi.com")
        , path_("/weather/index")
        , port_(80)
        , dtype_("json")
        , format_(1)
        , city_("上海")
        , authorization("APPCODE *******************************************")
        , upTime(60)
    {

    };
    int startTime;                //开始抓取信息时间(单位小时),可忽略项目需要
    int endTime;                //结束抓取信息时间(单位小时),可忽略项目需要
    std::string addr_;            // web 服务器地址  
    std::string path_;            // 本地请求的数据文件  
    int port_;                    //
    std::string dtype_;            //返回数据格式:json或xml,默认json
    int format_;                //未来6天预报(future)两种返回格式,1或2,默认1
    std::string city_;            //
    std::string authorization;    // 访问授权
    int upTime;                    //天气预报更新间隔,单位秒
};

/*

目前聚合数据的天气预报访问参数

addr_:weather-ali.juheapi.com

path_:/weather/index

city_:""

dtype_:json或xml

format_:1或2

authorization:其格式“APPCODE ***”,***=注册的AppCode

*/

以下是采用acl http库抓取聚合数据天气预报信息的关键代码(本例采用Json格式):

#include "acl_cpp/lib_acl.hpp" 

//HttpApiArgWeather myArgHttp

void HttpApiAclWeather::getHttpInfo()
{
    bool accept_gzip = false, send_body = false;

    //acl::log::stdout_open(true);
    acl::string aclurl, acladdr/*,aclContentType*/;
    aclurl.format("http://%s%s", myArgHttp.addr_.c_str(), myArgHttp.path_.c_str());
    acladdr.format("%s:%d", myArgHttp.addr_.c_str(), myArgHttp.port_);
    //aclContentType.format("application/json; charset=%s", myArgHttp.charset_.c_str());

    acl::http_request req(acladdr);

    acl::http_header& header = req.request_header();
    //
    //header.set_method(acl::HTTP_METHOD_POST);
    header.set_method(acl::HTTP_METHOD_GET);
    //
    //header.set_keep_alive(true);
    header.set_keep_alive(false);

    header.accept_gzip(accept_gzip ? true : false);

    //url
    header.set_url(aclurl);
    //host
    if (header.get_host() == NULL)
    {
        header.set_host(myArgHttp.addr_.c_str());
        printf(">>>set host: %s\r\n", myArgHttp.addr_.c_str());
    }
    else
        printf(">>>host: %s\r\n", header.get_host());
    
    //content_type
    //header.set_content_type(aclContentType);
    //header.set_content_length(1024);
    //param
    header.add_param("dtype", myArgHttp.dtype_.c_str());
    header.add_int("format", myArgHttp.format_);
    header.add_param("cityname", ASCII2UTF_8(myArgHttp.city_).c_str());
    //entry
    header.add_entry("Authorization", myArgHttp.authorization.c_str());
    //cookie
    //header.add_cookie("x-cookie-name", "cookie-value");

    bool rc = req.request(NULL, 0);
    // 只所以将 build_request 放在 req.request 后面,是因为
    // req.request 内部可能会修改请求头中的字段
    acl::string hdr;
    header.build_request(hdr);
    CLogger::createInstance()->Log(eTipMessage, "request header:\r\n%s\r\n", hdr.c_str());

    if (rc == false)
    {
        CLogger::createInstance()->Log(eTipMessage, "send request error");
        //break;
        return;
    }

    printf("send request ok!\r\n");

    // 取出 HTTP 响应头的 Content-Type 字段  

    const char* p = req.header_value("Content-Type");
    if (p == NULL || *p == 0)
    {
        CLogger::createInstance()->Log(eTipMessage, "no Content-Type");
        return;
    }
    // 分析 HTTP 响应头的数据类型  
    acl::http_ctype content_type;
    content_type.parse(p);
    //p = NULL;
    // 响应头数据类型的子类型  
    const char* stype = content_type.get_stype();

    bool ret;
    if (stype == NULL)
        ret = do_plain(req);
//#ifdef WIN32
    //else if (stricmp(stype, "xml") == 0)
//#else
    //else if (strcasecmp(stype, "xml") == 0)
//#endif
    //    ret = do_xml(req);
#ifdef WIN32
    else if (stricmp(stype, "json") == 0)//linux->strcasecmp
#else
    else if (strcasecmp(stype, "json") == 0)//linux->strcasecmp
#endif
        ret = do_json(req);
    else
        ret = do_plain(req);
    if (ret == true)
        CLogger::createInstance()->Log(eTipMessage, "read ok!");
    //stype = NULL;
};

// 处理 text/plain 类型数据  
bool HttpApiAclWeather::do_plain(acl::http_request& req)
{
    acl::string body;
    if (req.get_body(body/*, to_charset_.c_str()*/) == false)
    {
        CLogger::createInstance()->Log(eTipMessage, "get http body error");
        return false;
    }
    printf("body:\r\n(%s)\r\n", body.c_str());
    return true;
}

// 处理 text/json 类型数据  
bool HttpApiAclWeather::do_json(acl::http_request& req)
{
    acl::json body;
    if (req.get_body(body/*, to_charset_.c_str()*/) == false)
    {
        CLogger::createInstance()->Log(eTipMessage, "get http body error");
        return false;
    }

    clearWeather();
    WeatherData wd;
    bool weatherIsRight = false;
    acl::json_node* node = body.first_node();
    while (node)
    {
        if (node->tag_name())
        {
            std::string tagStr = std::string(node->tag_name());
            std::string valStr = std::string(node->get_text());
            if ("city" == tagStr) {
                weatherIsRight = true;
                wd.city = UTF_82ASCII(valStr);
            }
            if ("date_y" == tagStr) {
                wd.date = UTF_82ASCII(valStr);
            }
            if ("week" == tagStr) {
                wd.week = UTF_82ASCII(valStr);
            }
            if ("temperature" == tagStr) {
                wd.temperature = UTF_82ASCII(valStr);
            }
            if ("weather" == tagStr) {
                wd.weather = UTF_82ASCII(valStr);
            }
            if ("wind" == tagStr) {
                wd.wind = UTF_82ASCII(valStr);
            }
            if ("uv_index" == tagStr) {
                wd.uv_index = UTF_82ASCII(valStr);
            }
            printf("tag: %s", node->tag_name());
            if (!valStr.empty())
                printf(", text: %s\r\n", UTF_82ASCII(valStr).c_str());
            else
                printf("\r\n");
            if ("future" == tagStr) {
                break;
            }
        }
        node = body.next_node();
    }
    if (weatherIsRight) {
        char buf[512] = { 0 };
        sprintf(buf, "%s,%s,%s,%s,%s,%s,紫外强度:%s",wd.city.c_str(),wd.date.c_str(),wd.week.c_str()
        ,wd.temperature.c_str(),wd.weather.c_str(),wd.wind.c_str(),wd.uv_index.c_str());
        add(std::string(buf));
    }
    return true;
}

目录
相关文章
|
5月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
【7月更文挑战第31天】在网络数据的海洋中,使用Python的`requests`库构建网络爬虫就像探索未知的航船。HTTP协议指导爬虫与服务器交流,收集信息。HTTP请求包括请求行、头和体,响应则含状态行、头和体。`requests`简化了发送各种HTTP请求的过程。
86 4
|
2月前
|
JSON 网络协议 网络安全
详解新一代 HTTP 请求库:httpx
详解新一代 HTTP 请求库:httpx
82 1
|
3月前
|
数据采集 JSON API
🎓Python网络请求新手指南:requests库带你轻松玩转HTTP协议
本文介绍Python网络编程中不可或缺的HTTP协议基础,并以requests库为例,详细讲解如何执行GET与POST请求、处理响应及自定义请求头等操作。通过简洁易懂的代码示例,帮助初学者快速掌握网络爬虫与API开发所需的关键技能。无论是安装配置还是会话管理,requests库均提供了强大而直观的接口,助力读者轻松应对各类网络编程任务。
121 3
|
3月前
|
机器学习/深度学习 JSON API
HTTP协议实战演练场:Python requests库助你成为网络数据抓取大师
在数据驱动的时代,网络数据抓取对于数据分析、机器学习等至关重要。HTTP协议作为互联网通信的基石,其重要性不言而喻。Python的`requests`库凭借简洁的API和强大的功能,成为网络数据抓取的利器。本文将通过实战演练展示如何使用`requests`库进行数据抓取,包括发送GET/POST请求、处理JSON响应及添加自定义请求头等。首先,请确保已安装`requests`库,可通过`pip install requests`进行安装。接下来,我们将逐一介绍如何利用`requests`库探索网络世界,助你成为数据抓取大师。在实践过程中,务必遵守相关法律法规和网站使用条款,做到技术与道德并重。
55 2
|
3月前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
73 3
|
3月前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
85 8
|
3月前
|
JSON API 开发者
Python网络编程新纪元:urllib与requests库,让你的HTTP请求无所不能
【9月更文挑战第9天】随着互联网的发展,网络编程成为现代软件开发的关键部分。Python凭借简洁、易读及强大的特性,在该领域展现出独特魅力。本文介绍了Python标准库中的`urllib`和第三方库`requests`在处理HTTP请求方面的优势。`urllib`虽API底层但功能全面,适用于深入控制HTTP请求;而`requests`则以简洁的API和人性化设计著称,使HTTP请求变得简单高效。两者互补共存,共同推动Python网络编程进入全新纪元,无论初学者还是资深开发者都能从中受益。
52 7
|
4月前
|
开发者 Python
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
185 1
|
4月前
|
缓存 应用服务中间件 nginx
[nginx]定制http头信息
[nginx]定制http头信息
|
4月前
|
网络协议 Python
python requests库如何使用http连接池降低延迟 keepalive复用连接
Python的`requests`库通过内置的连接池机制支持HTTP Keep-Alive特性,允许复用TCP连接以发送多个请求,减少连接开销。默认情况下,`requests`不显式禁用Keep-Alive,其行为取决于底层HTTP库(如urllib3)及服务器的支持。通过创建`Session`对象并自定义`HTTPAdapter`,可以调整连接池大小和重试策略,进一步优化连接复用。测试显示,使用`Session`和定制的`HTTPAdapter`比普通请求方法能显著减少连续请求间的时间消耗,体现了Keep-Alive的优势。