中国黑客六道:网络基础学习篇-获取天气信息

无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。

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

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

中国黑客六道

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

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

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

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

这里是为了让小伙伴们了解整个过程 ,所以手动处理了。

其它,下面还有6个

...

,这里包含的就是后面六天的天气情况,并没有处理,只处理了当天的,但方法是一样的

有兴趣的小伙伴可以 自己去试试 ,毕竟大神之路是需要自己走的,哈哈。

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

一个黑客创业者

代码如下:

环境:VS2013 + Win7

一个黑客创业者

一个黑客创业者

一个黑客创业者

完整代码获取:

一个黑客创业者

gongzhonghao

代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

#include

#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

return -1;

}

cout

if (connect(sock, (struct sockaddr*)&serveraddr, sizeof(sockaddr_in)) == -1) {

g_dwErr = GetLastError();

cout

closesocket(sock);

return -1;

}

cout

/* 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

} else {

g_dwErr = GetLastError();

cout

closesocket(sock);

return -1;

}

/* 文件,用于把HTML源码保存起来,没什么用处,只是为了自己看一下源码而已 */

FILE *fp;

fp = fopen("E:/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 = "

";

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

}

/* 结束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

cout

cout

cout

*/

/* 把获取的天气信息写入到文件中 */

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);

}

本文来自企鹅号 - 一个黑客创业者媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构师学习

如何在ELK中解析各类日志文件

作为一个日志中心,它会收集各种各样的日志,可以用于问题排查,数据监控,统计分析等等。那么对于繁多的日志,它们都有各自的存储格式,我们如何来区分它们,对于不同的日...

2.1K50
来自专栏about云

OpenStack计费Billing功能前瞻(一)

问题导读: 1.openstack现阶段计费项目情况? 2.需要怎样的环境实现? 3.在没有cloudkitty的情况下如何实现? 4.最终的流程图是什么? ...

55960
来自专栏信安之路

常见端口及安全测试

在渗透测试中,端口扫描是一个非常重要的环节,端口扫描的目的是了解服务器上运行的服务信息,针对不同的端口进行不同的安全测试,本文的主要内容是关于常见端口安全隐患以...

26500
来自专栏Python中文社区

那些年在win下填过的Django坑

專 欄 ❈ JacobYRJ,Python中文社区专栏作者 Python语言爱好者,目前在做Django项目。 Github博客:https://JacobY...

19970
来自专栏Seebug漏洞平台

Django CSRF Bypass (CVE-2016-7401) 漏洞分析

Author: p0wd3r (知道创宇404安全实验室) Date: 2016-09-28 0x00 漏洞概述 1.漏洞简介 Django是一个由Python...

36050
来自专栏北京马哥教育

某次压测时物理内存被用光 Tomcat 被 Kernel kill 掉的案例

? 背景描述 某项目结构图如下(前端交互式体验及对象存储为主,Redis 及 rds 负载较小没有画出): ? web1 和 web2 是两个 Apache,...

33270
来自专栏架构师之旅

关于Socket高并发的原理介绍及使用Apache Mina带来线上的问题分析

上周在线上出现了一个很低级的问题,但是正是这个低级的问题引起了我的兴趣,其实所谓的低级是因为配置文件配置错了,原本线上是为每个客户端设置了一个席位,就说是客户端...

42630
来自专栏大内老A

并发与实例上下文模式: WCF服务在不同实例上下文模式下具有怎样的并发表现

通过《上篇》介绍,我们知道了如何通过编程和配置的方式设置相应的最大并发量,从而指导WCF的限流体系按照你设定的值对并发的服务调用请求进行限流控制。那么,在WCF...

19460
来自专栏大内老A

控制并发访问的三道屏障: WCF限流(Throttling)体系探秘[下篇]

通过《上篇》介绍,我们知道了如何通过编程和配置的方式设置相应的最大并发量,从而指导WCF的限流体系按照你设定的值对并发的服务调用请求进行限流控制。那么,在WCF...

22650
来自专栏从流域到海域

如何在Mule 4 Beta中实现自动流式传输

原文地址:https://dzone.com/articles/how-automatic-streaming-in-mule-4-beta-works

20750

扫码关注云+社区

领取腾讯云代金券