(原创)socket学习实验(一)——利用C 语言socket抓取一个网页内容
2016-04-01 15:27
393 查看
(纯手打,有问题可以交流)
最近在学习socket,然后做了一些小的实验,发现socket功能还真是强大,对于socket流使套接字在某种程度上其实是与终端的telnet相似的,IP地址对应socket里的sock地址,端口对应sock里的端口,然后就看自己在终端里发送命令,就如同利用socket的send和recv方法了,
我在终端上测试一个telnet,获取一个网页的内容:
~:telnet www.baidu.com 80 //首先进入到telnet
输入:GET / HTTP/1.1
输入:host bolg.chinaunix.net
![](http://blog.csdn.net/attachment/201511/20/30510400_1447984869axCJ.png)
回车后再按一次回车,就能获取网页代码:数量太大,仅仅粘贴一部分:
![](http://blog.csdn.net/attachment/201511/20/30510400_1447985189Tbo4.png)
这样就通过telnet抓取到一个网页,而利用socket也是如此,只是发送消息时将消息格式给变一下,就能实现这个功能:而我是将抓取的网页内容写到一个临时的html文件里,这样就可以将抓取的网页文件在浏览器中打开了,代码贴出:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#define PORT 80
//char *cmd = "GET / HTTP/1.1 \nhost:www.xust.edu.cn";
int main(int arg,char **argc)
{
printf("11111111\n");
int sockfd;
int fd;
struct sockaddr_in servaddr;
char buf[1024] ;
char tmp1[100];
char cmd[1024];
//char *cmd="GET /uid/30510400.html HTTP/1.1\r\nhost:blog.chinaunix.net\r\n\r\n";
struct hostent *host;
int n=0;
if((fd = open("text.html",O_CREAT|O_TRUNC|O_WRONLY)) < 0){
fprintf(stderr,"open error:%s\n",strerror(errno));
return -1;
}
if(arg != 2 ){
fprintf(stderr,"usage:./a.out IPaddress:%s\n",strerror(errno));
return -1;
}
printf("enter the web page path you want to grub,and if you want the all press enter key ");
fgets(tmp1,100,stdin);
tmp1[strlen(tmp1) - 1] = '\0';
sprintf(cmd,"GET /%s HTTP/1.1\r\nhost:%s\r\n\r\n",tmp1,argc[1]);
if((host = gethostbyname(argc[1])) == NULL){
fprintf(stderr,"get host by name error:%s\n",strerror(errno));
return -1;
}
printf("hostname:%s\n",host->h_name);
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
fprintf(stderr,"socket creat error :%s\n",strerror(errno));
return -1;
}
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n)) < 0){
fprintf(stderr,"set sock option error:%s\n",strerror(errno));
return -1;
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
// servaddr.sin_addr = *((struct in_addr *)host->h_addr);
servaddr.sin_addr = *((struct in_addr *)host->h_addr);
servaddr.sin_port = htons(PORT);
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){
fprintf(stderr,"connect error:%s\n",strerror(errno));
return -1;
}
if(send(sockfd,cmd,strlen(cmd),0) < 0){
fprintf(stderr,"send error:%s\n",strerror(errno));
return -1;
}
while(1){
if(recv(sockfd,buf,2048,0) < 1)
break;
write(fd,buf,strlen(buf));
}
close(sockfd);
close(fd);
printf("bye!\n");
return -1;
}
gcc编译之后运行:
![](http://blog.csdn.net/attachment/201511/20/30510400_1447986067E8SZ.png)
因为我想抓取我博客中的一篇文章,网址是这个http://blog.chinaunix.net/uid-30510400-id-5378031.html,所以我输入:uid-30510400-id-5378031.html
最后在当前目录下就能看到text.html文件,用浏览器打开,便可以看到自己抓取的那个网页,
![](http://blog.csdn.net/attachment/201511/20/30510400_144798627146zk.png)
很神奇吧,可以尝试抓取一下哦!
最近在学习socket,然后做了一些小的实验,发现socket功能还真是强大,对于socket流使套接字在某种程度上其实是与终端的telnet相似的,IP地址对应socket里的sock地址,端口对应sock里的端口,然后就看自己在终端里发送命令,就如同利用socket的send和recv方法了,
我在终端上测试一个telnet,获取一个网页的内容:
~:telnet www.baidu.com 80 //首先进入到telnet
输入:GET / HTTP/1.1
输入:host bolg.chinaunix.net
![](http://blog.csdn.net/attachment/201511/20/30510400_1447984869axCJ.png)
回车后再按一次回车,就能获取网页代码:数量太大,仅仅粘贴一部分:
![](http://blog.csdn.net/attachment/201511/20/30510400_1447985189Tbo4.png)
这样就通过telnet抓取到一个网页,而利用socket也是如此,只是发送消息时将消息格式给变一下,就能实现这个功能:而我是将抓取的网页内容写到一个临时的html文件里,这样就可以将抓取的网页文件在浏览器中打开了,代码贴出:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#define PORT 80
//char *cmd = "GET / HTTP/1.1 \nhost:www.xust.edu.cn";
int main(int arg,char **argc)
{
printf("11111111\n");
int sockfd;
int fd;
struct sockaddr_in servaddr;
char buf[1024] ;
char tmp1[100];
char cmd[1024];
//char *cmd="GET /uid/30510400.html HTTP/1.1\r\nhost:blog.chinaunix.net\r\n\r\n";
struct hostent *host;
int n=0;
if((fd = open("text.html",O_CREAT|O_TRUNC|O_WRONLY)) < 0){
fprintf(stderr,"open error:%s\n",strerror(errno));
return -1;
}
if(arg != 2 ){
fprintf(stderr,"usage:./a.out IPaddress:%s\n",strerror(errno));
return -1;
}
printf("enter the web page path you want to grub,and if you want the all press enter key ");
fgets(tmp1,100,stdin);
tmp1[strlen(tmp1) - 1] = '\0';
sprintf(cmd,"GET /%s HTTP/1.1\r\nhost:%s\r\n\r\n",tmp1,argc[1]);
if((host = gethostbyname(argc[1])) == NULL){
fprintf(stderr,"get host by name error:%s\n",strerror(errno));
return -1;
}
printf("hostname:%s\n",host->h_name);
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0){
fprintf(stderr,"socket creat error :%s\n",strerror(errno));
return -1;
}
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n)) < 0){
fprintf(stderr,"set sock option error:%s\n",strerror(errno));
return -1;
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
// servaddr.sin_addr = *((struct in_addr *)host->h_addr);
servaddr.sin_addr = *((struct in_addr *)host->h_addr);
servaddr.sin_port = htons(PORT);
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){
fprintf(stderr,"connect error:%s\n",strerror(errno));
return -1;
}
if(send(sockfd,cmd,strlen(cmd),0) < 0){
fprintf(stderr,"send error:%s\n",strerror(errno));
return -1;
}
while(1){
if(recv(sockfd,buf,2048,0) < 1)
break;
write(fd,buf,strlen(buf));
}
close(sockfd);
close(fd);
printf("bye!\n");
return -1;
}
gcc编译之后运行:
![](http://blog.csdn.net/attachment/201511/20/30510400_1447986067E8SZ.png)
因为我想抓取我博客中的一篇文章,网址是这个http://blog.chinaunix.net/uid-30510400-id-5378031.html,所以我输入:uid-30510400-id-5378031.html
最后在当前目录下就能看到text.html文件,用浏览器打开,便可以看到自己抓取的那个网页,
![](http://blog.csdn.net/attachment/201511/20/30510400_144798627146zk.png)
很神奇吧,可以尝试抓取一下哦!
相关文章推荐
- linux内核——进程管理
- iOS开发-UIView之动画效果的实现方法
- .js文件中写ajax请求
- dpdk初识
- Django Nginx+uwsgi 安装配置
- 模板---函数模板,类模板等
- mysql主库清理数据,从库保留
- apache RewriteRule
- Android —— Android应用程序真机调试(图文详解)
- Ubuntu安装磁共振处理软件Fsl步骤
- 【格灵深瞳】电话面试
- Linux进程间通信——消息队列:
- msgrcv error : Identifier removed(ERMID)错误解决;
- boa服务移植到安卓手机
- samba移植到android流程
- linux网络编程——套接字(socket)入门
- Linux 原始套接字--myping的实现
- linux 标准IO缓冲机制探究
- linux 进程(二) --- 进程的创建及相关api
- 进程间通信--信号(进程间通信唯一的异步方式)