linux下用socket实现一个简易的Web爬虫,从指定的一个初始页面的URL出发,链接最多获取三层
时间: 2024-03-16 18:46:26 浏览: 24
下面是一个简单的示例,实现一个简易的Web爬虫,从指定的一个初始页面的URL出发,链接最多获取三层。这个示例会获取每个页面的所有链接,并将结果保存到一个文本文件中。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUF_SIZE 1024
#define MAX_URLS 1000
void error_handling(char *msg);
void get_links(char *page_content, char *page_url, char **urls, int *num_urls);
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in serv_addr;
char request[BUF_SIZE];
char response[BUF_SIZE];
char *urls[MAX_URLS];
int num_urls = 0;
int i, j;
if(argc!=2) {
printf("Usage : %s <URL>\n", argv[0]);
exit(1);
}
urls[0] = argv[1];
num_urls++;
for(i=0; i<3; i++) {
printf("Level %d:\n", i+1);
for(j=0; j<num_urls; j++) {
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
error_handling("socket() error");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(urls[j]);
serv_addr.sin_port = htons(80);
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
error_handling("connect() error");
sprintf(request, "GET / HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", urls[j]);
write(sock, request, strlen(request));
memset(response, 0, sizeof(response));
read(sock, response, BUF_SIZE-1);
char *page_content = strstr(response, "\r\n\r\n") + 4;
get_links(page_content, urls[j], urls+num_urls, &num_urls);
close(sock);
}
for(j=0; j<num_urls; j++) {
printf("%s\n", urls[j]);
}
}
FILE *fp = fopen("urls.txt", "w");
for(i=0; i<num_urls; i++) {
fprintf(fp, "%s\n", urls[i]);
}
fclose(fp);
return 0;
}
void error_handling(char *msg) {
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
void get_links(char *page_content, char *page_url, char **urls, int *num_urls) {
char *p = page_content;
char *q;
char *url;
char buf[BUF_SIZE];
int len;
while((p = strstr(p, "href=\""))) {
p += 6;
if(*p=='/' || *p=='#') continue;
q = strchr(p, '\"');
len = q - p;
if(len>=BUF_SIZE-1) continue;
memset(buf, 0, sizeof(buf));
strncpy(buf, p, len);
if(strstr(buf, "http://")==0) {
url = malloc(strlen(page_url) + len + 2);
sprintf(url, "%s/%s", page_url, buf);
}
else {
url = malloc(len + 1);
strcpy(url, buf);
}
urls[(*num_urls)++] = url;
p = q;
}
}
```
这个示例从指定的初始页面开始,依次获取链接,直到达到指定的层数。它会从每个页面中提取所有链接,保存到一个数组中,并在控制台上打印出来。最终,它将所有链接保存到一个文本文件中。
需要注意的是,这个示例只是一个简单的Web爬虫,实际上,Web爬虫的实现要比这个复杂得多。例如,我们需要处理重定向、处理页面的编码、处理动态页面、避免陷入无限循环等等。