0.9
This commit is contained in:
parent
93ff1c3214
commit
94c5622a4f
12
CWeatherDataGet.cpp
Normal file
12
CWeatherDataGet.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "CWeatherDataGet.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CWeatherDataGet::CWeatherDataGet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CWeatherDataGet::~CWeatherDataGet()
|
||||||
|
{
|
||||||
|
}
|
15
CWeatherDataGet.h
Normal file
15
CWeatherDataGet.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//------------------------------------
|
||||||
|
//author: jidzh
|
||||||
|
//data; 2017-10-30
|
||||||
|
//------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
class CWeatherDataGet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWeatherDataGet();
|
||||||
|
~CWeatherDataGet();
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
249
CWeatherDataSpider.cpp
Normal file
249
CWeatherDataSpider.cpp
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
|
||||||
|
#include "CWeatherDataSpider.h"
|
||||||
|
#include"AuxFun.h"
|
||||||
|
#include"parseXML.h"
|
||||||
|
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
|
//#include<WinSock2.h>
|
||||||
|
|
||||||
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
|
||||||
|
#define RECV_BUFF_LENGTH 1024*10
|
||||||
|
|
||||||
|
#define WEATHER_REALTIME 0
|
||||||
|
#define WEATHER_FORECAST 1
|
||||||
|
CWeatherDataSpider::CWeatherDataSpider()
|
||||||
|
{
|
||||||
|
m_strAreaCode = "天津";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CWeatherDataSpider::~CWeatherDataSpider()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWeatherDataSpider::CreateWSAdata()
|
||||||
|
{
|
||||||
|
WSADATA wsadata;
|
||||||
|
int ierror = -1;
|
||||||
|
if (ierror = WSAStartup(MAKEWORD(2, 2), &wsadata))
|
||||||
|
{
|
||||||
|
wchar_t tchTmp[100];
|
||||||
|
swprintf(tchTmp, 100, L"WSAStartup failure: %d\n", ierror);
|
||||||
|
ErrHandle(tchTmp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool CWeatherDataSpider::GetWeatherDataXml()
|
||||||
|
{
|
||||||
|
//------------------创建描述符----------------------
|
||||||
|
if (!CreateWSAdata()){ WSACleanup(); return false; }
|
||||||
|
//----------------------------------------------------
|
||||||
|
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (INVALID_SOCKET == m_socket)
|
||||||
|
{
|
||||||
|
ErrHandle(L"Create socket failed");
|
||||||
|
WSACleanup();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//unsigned long iMode = 1;
|
||||||
|
//int retMode = ioctlsocket(m_socket, FIONBIO, (unsigned long *)&iMode);
|
||||||
|
//if (retMode == SOCKET_ERROR)
|
||||||
|
//{
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
//if(connect(sock, (SOCKADDR*)&sa, sizeof(sa)))
|
||||||
|
|
||||||
|
//连接主机
|
||||||
|
if (!ConnectHost()) { goto bad; }
|
||||||
|
|
||||||
|
//发送请求
|
||||||
|
if (!SendReq()) { goto bad; }
|
||||||
|
//接收回应
|
||||||
|
if (!HandleAck()) { goto bad; }
|
||||||
|
else{ CloseConnect(); return true; }
|
||||||
|
|
||||||
|
bad:
|
||||||
|
CloseConnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWeatherDataSpider::CloseConnect()
|
||||||
|
{
|
||||||
|
if (m_socket)
|
||||||
|
{
|
||||||
|
closesocket(m_socket);
|
||||||
|
}
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWeatherDataSpider::ErrHandle(const std::wstring msg, int code)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWeatherDataSpider::CheckIfRecSucceed(char * buf, int nTotalRecv, int nFlag)
|
||||||
|
{
|
||||||
|
int PosStart = -1;
|
||||||
|
int PosEnd = -1;
|
||||||
|
if (buf == NULL || nTotalRecv <= 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析回复是否是200
|
||||||
|
//截取xml
|
||||||
|
//
|
||||||
|
std::string strHeadFind =buf;
|
||||||
|
//int n =strHeadFind.find("\r\n");
|
||||||
|
//if (-1 != (n = strHeadFind.rfind("200", n))) { return true; }
|
||||||
|
|
||||||
|
//获取内容长度
|
||||||
|
int iTotalRead = 0;
|
||||||
|
char* Output = NULL;//= new char[10000];
|
||||||
|
if (-1 != (PosStart = strHeadFind.find("Content-Length: ")))//该标签 加空格16个字符
|
||||||
|
{
|
||||||
|
PosStart = PosStart + 16;
|
||||||
|
PosEnd = strHeadFind.find("\r\n", PosStart);
|
||||||
|
std::string strLen = strHeadFind.substr(PosStart, PosEnd - PosStart);
|
||||||
|
int nlen = atoi(strLen.c_str());//转换
|
||||||
|
//寻找起始点
|
||||||
|
PosStart = strHeadFind.find("\r\n\r\n") + 4;
|
||||||
|
if (PosStart + nlen > nTotalRecv)
|
||||||
|
{
|
||||||
|
printf("err\n");
|
||||||
|
}
|
||||||
|
//char* Output = NULL;//= new char[10000];
|
||||||
|
|
||||||
|
//fun((char*)buf + PosStart, nlen, &Output, 1, iTotalRead);
|
||||||
|
inflate_read((char*)buf + PosStart, nlen, &Output, 1, iTotalRead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PosStart = strHeadFind.find("\r\n\r\n") + 4;
|
||||||
|
std::string strlen = strHeadFind.substr(PosStart);
|
||||||
|
PosEnd = strlen.find("\r\n",0);
|
||||||
|
//char tmp[8] = {0};
|
||||||
|
// strncpy(tmp, buf+ PosStart,4);
|
||||||
|
int nlen = strtol(strlen.substr(0,PosEnd).c_str(), 0, 16);//转换
|
||||||
|
|
||||||
|
|
||||||
|
// int iTotalRead = 0;
|
||||||
|
inflate_read((char*)buf + PosStart+2, nlen, &Output, 1, iTotalRead);
|
||||||
|
//char *s = Output;
|
||||||
|
|
||||||
|
}
|
||||||
|
FILE *fp = NULL;
|
||||||
|
fp = fopen("test.xml", "wb+");
|
||||||
|
int num = fwrite(Output, sizeof(char), iTotalRead, fp);
|
||||||
|
//fclose(fp);//如果没有这个会发生什么?
|
||||||
|
|
||||||
|
char txt[10000] = {0};
|
||||||
|
memcpy(txt, Output, iTotalRead);
|
||||||
|
// ReadFileAndTraversal();
|
||||||
|
XMLparse(txt);
|
||||||
|
std::string a = UTF8ToMultiByte(Output);
|
||||||
|
printf("%s", a.c_str());
|
||||||
|
printf("%d", iTotalRead>a.length()?1:0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWeatherDataSpider::SendReq()
|
||||||
|
{
|
||||||
|
//将 http://wthrcdn.etouch.cn/WeatherApi?city=天津 中文utf编码
|
||||||
|
//转换为 http://wthrcdn.etouch.cn/WeatherApi?city=%E5%A4%A9%E6%B4%A5
|
||||||
|
std::string SendTmp = MBCStoUTF8(m_strAreaCode.c_str());
|
||||||
|
std::string SendTmp2 = UrlEncode(SendTmp);
|
||||||
|
std::string strSnd = "GET /WeatherApi?city=" + SendTmp2;
|
||||||
|
strSnd += " HTTP/1.1\r\n";
|
||||||
|
strSnd += "HOST:wthrcdn.etouch.cn\r\n";
|
||||||
|
strSnd += "Connection:close\r\n\r\n";
|
||||||
|
strSnd += "User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:32.0) Gecko/20100101 Firefox/32.0\r\n\r\n";
|
||||||
|
|
||||||
|
if (SOCKET_ERROR == send(m_socket, strSnd.c_str(), strSnd.length(), 0))
|
||||||
|
{
|
||||||
|
int ret = WSAGetLastError();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//突然懒了,一次接收算了,整这么多幺蛾子木用
|
||||||
|
//@2017-12-05,之后还是要写成多次接收比较好,针对各种情况一步到位
|
||||||
|
bool CWeatherDataSpider::HandleAck()
|
||||||
|
{
|
||||||
|
char* pRecvBuff = new char[RECV_BUFF_LENGTH];//10kBbuff
|
||||||
|
memset(pRecvBuff, 0, RECV_BUFF_LENGTH);
|
||||||
|
|
||||||
|
bool bIfRecSucceed = false;
|
||||||
|
int nTotalNum = 0;
|
||||||
|
int nRet = SOCKET_ERROR;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
nRet = recv(m_socket, (char*)pRecvBuff + nTotalNum, RECV_BUFF_LENGTH, 0);
|
||||||
|
|
||||||
|
if (nRet == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int r = WSAGetLastError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (nRet == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nTotalNum += nRet;
|
||||||
|
if (CheckIfRecSucceed(pRecvBuff, nTotalNum, 0))
|
||||||
|
{
|
||||||
|
printf("%s", pRecvBuff);
|
||||||
|
bIfRecSucceed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
delete[] pRecvBuff;
|
||||||
|
if (!bIfRecSucceed)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWeatherDataSpider::ConnectHost()
|
||||||
|
{
|
||||||
|
sockaddr_in sa;
|
||||||
|
sa.sin_family = AF_INET;
|
||||||
|
sa.sin_port = htons(80);
|
||||||
|
|
||||||
|
struct hostent *lphost;
|
||||||
|
lphost = gethostbyname("wthrcdn.etouch.cn");
|
||||||
|
|
||||||
|
if (lphost != NULL)
|
||||||
|
{
|
||||||
|
sa.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseConnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//成功返回0
|
||||||
|
int nRet = connect(m_socket, (SOCKADDR*)&sa, sizeof(sa));
|
||||||
|
|
||||||
|
if (!nRet)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int wsaErr = WSAGetLastError();
|
||||||
|
std::wstring strErr = L"connect err";
|
||||||
|
ErrHandle(strErr, wsaErr);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
53
CWeatherDataSpider.h
Normal file
53
CWeatherDataSpider.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//------------------------------------
|
||||||
|
//author: jidzh
|
||||||
|
//data; 2017-10-30
|
||||||
|
//------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
class CWeatherDataSpider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWeatherDataSpider();
|
||||||
|
~CWeatherDataSpider();
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string m_strAreaCode;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//------------------------------------------------
|
||||||
|
SOCKET m_socket;
|
||||||
|
//WSADATA m_WSAdata;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
||||||
|
//创建描述符
|
||||||
|
bool CreateWSAdata();
|
||||||
|
//连接主机
|
||||||
|
bool ConnectHost();
|
||||||
|
|
||||||
|
//发送请求
|
||||||
|
bool SendReq();
|
||||||
|
|
||||||
|
//处理回应
|
||||||
|
bool HandleAck();
|
||||||
|
|
||||||
|
//检查是否接收成功
|
||||||
|
bool CheckIfRecSucceed(char * buf, int nTotalRecv, int nFlag);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool GetWeatherDataXml();
|
||||||
|
void CloseConnect();
|
||||||
|
void ErrHandle(const std::wstring msg, int code = 0);
|
||||||
|
};
|
||||||
|
|
120
parseXML.cpp
Normal file
120
parseXML.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include "parseXML.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include "rapidxml.hpp"
|
||||||
|
#include "rapidxml_utils.hpp"
|
||||||
|
#include "rapidxml_print.hpp"
|
||||||
|
using namespace rapidxml;
|
||||||
|
|
||||||
|
parseXML::parseXML()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
parseXML::~parseXML()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string ReadFile(const char* fileName)
|
||||||
|
{
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
std::string strBuffer;
|
||||||
|
FILE *fp = fopen(fileName, "rb");
|
||||||
|
if (NULL == fp)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const size_t byteRead = fread(buf, 1, sizeof(buf), fp);
|
||||||
|
if (0 == byteRead)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strBuffer.insert(strBuffer.end(), buf, buf + byteRead);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return strBuffer;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
int ReadFileAndTraversal()
|
||||||
|
{
|
||||||
|
//读取文件内容
|
||||||
|
std::string szFileBuf = ReadFile("test.xml");
|
||||||
|
|
||||||
|
//使用rapidxml::file读取文件更方便
|
||||||
|
rapidxml::file<> fdoc("test.xml");
|
||||||
|
|
||||||
|
//打印读取的内容
|
||||||
|
std::cout << fdoc.data() << std::endl;
|
||||||
|
|
||||||
|
rapidxml::xml_document<> doc;
|
||||||
|
doc.parse<0>(fdoc.data());
|
||||||
|
//doc.parse<0>(szFileBuf.c_str());
|
||||||
|
|
||||||
|
//打印整个XML内容
|
||||||
|
std::cout << doc.name() << std::endl;
|
||||||
|
|
||||||
|
//在XML文档中寻找第一个节点
|
||||||
|
const rapidxml::xml_node<> *ellipsoid = doc.first_node("EllipsoidParams");
|
||||||
|
if (NULL == ellipsoid)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历所有椭球信息
|
||||||
|
for (rapidxml::xml_node<> *datum = ellipsoid->first_node("Datum");
|
||||||
|
NULL != datum;
|
||||||
|
datum = datum->next_sibling())
|
||||||
|
{
|
||||||
|
//遍历单个椭球的所有属性
|
||||||
|
std::string szTmp("");
|
||||||
|
for (rapidxml::xml_attribute<char> * attr = datum->first_attribute("Name");
|
||||||
|
attr != NULL;
|
||||||
|
attr = attr->next_attribute())
|
||||||
|
{
|
||||||
|
szTmp.append(attr->name());//name() value()返回的字符串不会去掉首尾的空白字符
|
||||||
|
szTmp.append(": ");
|
||||||
|
szTmp.append(attr->value());
|
||||||
|
szTmp.append(", ");
|
||||||
|
}
|
||||||
|
std::cout << szTmp.c_str() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool XMLparse(char * data)
|
||||||
|
{
|
||||||
|
rapidxml::xml_document<> doc;
|
||||||
|
|
||||||
|
doc.parse<0>(data);
|
||||||
|
std::cout << doc.name() << std::endl;
|
||||||
|
|
||||||
|
//在XML文档中寻找第一个节点
|
||||||
|
const rapidxml::xml_node<> *ellipsoid = doc.first_node("resp");
|
||||||
|
if (NULL == ellipsoid)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历所有椭球信息
|
||||||
|
for (rapidxml::xml_node<> *datum = ellipsoid->first_node("weather");
|
||||||
|
NULL != datum;
|
||||||
|
datum = datum->next_sibling())
|
||||||
|
{
|
||||||
|
//遍历单个椭球的所有属性
|
||||||
|
std::string szTmp("");
|
||||||
|
for (rapidxml::xml_attribute<char> * attr = datum->first_attribute("Name");
|
||||||
|
attr != NULL;
|
||||||
|
attr = attr->next_attribute())
|
||||||
|
{
|
||||||
|
szTmp.append(attr->name());//name() value()返回的字符串不会去掉首尾的空白字符
|
||||||
|
szTmp.append(": ");
|
||||||
|
szTmp.append(attr->value());
|
||||||
|
szTmp.append(", ");
|
||||||
|
}
|
||||||
|
std::cout << szTmp.c_str() << std::endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
11
parseXML.h
Normal file
11
parseXML.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <tchar.h>
|
||||||
|
class parseXML
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
parseXML();
|
||||||
|
~parseXML();
|
||||||
|
};
|
||||||
|
|
||||||
|
bool XMLparse(char * data);
|
||||||
|
int ReadFileAndTraversal();
|
Reference in New Issue
Block a user