帮忙调试,一小段抓取网页的C程序!

LeonTown 2009-12-16 10:20:06
从网上抄的一段代码,
用于抓取指定的网页。
代码如下:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
//#endif

char* host = "www.baidu.com"; //指定为抓取www.baidu.com页面
int port = 80;

int main(void)
{
char buffer[4096];
int isock;
struct sockaddr_in pin;
struct hostent * remoteHost;
char message[512];
int done = 0;
int chars = 0;
int l = 0;

if( (remoteHost = gethostbyname(host)) == 0 )
{
printf("Error resolving host\n");
exit(1);
}

bzero(message,sizeof(message));
bzero(&pin,sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_port = htons(port);
pin.sin_addr.s_addr = ( (struct in_addr *)(remoteHost->h_addr) )->s_addr;

if( (isock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Error opening socket!\n");
exit(1);
}
sprintf(message, "GET / HTTP/1.1\r\n");
strcat(message, "Host:www.baidu.com\r\n");
strcat(message, "Accept: */*\r\n");
strcat(message, "User-Agent: Mozilla/4.0(compatible)\r\n");
strcat(message, "connection:Keep-Alive\r\n");
strcat(message, "\r\n\r\n");

printf("%s",message);

if( connect(isock, /*(void *)*/ (const sockaddr*)&pin, sizeof(pin)) == -1 )
{
printf("Error connecting to socket\n");
exit(1);
}

if( send(isock, message, strlen(message), 0) == -1)
{
printf("Error in send\n");
exit(1);
}

while(done == 0)
{
l = recv(isock, buffer, 1, 0);
if( l < 0 )
done = 1;
switch(*buffer)
{
case '\r':
break;
case '\n':
if(chars == 0)
done = 1;
chars = 0;
break;
default:
chars++;
break;
}
printf("%c",*buffer);
}

printf("begin to crawling page\n");

do
{
l = recv(isock, buffer, sizeof(buffer) - 1, 0);
if( l < 0 )
break;
*(buffer + l) = 0;
fputs(buffer, stdout);
}while( l > 0 );

// close(isock);
shutdown(isock, SHUT_RDWR);
return 0;
}


编译运行后,
程序在抓取一部分信息后,会“僵死”住。
希望大家能帮忙找出问题在哪里。

抓取其它的网页也是类似的“僵死”问题。

另外,curl命令还真是很牛逼,
不知道代码是怎么实现的。。。
...全文
166 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjh274 2011-10-06
  • 打赏
  • 举报
回复
我认为这段代码并没有实现网页抓取,你只是获取了整个网页啊。
小菜_默 2009-12-16
  • 打赏
  • 举报
回复
建议再给recv设置个超时吧。
LeonTown 2009-12-16
  • 打赏
  • 举报
回复
嗯,
第一段recv代码能够成功返回,
但第二段recv就阻塞住了。

能说一下
具体该如何设置吗?

[Quote=引用 3 楼 wenxy1 的回复:]
C/C++ codewhile(done==0)
{
l= recv(isock, buffer,1,0);/* 非阻塞模式,当服务器不发送数据时,就阻塞在这里*/if( l<0 )
done=1;switch(*buffer)
{case'\r':break;case'?-
[/Quote]
Wenxy1 2009-12-16
  • 打赏
  • 举报
回复

while(done == 0)
{
l = recv(isock, buffer, 1, 0); /* 非阻塞模式,当服务器不发送数据时,就阻塞在这里*/
if( l < 0 )
done = 1;
switch(*buffer)
{
case '\r':
break;
case '\n':
if(chars == 0)
done = 1;
chars = 0;
break;
default:
chars++;
break;
}
printf("%c",*buffer);
}

Wenxy1 2009-12-16
  • 打赏
  • 举报
回复
你用了阻塞模式socket, 调用 setsockopt()设置成非阻塞模式。
LeonTown 2009-12-16
  • 打赏
  • 举报
回复
貌似,recv只执行了一次,
然后就阻塞在那里了。。。
快乐田伯光 2009-12-16
  • 打赏
  • 举报
回复
抓取网页直接用wget嘛,提取网页内容直接发用sed + awk嘛。写C程序多费时啊.

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧