网络爬虫3 --- 编写代码将https的图片下载到本地

一、我们用应对HTTP的策略来应对HTTPS一定是行不通的,HTTPS除了与服务器进行基本的连接以后,还需要与服务器进行一个安全认证,只连接不认证是无法获取到资源的。认证基于连接,先连接再认证。
二、OPEN_SEEL库
1、我们需要第三方OPEN_SEEL库来帮助我们认证。
openssl安装

sudo apt-get install libssl-doc #openssl文档 
sudo apt-get install libssl-dev #openssl库

2、使用openssl编译时需要链接库

gcc *.c -I../include -lssl -lcrypto -o app

3、头文件

#include <openssl/ssl.h> 
#include <openssl/err.h> 

4、相关接口

SSL * sslsocket; //安全套接字  可以简单理解为webfd的升级版

SSL_CTX * sslctx; //安全认证上下文(保存了安全认证过程)
先创建上下文信息,然后用上下文去生成安全套接字。

SSL_load_error_strings(); //初始化加载openssl错误处理函数 

SSL_library_init(); //初始化openssl库 

OpenSSL_add_ssl_algorithms(); //初始化散列函数 (初始化加密方式)

SSL_CTX * sslctx = SSL_CTX_new(版本信息);  //new安全认证上下文
版本信息 = SSLv23_method();(有很多,这只是其中之一)

SSL * sslsocket = SSL_new(sslctx) //使用认证上下文信息创建安全套接字 

SSL_set_fd(sslsocket , webfd); //用已连接成功的webfd对sslsocket进行服务端关联设置,让sslsocket可以访问服务端

SSL_connect(sslsocket)  //与https服务端完成安全认证 , 认证成功可以交互数据 

//SSL提供了读写模块,加密解密读写 
SSL_read(SSL * sslsocket , cosnt char * buffer , ssize_t rsize);
SSL_write(SSL * sslsocket , char * buffer , ssize_t wsize);
RETURN VALUE: 成功返回读到的数据量, 读取完毕返回0 , 失败返回-1

5、改造下载模块,区分HTTP和HTTPS

//下载模块,发送请求,接收并处理响应 , 如果ssl为NULL表示http交互方式,否则https交互方式 。
int spider_response_download(int , char * , url_t * , ssl_t *);
#include<SPIDER.h>

int spider_response_download(int webfd , const char* req_head , url_t* node , ssl_t* ssl)
{
	char buffer[8192];
	char res_head[4096];
	int rsize;
	char *pos = NULL;
	int fd;
	bzero(buffer,sizeof(buffer));
	bzero(res_head,sizeof(res_head));

	if(!ssl)
	{
		send(webfd,req_head,strlen(req_head),0);
		printf("[5] HTTP Request_head Send To Webserver Successfully...\n");

		rsize = recv(webfd,buffer,sizeof(buffer),0);
		if((pos = strstr(buffer,"\r\n\r\n")) == NULL)
		{
			printf("spider_response_download strstr not found..\n");
			return -1;
		}

		snprintf(res_head,pos - buffer + 4,"%s",buffer);
		printf("[6] HTTP Get Response Head Successfully :\n%s",res_head);
		
		fd = open(node->save_file,O_RDWR|O_CREAT,0775);
		write(fd,pos + 4,rsize - (pos - buffer + 4));

		while((rsize = recv(webfd,buffer,sizeof(buffer),0)) > 0){
			write(fd,buffer,rsize);
			bzero(buffer,sizeof(buffer));
		}
		printf("[7] HTTP Download Successfully...\n");
		return 0;
	}
	else
	{
		SSL_write(ssl->sslsocket,req_head,strlen(req_head));
		printf("[5] HTTPS Request_head Send To Webserver Successfully...\n");
		rsize = SSL_read(ssl->sslsocket,buffer,sizeof(buffer));

		if((pos = strstr(buffer,"\r\n\r\n")) == NULL)
		{
			printf("spider_response_download strstr not found..\n");
			return -1;
		}

		snprintf(res_head,pos - buffer + 4,"%s",buffer);
		printf("[6] HTTPS Get Response Head Successfully :\n%s",res_head);
	
		fd = open(node->save_file,O_RDWR|O_CREAT,0775);
		write(fd,pos + 4,rsize - (pos - buffer + 4));

		while((rsize = SSL_read(ssl->sslsocket,buffer,sizeof(buffer))) > 0)
		{
			write(fd,buffer,rsize);
			bzero(buffer,sizeof(buffer));
		}

	    printf("[7] HTTPS Download Successfully...\n");
	    free(ssl);
	    ssl = NULL;
	    return 0;

	}
	close(fd);
	close(webfd);
	return -1;
}

6、添加安全认证模块

typedef struct{
	SSL * sslsocket;   //安全套接字
    SSL_CTX * sslctx;  //安全认证上下文
}ssl_t;
//安全认证过程  基于连接
ssl_t * spider_openssl_create(int);
#include<SPIDER.h>
ssl_t* spider_openssl_create(int webfd)
{
	ssl_t *ssl = NULL;

	if((ssl = (ssl_t*)malloc(sizeof(ssl_t)))== NULL) //申请空间
	{
		perror("openssl_create malloc ssl error");
		return NULL;
	}
	SSL_load_error_strings();
	SSL_library_init();
	OpenSSL_add_ssl_algorithms();

	ssl->sslctx = SSL_CTX_new(SSLv23_method());  //生成安全认证上下文

	ssl->sslsocket = SSL_new(ssl->sslctx);   //生成安全套接字

	SSL_set_fd(ssl->sslsocket,webfd); //与连接好的webfd进行关联

	SSL_connect(ssl->sslsocket);  //安全认证
    printf("------openssl connect succefffully!------\n");

	return ssl;
}

其余模块没有发生改动,不再赘述。

7、主函数

#include<SPIDER.h>

int main()
{
	const char *turl ="https://seopic.699pic.com/photo/40202/3604.jpg_wh1200.jpg";           
    url_t node;
    char req_head[4096]; 
    ssl_t* ssl = NULL;
	strcpy(node.alpha_url,turl);

	int webfd = spider_net_init();

	spider_analytical_url(&node);

	spider_connect_webserver(webfd,&node);
 
    spider_create_request_head(req_head,&node);
        
    if(node.http_type)
        ssl = spider_openssl_create(webfd);

    spider_response_download(webfd , req_head, &node,ssl);
	
	return 0;
}

注:编译时切记链入库,否则会提醒缺少库,或者不识别函数。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值