爬虫、代理和Nginx

进群,一起学习后端技术

一、爬虫和Http代理起因寻找代理测试代理使用代理持续不断供应代理服务化进一步整合二、怎么用Nginx搭建正向代理

一、爬虫和Http代理

起因

做过爬虫的人应该都知道,抓的网站和数据多了,如果爬虫抓取速度过快,免不了触发网站的防爬机制,几乎用的同一招就是封IP。解决方案有2个:

同一IP,放慢速度(爬取速度慢)

使用代理IP访问(推荐)

第一种方案牺牲的就是时间和速度,来换取数据,但是一般情况下我们的时间是很宝贵的,理想情况下是用最短的时间获取最多的数据。所以第二种方案是推荐的,那么从哪里能找到这么多代理IP呢?

寻找代理

程序猿不懂的时候就去寻找嘛,google、度娘,输入关键字:免费代理IP,前几页几乎都是提供代理IP的网站,一一打开后观察发现,几乎都是一个列表页,展示少则几十、多至几百个IP。

但是仔细观察你就会发现,每个网站提供的免费IP是有限的,拿来用几个就会发现,有的也已经失效了。当然,他们更倾向于你购买人家的代理,人家就靠这个赚钱嘛。

身为狡猾的程序猿,当然不能因为这点困难就跪了,仔细想一下,既然搜索引擎能搜到这么多提供代理的网站,每个网站提供几十或几百个,假如有10家网站,那加在一起也有几百到几千个IP。

那么好了,你要做的事情就是,把这些网站记录下来,用程序把IP抓过来就好了,想想是不是很简单?

测试代理

通过刚才的方式,应该可以获得几百或上千的代理IP了。

等等,这么多IP,难道别人真的就免费送给你了么?当然不是,前面也提到过,这些代理中,有很大一部分已经是失效的了。那么怎么办?如何知道哪些代理是有效,哪些是不可用的呢?

很简单,挂上这些代理,访问某一个稳定的网站,然后看是否能正常访问,可以正常访问的就是可用的,不能访问的不就是无效的嘛。

最快速的,用curl命令就可以测试某个代理是否可用:

#使用代理 48.139.133.93:3128 访问 网易首页curl -x "48.139.133.93:3128" ""

当然,这种方式只是为了演示方便,实际最好的方式是:用多线程方式,使用代理去访问某个网站,然后输出可用的代理。这样做能最快速的找出可用代理。

使用代理

现在已经可以通过上面的方式,找出可用的代理了,如果应用到程序中,应该不用我多说,大部分都应该会用了。例如,刚才把可用的代理输入到某个文件中,每一行是一个代理,那么就可以这样使用:

读取代理文件

随机选择代理IP,发起HTTP请求

这样,如果代理有几百个,基本上可以保持一段时间抓取某个网站的数据了,抓个几千几万条数据不成问题。

但是,如果我想持续不断的从某个网站获取数据,或者是抓取上百万甚至上亿的网页数据,那这样肯定是不行的。

持续不断供应代理

刚才的方式是,一次性抓取某几个代理网站,然后通过程序测试每个代理是否可用,得到可用的代理列表。但是这只是一次性的,而且代理量往往很少,在持续抓取中肯定无法满足需要。那么怎么能持续不断的找到可用代理呢?

找到更多的代理网站(数据基础)

定时监控这些代理网站,获取代理

拿到代理IP后,程序自动检测,输出可用代理(文件或数据库)

程序加载文件或数据库,随机选取代理IP发起HTTP请求

按照上面的方式,可以写出一个自动采集代理的程序,然后爬虫端就可以定时去文件/数据库中获取然后使用就可以了。但是有一个小问题,怎样知道每个代理的质量如何?也就是说,代理的速度怎么样?

在检测代理时,记录请求响应时间

响应时间从短到长,加权重值,响应短的使用率高一些

限制某段时间内最大使用次数

前面几点只是基础,这3点可以进一步优化你的代理程序,输出有优先级的代理列表,爬虫端根据权重和最大使用次数使用代理。这样做的好处:保证使用高质量代理,同时防止某一代理频繁使用防止被封。

服务化

上面经过一系列的完善和优化,已经搭建好了一个可用的代理服务,只不过是基于文件系统或数据库的。

爬虫端要想使用这些代理,只能是读取文件或读取数据库,然后根据某种规则选择代理使用,这样做比较繁琐,能不能让爬虫端使用代理变得简单一些?那么就需要把代理访问做成服务化。

有个大名鼎鼎的服务器软件squid,利用它的cache_peer邻居代理机制,就可以帮这个事情做的很完美。

把代理列表的代理,按照squid的cache_peer机制按照一定格式,写在配置文件中即可。

squid是个代理服务器软件,一般情况下是这样使用的,假如爬虫在机器A,squid安装在机器B,需要爬取的网站服务器是机器C,代理IP是机器D/E/F…

不使用代理:爬虫机器A请求 —> 网站机器C

使用代理:爬虫机器A —> 代理IP机器D/E/F/… —> 网站机器C

使用squid:爬虫机器A—>squid(机器B,cache_peer机制管理调度代理D/E/F) —> 网站机器C

这样做的好处就是:爬虫端不用考虑如何加载和选择可用代理,给出一个代理列表给squid,按照配置文件的规则,它就可以帮你管理和调度选择代理。最重要的是,爬虫端使用代理只需访问squid的服务端口就可以了!

进一步整合

现在服务化也搭建完成了,唯一差得一步就是整合:

定时监控代理源网站(30分/1小时都可),解析出所有代理IP,入数据库

从数据库中取出所有代理,访问某个固定的网站,找出访问成功的代理,更新数据库可用标记和响应时间

从数据库中加载所有可用代理,通过某种算法,根据响应时间计算使用权重和最大使用次数

按照squid的cache_peer格式,写入配置文件

重新加载squid配置文件,刷新squid下的代理列表

爬虫指定squid的服务IP和端口,进行纯粹的爬取操作

一个完整的代理服务通过这样的方法就可以搭建完成,定时输出高质量代理。爬虫端不用关心代理的采集和测试,只管使用squid的统一服务入口爬取数据即可。

二、怎么用Nginx搭建正向代理

上面介绍了爬虫通过使用代理来应对爬取对象的反爬策略,那么它所使用的代理怎么使用nginx来搭建呢?

在官网下载最新稳定版本的 nginx源码默认配置编译安装 ( 需要先安装nginx所需的依赖库 )

依赖库安装

rpm -qa | grep zlib //查看是否安装了zlib,其他类推.sudo yum install openssl-devel  //安装opensslsudo yum install pcre-devel  //安装pcresudo yum install zlib-devel  //安装zlib

nginx编译

--prefix= 指向安装目录。--sbin-path= 指定执行程序文件存放位置。--modules-path= 指定第三方模块的存放路径。--conf-path= 指定配置文件存放位置。--error-log-path= 指定错误日志存放位置。--pid-path= 指定pid文件存放位置。--lock-path= 指定lock文件存放位置。--user= 指定程序运行时的非特权用户。--group= 指定程序运行时的非特权用户组。--builddir= 指向编译目录。--with-rtsig_module 启用rtsig模块支持。--with-select_module 启用select模块支持,一种轮询处理方式,不推荐在高并发环境中使用,禁用:--without-select_module。--with-poll_module 启用poll模块支持,功能与select相同,不推荐在高并发环境中使用。--with-threads启用thread pool支持。--with-file-aio 启用file aio支持。--with-http_ssl_module 启用https支持。--with-http_v2_module 启用ngx_http_v2_module支持。--with-ipv6 启用ipv6支持。--with-http_realip_module 允许从请求报文头中更改客户端的ip地址,默认为关。--with-http_addition_module 启用ngix_http_additon_mdoule支持(作为一个输出过滤器,分部分响应请求)。--with -http_xslt_module 启用ngx_http_xslt_module支持,过滤转换XML请求 。--with-http_image_filter_mdoule 启用ngx_http_image_filter_module支持,传输JPEG\GIF\PNG图片的一个过滤器,默认不启用,需要安装gd库。--with-http_geoip_module 启用ngx_http_geoip_module支持,用于创建基于MaxMind GeoIP二进制文件相配的客户端IP地址的ngx_http_geoip_module变量。--with-http_sub_module 启用ngx_http_sub_module支持,允许用一些其他文本替换nginx响应中的一些文本。--with-http_dav_module 启用ngx_http_dav_module支持,增加PUT、DELETE、MKCOL创建集合,COPY和MOVE方法,默认为关闭,需要编译开启。--with-http_flv_module 启用ngx_http_flv_module支持,提供寻求内存使用基于时间的偏移量文件。--with-http_mp4_module 启用ngx_http_mp4_module支持,启用对mp4类视频文件的支持。--with-http_gzip_static_module 启用ngx_http_gzip_static_module支持,支持在线实时压缩输出数据流。--with-http_random_index_module 启用ngx_http_random_index_module支持,从目录中随机挑选一个目录索引。--with-http_secure_link_module 启用ngx_http_secure_link_module支持,计算和检查要求所需的安全链接网址。--with-http_degradation_module 启用ngx_http_degradation_module 支持允许在内存不足的情况下返回204或444代码。--with-http_stub_status_module 启用ngx_http_stub_status_module 支持查看nginx的状态页。--without-http_charset_module 禁用ngx_http_charset_module这一模块,可以进行字符集间的转换,从其它字符转换成UTF-8或者从UTF8转换成其它字符。它只能从服务器到客户端方向,只有一个字节的字符可以转换。--without-http_gzip_module 禁用ngx_http_gzip_module支持,同--with-http_gzip_static_module功能一样。--without-http_ssi_module 禁用ngx_http_ssi_module支持,提供了一个在输入端处理服务器包含文件(SSI)的过滤器。--without-http_userid_module 禁用ngx_http_userid_module支持,该模块用来确定客户端后续请求的cookies。--without-http_access_module 禁用ngx_http_access_module支持,提供了基于主机ip地址的访问控制功能。--without-http_auth_basic_module 禁用ngx_http_auth_basic_module支持,可以使用用户名和密码认证的方式来对站点或部分内容进行认证。--without-http_autoindex_module 禁用ngx_http_authindex_module,该模块用于在ngx_http_index_module模块没有找到索引文件时发出请求,用于自动生成目录列表。--without-http_geo_module 禁用ngx_http_geo_module支持,这个模块用于创建依赖于客户端ip的变量。--without-http_map_module 禁用ngx_http_map_module支持,使用任意的键、值 对设置配置变量。--without-http_split_clients_module 禁用ngx_http_split_clients_module支持,该模块用于基于用户ip地址、报头、cookies划分用户。--without-http_referer_module 禁用ngx_http_referer_modlue支持,该模块用来过滤请求,报头中Referer值不正确的请求。--without-http_rewrite_module 禁用ngx_http_rewrite_module支持。该模块允许使用正则表达式改变URI,并且根据变量来转向以及选择配置。如果在server级别设置该选项,那么将在location之前生效,但如果location中还有更进一步的重写规则,location部分的规则依然会被执行。如果这个URI重写是因为location部分的规则造成的,那么location部分会再次被执行作为新的URI,这个循环会被执行10次,最后返回一个500错误。--without-http_proxy_module 禁用ngx_http_proxy_module支持,http代理功能。--without-http_fastcgi_module 禁用ngx_http_fastcgi_module支持,该模块允许nginx与fastcgi进程交互,并通过传递参数来控制fastcgi进程工作。--without-http_uwsgi_module 禁用ngx_http_uwsgi_module支持,该模块用来使用uwsgi协议,uwsgi服务器相关。--without-http_scgi_module 禁用ngx_http_scgi_module支持,类似于fastcgi,也是应用程序与http服务的接口标准。--without-http_memcached_module 禁用ngx_http_memcached支持,用来提供简单的缓存,提高系统效率。--without-http_limit_conn_module 禁用ngx_http_limit_conn_module支持,该模块可以根据条件进行会话的并发连接数进行限制。--without-http_limit_req_module 禁用ngx_limit_req_module支持,该模块可以实现对于一个地址进行请求数量的限制。--without-http_empty_gif_module 禁用ngx_http_empty_gif_module支持,该模块在内存中常驻了一个1*1的透明gif图像,可以被非常快速的调用。--without-http_browser_module 禁用ngx_http_browser_mdoule支持,创建依赖于请求报头的值 。如果浏览器为modern,则$modern_browser等于modern_browser_value的值;如果浏览器为old,则$ancient_browser等于$ancient_browser_value指令分配的值;如果浏览器为MSIE,则$msie等于1。--without-http_upstream_ip_hash_module 禁用ngx_http_upstream_ip_hash_module支持,该模块用于简单的负载均衡。--with-http_perl_module 启用ngx_http_perl_module支持,它使nginx可以直接使用perl或通过ssi调用perl。--with-perl_modules_path= 设定perl模块路径--with-perl= 设定perl库文件路径--http-log-path= 设定access log路径--http-client-body-temp-path= 设定http客户端请求临时文件路径--http-proxy-temp-path= 设定http代理临时文件路径--http-fastcgi-temp-path= 设定http fastcgi临时文件路径--http-uwsgi-temp-path= 设定http scgi临时文件路径--http-scgi-temp-path= 设定http scgi临时文件路径--without-http 禁用http server功能--without-http-cache 禁用http cache功能--with-mail 启用POP3、IMAP4、SMTP代理模块--with-mail_ssl_module 启用ngx_mail_ssl_module支持--without-mail_pop3_module 禁用pop3协议。--without-mail_iamp_module 禁用iamp协议。--without-mail_smtp_module 禁用smtp协议。--with-google_perftools_module 启用ngx_google_perftools_mdoule支持,调试用,可以用来分析程序性能瓶颈。--with-cpp_test_module 启用ngx_cpp_test_module支持。--add-module= 指定外部模块路径,启用对外部模块的支持。--with-cc= 指向C编译器路径。--with-cpp= 指向C预处理路径。--with-cc-opt= 设置C编译器参数,指定--with-cc-opt="-I /usr/lcal/include",如果使用select()函数,还需要同时指定文件描述符数量--with-cc-opt="-D FD_SETSIZE=2048"。 (PCRE库)--with-ld-opt= 设置连接文件参数,需要指定--with-ld-opt="-L /usr/local/lib"。(PCRE库)--with-cpu-opt= 指定编译的CPU类型,如pentium,pentiumpro,...amd64,ppc64...--without-pcre 禁用pcre库。--with-pcre 启用pcre库。--with-pcre= 指向pcre库文件目录。--with-pcre-opt= 在编译时为pcre库设置附加参数 。--with-md5= 指向md5库文件目录。--with-md5-opt= 编译时为md5库设置附加参数。--with-md5-asm 使用md5汇编源。--with-sha1= 指向sha1库文件目录。--with-sha1-opt= 编译时为sha1库设置附加参数。--with-sha1-asm 使用sha1汇编源。--with-zlib= 指向zlib库文件目录。--with-zlib-opt= 在编译时为zlib设置附加参数。--with-zlib-asm= 为指定的CPU使用汇编源进行优化。--with-libatomic 为原子内存的更新操作的实现提供一个架构。--with-libatomic= 指向libatomic_ops的安装目录。--with-openssl= 指向openssl安装目录。--with-openssl-opt= 在编译时为openssl设置附加参数。--with-debug 启用debug日志。

nginx安装

tar zxvf nginx-1.10.3.tar.gz cd nginx-1.10.3 ./configure make make install修改nginx运行配置文件

[ nginx 默认安装在/usr/local/nginx/下 ]vim /usr/local/nginx/conf/nginx.conf

    include       mime.types;    default_type  application/octet-stream;    #log_format  main  $remote_addr - $remote_user [$time_local] "$request"     #                  $status $body_bytes_sent "$http_referer"     #                  "$http_user_agent" "$http_x_forwarded_for";    #access_log  logs/access.log  main;    sendfile        on;    #tcp_nopush     on;    keepalive_timeout  65;    #gzip  on;    #代理服务设置    server {        resolver 192.168.99.100;  #可用的DNS        listen 81;   #监听的端口        location / {             proxy_pass http://$http_host$request_uri;        }       }} 

文章推荐

1

深入 Nginx:我们是如何为性能和规模做设计的

2

几道面试题

3

nginx实现图片防盗链-技术精短文