设为首页收藏本站
查看: 21338|回复: 83

网络基础学习篇 ----- 获取天气信息(C++实现)

  [复制链接]
  • TA的每日心情
    奋斗
    2018-6-1 21:33
  • 签到天数: 177 天

    [LV.7]常住居民III

    发表于 2017-9-19 11:17:04 | 显示全部楼层 |阅读模式
    无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。

    这里也是一样的,也是向服务器发送一个GET请求,然后接收数据,接着请求数据。

    处理之前,得先来看看我们需要 的数据是什么。如下图


    用红色圆圈画的部分,就是网页上显示的东西,而下面用方框 的画的部分,就是相应的HTML代码

    我们要做的,就是从服务器上接收到这些源码,然后进行处理。

    其中,有一些函数,如:socket(),connect(),send(),recv()之类,这些都已经在 "一起愉快的开黑吧"小系列中讲过了,就不重复。

    话说,手动处理这些东西是很麻烦的,如果有时间的小伙伴可以自己封装一个类就行,使用其它网络上有的库来处理也行。
    这里是为了让小伙伴们了解整个过程 ,所以手动处理了。

    其它,下面还有6个<li>...</li>,这里包含的就是后面六天的天气情况,并没有处理,只处理了当天的,但方法是一样的
    有兴趣的小伙伴可以 自己去试试 ,毕竟大神之路是需要自己走的,哈哈。

    希望小伙伴们能举一反三,让我的这块砖头引出古玉……

    下面是处理后的信息


    代码如下:
    环境:VS2013 + Win7
    1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
    2. #define _CRT_SECURE_NO_WARNINGS
    3. #include <WinSock2.h>
    4. #include <iostream>
    5. #include <stdio.h>
    6. #include <string>

    7. #pragma comment(lib, "ws2_32")

    8. using namespace std;

    9. /* 用于取得错误信息 */
    10. DWORD g_dwErr;

    11. /* 保存数组的大小 */
    12. const int MAX_SIZE = 40960;

    13. /*
    14.         此结构体用于保存天气信息
    15. */
    16. typedef struct stWeatherInfo
    17. {
    18.         string date;        //日期
    19.         string wea;                //天气
    20.         string tem;                //温度
    21.         string win;                //风力
    22. }WeatherInfo, *pWeatherInfo;

    23. /* 用于处理THML中的数据,把相应信息放入结构体中 */
    24. void GetWeather(const string& s);

    25. int main()
    26. {
    27.         /* 初始化 */
    28.         WSADATA wsdata;
    29.         WSAStartup(MAKEWORD(2, 2), &wsdata);

    30.         const char* hostname = "www.weather.com.cn";
    31.         struct hostent* host = gethostbyname(hostname);

    32.         /* 初始化一个连接服务器的结构体 */
    33.         sockaddr_in serveraddr;
    34.         serveraddr.sin_family = AF_INET;
    35.         serveraddr.sin_port = htons(80);

    36.         /* 此处也可以不用这么做,不需要用gethostbyname,把网址ping一下,得出IP也是可以的 */
    37.         serveraddr.sin_addr.S_un.S_addr = *((int*)*host->h_addr_list);

    38.         int sock = socket(AF_INET, SOCK_STREAM, 0);
    39.         if (sock == -1) {
    40.                 cout << "socket error" << endl;
    41.                 return -1;
    42.         }
    43.         cout << "socket succeed" << endl;

    44.         if (connect(sock, (struct sockaddr*)&serveraddr, sizeof(sockaddr_in)) == -1) {
    45.                 g_dwErr = GetLastError();
    46.                 cout << "connect error" << endl;
    47.                 closesocket(sock);
    48.                 return -1;
    49.         }
    50.         cout << "connect succeed" << endl;

    51.         /* GET请求 */
    52.         const char* bufSned = "GET http://www.weather.com.cn/weather/101280601.shtml\r\n";

    53.         /* 发送GET请求 */
    54.         if (send(sock, bufSned, strlen(bufSned), 0) > 0) {
    55.                 cout << "send succeed" << endl;
    56.         } else {
    57.                 g_dwErr = GetLastError();
    58.                 cout << "send error, 错误编号: "<< g_dwErr << endl;
    59.                 closesocket(sock);
    60.                 return -1;
    61.         }

    62.         /* 文件,用于把HTML源码保存起来,没什么用处,只是为了自己看一下源码而已 */
    63.         FILE *fp;
    64.         fp = fopen("E:/get.txt","w");

    65.         char BufRecv[MAX_SIZE] = {};
    66.         int nLen = 0;
    67.         string HtmlData;

    68.         /* 开始接收数据 */
    69.         while ((nLen = recv(sock, BufRecv, MAX_SIZE, 0)) > 0) {

    70.                 /* 写文件 */
    71.                 fwrite(BufRecv, 1, nLen, fp);

    72.                 /* 把数组拼接成string类型,方便下面的处理 */
    73.                 HtmlData += BufRecv;
    74.         }

    75.         /* 开始分析HTML */
    76.         string Area0 = "<ul class=\"t clearfix\">";
    77.         string Area1 = "<li class=\'on\'>";
    78.         string Area2 = "</li>";

    79.         string::size_type PosBegin0;
    80.         string::size_type PosBegin;
    81.         string::size_type PosEnd;
    82.         string s;
    83.         PosBegin0 = HtmlData.find(Area0);
    84.         if (PosBegin0 > 0) {
    85.                 PosBegin = HtmlData.find(Area1, PosBegin0);
    86.                 PosEnd = HtmlData.find(Area2, PosBegin);
    87.                 s = HtmlData.substr(PosBegin, PosEnd - PosBegin + 5);
    88.                 //cout << s << endl;                //s即为存储天气信息的HTML源码
    89.         }
    90.         /* 结束HTML分析 */

    91.         /* 处理存储有天气部分的HTML代码 */
    92.         GetWeather(s);

    93.         fclose(fp);
    94.         cin.get();
    95.         closesocket(sock);
    96.         return 0;
    97. }

    98. void GetWeather(const string& s)
    99. {
    100.         WeatherInfo weatherinfo;
    101.         string::size_type DataPosBegin = s.find("<h1>");
    102.         string::size_type DataPosEnd = s.find("</h1>");
    103.         weatherinfo.date = s.substr(DataPosBegin + 4, DataPosEnd - DataPosBegin - 4);

    104.         string::size_type WeaPosEnd = s.find("</p>");
    105.         string::size_type WeaPosBegin = s.rfind(">", WeaPosEnd);
    106.         weatherinfo.wea = s.substr(WeaPosBegin + 1, WeaPosEnd - WeaPosBegin - 1);

    107.         string::size_type TemPosBegin1 = s.find("<span>");
    108.         string::size_type TemPosEnd1 = s.find("</span>");
    109.         string tem1 = s.substr(TemPosBegin1 + 6, TemPosEnd1 - TemPosBegin1 - 6);

    110.         string::size_type TemPosBegin2 = s.find("<i>");
    111.         string::size_type TemPosEnd2 = s.find("</i>", TemPosBegin2);
    112.         string tem2 = s.substr(TemPosBegin2 + 3, TemPosEnd2 - TemPosBegin2 - 3);
    113.         weatherinfo.tem = tem1 + "/" + tem2;

    114.         string::size_type WinPosBegin = s.find("</em>");
    115.         WinPosBegin = s.find("<i>", WinPosBegin);
    116.         string::size_type WinPosEnd = s.find("</i>", WinPosBegin);
    117.         weatherinfo.win = s.substr(WinPosBegin + 3, WinPosEnd - WinPosBegin - 3);

    118.         /*
    119.         cout << "日期:" << weatherinfo.date << endl;
    120.         cout << "天气:" << weatherinfo.wea << endl;
    121.         cout << "温度:" << weatherinfo.tem << endl;
    122.         cout << "风力:" << weatherinfo.win << endl;
    123.         */

    124.         /* 把获取的天气信息写入到文件中 */
    125.         FILE *fp;
    126.         fp = fopen("E:/weather.txt","w");
    127.         fwrite(weatherinfo.date.c_str(), 1, weatherinfo.date.length(), fp);
    128.         fwrite(weatherinfo.wea.c_str(), 1, weatherinfo.wea.length(), fp);
    129.         fwrite(weatherinfo.tem.c_str(), 1, weatherinfo.tem.length(), fp);
    130.         fwrite(weatherinfo.win.c_str(), 1, weatherinfo.win.length(), fp);

    131.         fclose(fp);
    132. }
    复制代码

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    点评

    所以我才会吐槽c++有些地方不如C#和易语言好耍  发表于 2018-5-7 04:07

    评分

    1

    查看全部评分

  • TA的每日心情
    奋斗
    2018-6-1 21:33
  • 签到天数: 177 天

    [LV.7]常住居民III

     楼主| 发表于 2017-9-19 22:40:06 | 显示全部楼层
    白妄常 发表于 2017-9-19 21:48
    对我有很大帮助,谢谢楼主

    嗯 ,有用就好。
    回复 支持 3 反对 0

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 14:31
  • 签到天数: 203 天

    [LV.7]常住居民III

    发表于 2017-9-19 21:48:00 | 显示全部楼层
    对我有很大帮助,谢谢楼主
    回复 支持 2 反对 0

    使用道具 举报

  • TA的每日心情

    2017-10-20 10:37
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2017-10-8 15:51:26 | 显示全部楼层
    学习代码怎么学习。
    回复 支持 2 反对 0

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-12-7 08:59
  • 签到天数: 298 天

    [LV.8]以坛为家I

    发表于 2017-9-25 08:28:17 | 显示全部楼层
    好贴~~~顶一个
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-12-14 14:25
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2017-9-25 11:32:36 | 显示全部楼层
    厉害呀  0.0
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-9-25 15:20
  • 签到天数: 48 天

    [LV.5]常住居民I

    发表于 2017-9-25 16:35:48 | 显示全部楼层
    学习学习,谢谢分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-4-6 21:24
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    发表于 2017-10-4 17:09:26 | 显示全部楼层
    为什么我编译不出来??????????
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2017-10-7 15:43
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2017-10-7 16:16:57 | 显示全部楼层
    学习了学习了,网络编程快忘记完了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-8-8 15:24
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2017-10-7 21:14:09 | 显示全部楼层
    厉害啊,怎么长的代码
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-6-1 21:33
  • 签到天数: 177 天

    [LV.7]常住居民III

     楼主| 发表于 2017-10-17 15:05:54 | 显示全部楼层
    WHOAMME 发表于 2017-10-4 17:09
    为什么我编译不出来??????????

    编译不出来就看看错误是哪些
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2017-11-6 12:07
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2017-10-17 19:45:42 | 显示全部楼层
    厉害 了,涨知识
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-10-15 10:47
  • 签到天数: 49 天

    [LV.5]常住居民I

    发表于 2017-10-22 15:10:01 | 显示全部楼层
    厉害了,大佬,666
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-12-1 20:00
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2017-10-24 19:23:05 来自手机 | 显示全部楼层
    对于我这个小白来说作用很大
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    站长推荐 上一条 /1 下一条

    红盟社区--中国红客联盟 

    Processed in 0.133129 second(s), 30 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    Powered by HUC © 2001-2017 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表