科林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池

爬虫的抓取策略

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

反爬虫机制

反反爬虫

相关推荐
兆。2 小时前
掌握 PyQt5:从零开始的桌面应用开发
开发语言·爬虫·python·qt
API快乐传递者8 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
兜里有糖请分享18 小时前
Python中序列化/反序列化JSON格式的数据
爬虫·python
亿牛云爬虫专家1 天前
用Puppeteer点击与数据爬取:实现动态网页交互
javascript·爬虫·爬虫代理·puppeteer·数据·代理ip·16yun
API快乐传递者1 天前
利用Python 的爬虫技术淘宝天猫销量和库存
开发语言·爬虫·python
操练起来1 天前
【Python实战案例】爬虫项目实例(附赠源码)
数据库·爬虫·python
编码小袁1 天前
利用爬虫爬取网站信息
爬虫
孤寒者1 天前
【实战篇】requests库 - 有道云翻译爬虫 【附:代理IP的使用】
爬虫·代理ip·隧道代理·有道云翻译爬虫·青果代理ip
=(^.^)=哈哈哈1 天前
从安全角度看多线程(附Golang举例)
爬虫·python·golang
Python_trys2 天前
Python网络爬虫入门篇!
开发语言·爬虫·python