科林Linux7_网络爬虫

一、爬虫

网络资源的下载工具,工作与万维网环境,持续获取网页网站中的网络信息。可持续的数据采集机器人

1、搜索引擎技术使用爬虫

2、数据分析、数据挖掘领域,需要爬虫进行数据准备

3、数据批处理、采集,大量获取某些网站中的网络资源

爬虫进行数据准备截断,数据下载完毕、如何处理与爬虫无关,爬虫只负责下载

网站之间、网页之间是强关联的,通过超链接技术指向新的网页或网站。通过强关联特性,完成若干网页的拓扑跳转与处理

网页与网页之间有关联:出链接、入链接

理论上,通过一个有效的网页可以拓扑所有的网页。

爬虫在网页的工作:

  1. 获取资源

  2. 获取跳转地址(新链接)

二、网络资源的种类:

  1. 文本资源(txt,html,shtm,xml)

  2. 二进制数据(jpg,png,gif,bmp)

  3. 音频数据(mp3)

  4. 视频数据(mp4,rmvb,flv)

URL网络资源定位符,所有的网络资源,都有唯一的URL

三、关于B/S架构(浏览器/web服务器模型)

爬虫属于客户端,模拟浏览器行为,获取网站资源

使用http协议(基于TCP),只要获取了目标的端口和IP,可以直接对网站web服务进行连接

如果网站使用https协议(SSL),我们需要与网站进行安全连接openssl,否则无法与网站交互

① http协议的使用

② 正则表达式技术(html语言)

1)下载网页

2)提取关键数据

3)匹配更多新地址

爬虫的步骤:

1、下载资源

2、持续拓扑执行,获取若干资源

四、http下载

资源的下载流程(http 80,https 443):

(一)URL地址解析

  1. 资源完整的URL

  2. 协议类型

  3. 网站域名

cs 复制代码
#include<netdb.h>
struct hostent* ent = gethostbyname(域名);
//ent->h_addr_list;地址表中存储指向服务的公网IP,大端序
  1. 存储路径

  2. 资源名

  3. 端口

  4. ip地址

cs 复制代码
//Analytical_url.c
#include<spider.h>

int Analytical_url(url_t* url){
	int flag=0;//遍历下标
	int j=0;//写入下标
	int start_len;//协议头长度
	int fsize=0;//文件名长度
	char* array[]={"http://","https://",NULL};

	//初始化url中未使用数组
	bzero(url->save_path,1024);
	bzero(url->domain,1024);
	bzero(url->file,1024);
	bzero(url->ip,16);

	//判定协议类型
	if(strncmp(url->origin,array[0],strlen(array[0]))==0){
		url->type=0;
		url->port=80;
		start_len=strlen(array[0]);
	}
	else{

		url->type=1;
		url->port=443;
		start_len=strlen(array[1]);
	}

	//获取域名
	for(flag=start_len;url->origin[flag]!='/';flag++){
		url->domain[j]=url->origin[flag];
		j++;
	}
	j=0;

	//获取文件名长度
	for(flag=strlen(url->origin);url->origin[flag]!='/';flag--,fsize++);
	//获取文件名
	for(flag=strlen(url->origin)-fsize+1;url->origin[flag]!='\0';flag++){
		url->file[j]=url->origin[flag];
		j++;
	}
	j=0;

	//获取路径
	for(flag=start_len+strlen(url->domain);flag<strlen(url->origin)-fsize+1;flag++){
		url->save_path[j]=url->origin[flag];
		j++;
	}

	//获取ip
	struct hostent* ent=NULL;
	if((ent=gethostbyname(url->domain))==NULL){
		printf("gethostbyname fail\n");
		exit(0);
	}
	inet_ntop(AF_INET,ent->h_addr_list[0],url->ip,16);
	
	printf("spider [1] Analytical_url:\norigin:%s\ndomain:%s\npath:%s\nfile:%s\nip:%s\nport:%d\ntype:%d\n",url->origin,url->domain,url->save_path,url->file,url->ip,url->port,url->type);
}

(二)网络初始化

cs 复制代码
//Net_initalizer.c
#include<spider.h>

int Net_initalizer(){
	int sock;
	if((sock=socket(AF_INET,SOCK_STREAM,0))==-1){
		perror("sock create fail");
		exit(0);
	}
	printf("spider [2] sock create sucess\n");
	return sock;
}

(三)连接

cs 复制代码
//Connection_web.c
#include <spider.h>

int Connection_web(int sock,url_t* url){
	//构造网络信息
	struct sockaddr_in webaddr;
	webaddr.sin_family=AF_INET;
	webaddr.sin_port=htons(url->port);
	inet_pton(AF_INET,url->ip,&webaddr.sin_addr.s_addr);

	if((connect(sock,(struct sockaddr*)&webaddr,sizeof(webaddr)))==1){
		perror("connection failed");
		exit(0);
	}
	printf("spider [3] connection sucess\n");
	return 0;
}

(四)资源下载

  1. 构建请求头(http请求协议)

页面请求方式:GET POST

请求资源权重:对于一个网页的性能和体验来讲,控制好请求发起的优先级是非常重要的,网络带宽是有限的,优先去加载重要的资源,让次要的资源延后,就可以让我们的网站体验提升一个台阶。

长链接:客户端主动连接,客户端主动断开

短连接:客户端主动连接,服务端主动断开,请求响应交互一次

cs 复制代码
#include<spider.h>

int Create_request_str(char* request,url_t* node){
	bzero(request,4096);
	sprintf(request,"GET %s HTTP/1.1\r\n"\
					"Accept:text/html,application/sgtml+xml;q=0.9,image;q=0.8\r\n"\
					"User-Agent:Mozilla/5.0 (X11; Linux x86_64)\r\n"\
					"Host:%s\r\n"\
					"Connection:close\r\n\r\n"\
					,node->origin,node->domain);
	printf("spider [4] create_requeset:%s sucess\n",request);
	return 0;
}
  1. 发送请求头

  2. 服务器解析请求

  3. 爬虫客户端读取响应

根据响应码,判断响应是否成功,成功则进入存储流程

响应头一般都小于8192,为了一次完整的读完响应头,第一次读直接读8192。会读到完整的响应头和一部分响应体

HTTP/1.1 响应码 响应信息\r\n

cs 复制代码
#include<spider.h>

int Get_response_code(char* response){
	regex_t reg;
	regmatch_t match[2];
	int code;
	char str_code[10];
	bzero(str_code,10);
	char* reg_str="HTTP/1.1 \\([^\r\n]\\+\\?\\)\r\n";
	regcomp(&reg,reg_str,0);
	if((regexec(&reg,response,2,match,0))==0){
		snprintf(str_code,match[1].rm_eo-match[1].rm_so+1,"%s",response+match[1].rm_so);
	}
	sscanf(str_code,"%d",&code);
	return code;
}
  1. 爬虫处理响应内容获取存储资源到磁盘
cs 复制代码
//Download.c
#include<spider.h>

int Download(char* request,int sock,url_t* url){
	char buf[8192];
	char response[4096];
	bzero(buf,sizeof(buf));
	bzero(response,sizeof(response));
	int len;
	char* pos=NULL;
	int fd;
	
		//发送请求头
		if((send(sock,request,strlen(request),0))==-1){
			perror("first send request faile");
			return -1;;
		}
		printf("spider [5] send_requset sucess\n");
	
		//首次读取响应
		if((len=recv(sock,buf,sizeof(buf),0))==-1){
			perror("firsr recv failed");
			return -1;
		}
		if((pos=strstr(buf,"\r\n\r\n"))==NULL){
			printf("strstr error\n");
			return -1;
		}
		snprintf(response,pos-buf+4,"%s",buf);//提取响应头
		printf("spider [6] Get_response head:%s sucess\n",response);
	
		//提取响应码
		int code;
		code=Get_response_code(response);
		if(code==200){
			fd=open(url->file,O_RDWR|O_CREAT,0664);
			//写入部分
			write(fd,pos+4,len-(pos-buf+4));
			bzero(buf,sizeof(buf));
			while((len=recv(sock,buf,sizeof(buf),0))>0){
				write(fd,buf,len);
			}
			close(fd);
			printf("spider [7] %d download sucess\n",code);
		}
		else{
			printf("spider [7] %d download fail\n",code);
			close(sock);
			return -1;
		}
		close(sock);

	return 0;
}	

五、https下载

关于HHTPS协议,最大限度保证传输安全

openssl技术,可以完成https协议的安全认证

bash 复制代码
sudo apt-get install libssl-dev
sudo apt-get install libssl-doc

man SSL

http不安全,数据未加密保护,https如何改善?

  1. https协议采用嵌套加密方式,最大限度保证传输安全

  2. 通过认证,让客户端验证服务器的CA数字证书,看是否有效

加密:

密钥对。多个公钥和一个私钥构成,密文串由128位随机码组成,保证唯一性

私钥加密数据,公钥解密

对称加密:安全性低,适合加密大段数据,速度快

非堆成加密(RSA):安全性高,适合加密小段重要数据,速度慢

https 单向认证

bash 复制代码
gcc *.c -I ../include -lssl -lcrypto -o download
cs 复制代码
//Openssl_init.c
#include<spider.h>

ssl_t* Openssl_init(int sock){
	ssl_t* ssl=NULL;
	if((ssl=(ssl_t*)malloc(sizeof(ssl_t)))==NULL){
		perror("malloc ssl faile");
		return NULL;
	}
	SSL_load_error_strings();//初始化错误处理函数
	SSL_library_init();//初始化ssl库函数
	OpenSSL_add_ssl_algorithms();//初始化加密散列函数
	
	ssl->sslctx=SSL_CTX_new(SSLv23_method());
	ssl->sslsock=SSL_new(ssl->sslctx);
	SSL_set_fd(ssl->sslsock,sock);//使用tcp sock设置安全套接字
	SSL_connect(ssl->sslsock);//发起https安全认证

	return ssl;
}
cs 复制代码
//Download.c
#include<spider.h>

int Download(char* request,int sock,url_t* url,ssl_t* ssl){
	char buf[8192];
	char response[4096];
	bzero(buf,sizeof(buf));
	bzero(response,sizeof(response));
	int len;
	char* pos=NULL;
	int fd;
	if(ssl){
		//发送请求头
		if((SSL_write(ssl->sslsock,request,strlen(request)))==-1){
			perror("first send request faile");
			return -1;;
		}
		printf("spider [5] HTTPS send_requset sucess\n");
	
		//首次读取响应
		if((len=SSL_read(ssl->sslsock,buf,sizeof(buf)))==-1){
			perror("firsr recv failed");
			return -1;
		}
		if((pos=strstr(buf,"\r\n\r\n"))==NULL){
			printf("strstr error\n");
			return -1;
		}
		snprintf(response,pos-buf+4,"%s",buf);//提取响应头
		printf("spider [6] HTTPS Get_response head:%s sucess\n",response);
	
		//提取响应码
		int code;
		code=Get_response_code(response);
		if(code==200){
			fd=open(url->file,O_RDWR|O_CREAT,0664);
			//写入部分
			write(fd,pos+4,len-(pos-buf+4));
			bzero(buf,sizeof(buf));
			while((len=SSL_read(ssl->sslsock,buf,sizeof(buf)))>0){
				write(fd,buf,len);
			}
			close(fd);
			free(ssl);
			ssl=NULL;
			printf("spider [7] %d HTTPS download sucess\n",code);
		}
		else{
			printf("spider [7] %d HTTPS download fail\n",code);
			close(sock);
			free(ssl);
			ssl=NULL;
			return -1;
		}
		close(sock);	
	}
	else{...}
	return 0;
}	

五、持续拓扑与下载资源

种子URL

优化选项

1、DNS 优化

进程中自建缓存地址,便于后续的使用与访问,减少gethostbyname(开销大)的调用

2、去重优化

使用Hash表保存url,进行哈希去重。为了提高去重效率(哈希冲突),可以采用布隆过滤器。但是使用hash的内存占用问题无法解决

3、并发优化,线程池并发爬虫

获取更多时间片,提高爬虫的工作能力。随不能提高下载速度,但是可以多线程存储、多线程解析,缩减任务的完成时间

4、UA池 IP池

爬虫的抓取策略

可以用图改变爬虫的工作方式

反爬虫机制

反反爬虫

相关推荐
IT毕设实战小研20 小时前
电影数据可视化推荐系统
大数据·后端·爬虫·python·算法·信息可视化·课程设计
笔触狂放1 天前
第3章 抓取静态网页数据
爬虫·python
笔触狂放1 天前
第1章 认识网络爬虫
爬虫
深蓝电商API2 天前
Referer 校验原理
爬虫·referer
天空1102 天前
你的网站在 AI 眼里是什么样:三类「人能看见、AI 看不见」的内容
爬虫·seo
zx_741484812 天前
【Python入门】爬虫实战:Requests + XPath 从基础到实战
开发语言·爬虫·python
for_ever_love__2 天前
python爬虫: GET请求与POST请求
开发语言·爬虫·python·网络编程
IT毕设实战小研2 天前
基于安卓的考研资讯系统设计与实现
android·大数据·vue.js·爬虫·python·考研·课程设计
IT毕设实战小研2 天前
基于安卓的空气质量查询系统
android·大数据·vue.js·爬虫·python·django·课程设计
benchmark_cc3 天前
1000只ETF的5分钟K线如何批量获取?QuantDash分页策略与高性能Python实践
开发语言·人工智能·爬虫·python·算法·quantdash·量化数据源