无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。
这里也是一样的,也是向服务器发送一个GET请求,然后接收数据,对数据进行处理,然后保存到文件中,weather.txt即为处理后的文件。
其中,有一些函数,如:socket(),connect(),send(),recv()之类,这些属于C语言的socket编程,找孙鑫老师的视频一集就能学会。
话说,手动处理这些东西是很麻烦的,如果有时间的小伙伴可以自己封装一个类就行,使用其它网络上有的库来处理也行。
这里是为了让小伙伴们了解整个过程 ,所以手动处理了。
其它,下面还有6个<li>...</li>,这里包含的就是后面六天的天气情况,并没有处理,只处理了当天的,但方法是一样的
有兴趣的小伙伴可以 自己去试试 ,毕竟大神之路是需要自己走的,哈哈。
希望小伙伴们能举一反三,让我的这块砖头引出古玉……
下面是处理后的信息
代码如下:
环境:VS2013 + Win7
这里也是一样的,也是向服务器发送一个GET请求,然后接收数据,对数据进行处理,然后保存到文件中,weather.txt即为处理后的文件。
其中,有一些函数,如:socket(),connect(),send(),recv()之类,这些属于C语言的socket编程,找孙鑫老师的视频一集就能学会。
话说,手动处理这些东西是很麻烦的,如果有时间的小伙伴可以自己封装一个类就行,使用其它网络上有的库来处理也行。
这里是为了让小伙伴们了解整个过程 ,所以手动处理了。
其它,下面还有6个<li>...</li>,这里包含的就是后面六天的天气情况,并没有处理,只处理了当天的,但方法是一样的
有兴趣的小伙伴可以 自己去试试 ,毕竟大神之路是需要自己走的,哈哈。
希望小伙伴们能举一反三,让我的这块砖头引出古玉……
下面是处理后的信息
代码如下:
环境:VS2013 + Win7
-
#define _WINSOCK_DEPRECATED_NO_WARNINGS
-
#define _CRT_SECURE_NO_WARNINGS
-
#include <WinSock2.h>
-
#include <iostream>
-
#include <stdio.h>
-
#include <string>
-
-
#pragma comment(lib, "ws2_32")
-
-
using namespace std;
-
-
/* 用于取得错误信息 */
-
DWORD g_dwErr;
-
-
/* 保存数组的大小 */
-
const int MAX_SIZE = 40960;
-
-
/*
-
此结构体用于保存天气信息
-
*/
-
typedef struct stWeatherInfo
-
{
-
string date; //日期
-
string wea; //天气
-
string tem; //温度
-
string win; //风力
-
}WeatherInfo, *pWeatherInfo;
-
-
/* 用于处理THML中的数据,把相应信息放入结构体中 */
-
void GetWeather(const string& s);
-
-
int main()
-
{
-
/* 初始化 */
-
WSADATA wsdata;
-
WSAStartup(MAKEWORD(2, 2), &wsdata);
-
-
const char* hostname = "www.weather.com.cn";
-
struct hostent* host = gethostbyname(hostname);
-
-
/* 初始化一个连接服务器的结构体 */
-
sockaddr_in serveraddr;
-
serveraddr.sin_family = AF_INET;
-
serveraddr.sin_port = htons(80);
-
-
/* 此处也可以不用这么做,不需要用gethostbyname,把网址ping一下,得出IP也是可以的 */
-
serveraddr.sin_addr.S_un.S_addr = *((int*)*host->h_addr_list);
-
-
int sock = socket(AF_INET, SOCK_STREAM, 0);
-
if (sock == -1) {
-
cout << "socket error" << endl;
-
return -1;
-
}
-
cout << "socket succeed" << endl;
-
-
if (connect(sock, (struct sockaddr*)&serveraddr, sizeof(sockaddr_in)) == -1) {
-
g_dwErr = GetLastError();
-
cout << "connect error" << endl;
-
closesocket(sock);
-
return -1;
-
}
-
cout << "connect succeed" << endl;
-
-
/* GET请求 */
-
const char* bufSned = "GET http://www.weather.com.cn/weather/101280601.shtml\r\n";
-
-
/* 发送GET请求 */
-
if (send(sock, bufSned, strlen(bufSned), 0) > 0) {
-
cout << "send succeed" << endl;
-
} else {
-
g_dwErr = GetLastError();
-
cout << "send error, 错误编号: "<< g_dwErr << endl;
-
closesocket(sock);
-
return -1;
-
}
-
-
/* 文件,用于把HTML源码保存起来,没什么用处,只是为了自己看一下源码而已 */
-
FILE *fp;
-
fp = fopen("get.txt","w");
-
-
char BufRecv[MAX_SIZE] = {};
-
int nLen = 0;
-
string HtmlData;
-
-
/* 开始接收数据 */
-
while ((nLen = recv(sock, BufRecv, MAX_SIZE, 0)) > 0) {
-
-
/* 写文件 */
-
fwrite(BufRecv, 1, nLen, fp);
-
-
/* 把数组拼接成string类型,方便下面的处理 */
-
HtmlData += BufRecv;
-
}
-
-
/* 开始分析HTML */
-
string Area0 = "<ul class=\"t clearfix\">";
-
string Area1 = "<li class=\'on\'>";
-
string Area2 = "</li>";
-
-
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("<h1>");
-
string::size_type DataPosEnd = s.find("</h1>");
-
weatherinfo.date = s.substr(DataPosBegin + 4, DataPosEnd - DataPosBegin - 4);
-
-
string::size_type WeaPosEnd = s.find("</p>");
-
string::size_type WeaPosBegin = s.rfind(">", WeaPosEnd);
-
weatherinfo.wea = s.substr(WeaPosBegin + 1, WeaPosEnd - WeaPosBegin - 1);
-
-
string::size_type TemPosBegin1 = s.find("<span>");
-
string::size_type TemPosEnd1 = s.find("</span>");
-
string tem1 = s.substr(TemPosBegin1 + 6, TemPosEnd1 - TemPosBegin1 - 6);
-
-
string::size_type TemPosBegin2 = s.find("<i>");
-
string::size_type TemPosEnd2 = s.find("</i>", TemPosBegin2);
-
string tem2 = s.substr(TemPosBegin2 + 3, TemPosEnd2 - TemPosBegin2 - 3);
-
weatherinfo.tem = tem1 + "/" + tem2;
-
-
string::size_type WinPosBegin = s.find("</em>");
-
WinPosBegin = s.find("<i>", WinPosBegin);
-
string::size_type WinPosEnd = s.find("</i>", 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("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);
- }