查看: 35061|回复: 106
打印 上一主题 下一主题

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

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

    [LV.7]常住居民III

    跳转到指定楼层
    1#
    发表于 2017-9-19 11:17:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。

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

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


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

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

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

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

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

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

    下面是处理后的信息


    代码如下:
    环境:VS2013 + Win7
    1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
    2. #define _CRT_SECURE_NO_WARNINGS
    3. #include
    4. #include
    5. #include
    6. #include

    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 = "
        ";
      • ? ? ? ? string Area1 = "
      • ";
      • ? ? ? ? string Area2 = "
      • ";

      • ? ? ? ? string::size_type PosBegin0;
      • ? ? ? ? string::size_type PosBegin;
      • ? ? ? ? string::size_type PosEnd;
      • ? ? ? ? string s;
      • ? ? ? ? PosBegin0 = HtmlData.find(Area0);
      • ? ? ? ? if (PosBegin0 > 0) {
      • ? ? ? ? ? ? ? ? PosBegin = HtmlData.find(Area1, PosBegin0);
      • ? ? ? ? ? ? ? ? PosEnd = HtmlData.find(Area2, PosBegin);
      • ? ? ? ? ? ? ? ? s = HtmlData.substr(PosBegin, PosEnd - PosBegin + 5);
      • ? ? ? ? ? ? ? ? //cout << s << endl;? ? ? ? ? ? ? ? //s即为存储天气信息的HTML源码
      • ? ? ? ? }
      • ? ? ? ? /* 结束HTML分析 */

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

      • ? ? ? ? fclose(fp);
      • ? ? ? ? cin.get();
      • ? ? ? ? closesocket(sock);
      • ? ? ? ? return 0;
      • }

      • void GetWeather(const string& s)
      • {
      • ? ? ? ? WeatherInfo weatherinfo;
      • ? ? ? ? string::size_type DataPosBegin = s.find("

        ");
      • ? ? ? ? string::size_type DataPosEnd = s.find("
      • ");
      • ? ? ? ? weatherinfo.date = s.substr(DataPosBegin + 4, DataPosEnd - DataPosBegin - 4);

      • ? ? ? ? string::size_type WeaPosEnd = s.find("");
      • ? ? ? ? string::size_type WeaPosBegin = s.rfind(">", WeaPosEnd);
      • ? ? ? ? weatherinfo.wea = s.substr(WeaPosBegin + 1, WeaPosEnd - WeaPosBegin - 1);

      • ? ? ? ? string::size_type TemPosBegin1 = s.find("");
      • ? ? ? ? string::size_type TemPosEnd1 = s.find("
      • ");
      • ? ? ? ? string tem1 = s.substr(TemPosBegin1 + 6, TemPosEnd1 - TemPosBegin1 - 6);

      • ? ? ? ? string::size_type TemPosBegin2 = s.find("");
      • ? ? ? ? string::size_type TemPosEnd2 = s.find("
      • ", TemPosBegin2);
      • ? ? ? ? string tem2 = s.substr(TemPosBegin2 + 3, TemPosEnd2 - TemPosBegin2 - 3);
      • ? ? ? ? weatherinfo.tem = tem1 + "/" + tem2;

      • ? ? ? ? string::size_type WinPosBegin = s.find("");
      • ? ? ? ? WinPosBegin = s.find("", WinPosBegin);
      • ? ? ? ? string::size_type WinPosEnd = s.find("
      • ", WinPosBegin);
      • ? ? ? ? weatherinfo.win = s.substr(WinPosBegin + 3, WinPosEnd - WinPosBegin - 3);

      • ? ? ? ? /*
      • ? ? ? ? cout << "日期:" << weatherinfo.date << endl;
      • ? ? ? ? cout << "天气:" << weatherinfo.wea << endl;
      • ? ? ? ? cout << "温度:" << weatherinfo.tem << endl;
      • ? ? ? ? cout << "风力:" << weatherinfo.win << endl;
      • ? ? ? ? */

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

      • ? ? ? ? fclose(fp);
      • }
    复制代码

    本帖子中包含更多资源

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

    x

    点评

    162
    好!\(^o^)/~? 发表于 2019-3-5 06:38
    所以我才会吐槽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
    对我有很大帮助,谢谢楼主

    嗯 ,有用就好。
  • TA的每日心情
    慵懒
    2019-9-6 08:53
  • 签到天数: 214 天

    [LV.7]常住居民III

    推荐
    发表于 2017-9-19 21:48:00 | 只看该作者
    对我有很大帮助,谢谢楼主
  • TA的每日心情

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

    [LV.2]偶尔看看I

    推荐
    发表于 2017-10-8 15:51:26 | 只看该作者
    学习代码怎么学习。
  • TA的每日心情
    开心
    2017-12-14 14:25
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    推荐
    发表于 2017-9-25 11:32:36 | 只看该作者
    厉害呀??0.0
  • TA的每日心情
    慵懒
    2019-4-2 17:37
  • 签到天数: 314 天

    [LV.8]以坛为家I

    6#
    发表于 2017-9-25 08:28:17 | 只看该作者
    好贴~~~顶一个
  • TA的每日心情
    慵懒
    2018-9-25 15:20
  • 签到天数: 48 天

    [LV.5]常住居民I

    7#
    发表于 2017-9-25 16:35:48 | 只看该作者
    学习学习,谢谢分享
  • TA的每日心情
    慵懒
    2018-4-6 21:24
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    8#
    发表于 2017-10-4 17:09:26 | 只看该作者
    为什么我编译不出来??????????
  • TA的每日心情
    无聊
    2017-10-7 15:43
  • 签到天数: 1 天

    [LV.1]初来乍到

    9#
    发表于 2017-10-7 16:16:57 | 只看该作者
    学习了学习了,网络编程快忘记完了
  • TA的每日心情
    郁闷
    2018-8-8 15:24
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    10#
    发表于 2017-10-7 21:14:09 | 只看该作者
    厉害啊,怎么长的代码
  • TA的每日心情
    奋斗
    2018-6-1 21:33
  • 签到天数: 177 天

    [LV.7]常住居民III

    12#
    ?楼主| 发表于 2017-10-17 15:05:54 | 只看该作者
    WHOAMME 发表于 2017-10-4 17:09
    为什么我编译不出来??????????

    编译不出来就看看错误是哪些
  • TA的每日心情
    慵懒
    2017-11-6 12:07
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    13#
    发表于 2017-10-17 19:45:42 | 只看该作者
    厉害 了,涨知识
  • TA的每日心情
    奋斗
    2019-9-7 01:26
  • 签到天数: 65 天

    [LV.6]常住居民II

    14#
    发表于 2017-10-22 15:10:01 | 只看该作者
    厉害了,大佬,666
  • TA的每日心情
    开心
    2017-12-1 20:00
  • 签到天数: 31 天

    [LV.5]常住居民I

    15#
    发表于 2017-10-24 19:23:05 来自手机 | 只看该作者
    对于我这个小白来说作用很大
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    红盟社区--中国亚博亚洲平台联盟?

    Processed in 0.210567 second(s), 30 queries.

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

    Powered by HUC ? 2001-2017 Comsenz Inc.

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

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

    Honor accompaniments. theme macfee

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