网络请求相关抓取效率优化和抓取窍门
针对大规模抓取:
1、优化抓取时间,在一些环节里面节省几十毫秒。
2、发现一些
面试题:当用户在浏览器输入URL并回车时,到浏览器现实网页数据,这个详细的过程。
发起http请求,域名(https://www.yuanrenxue.com---->转换成ip)
答案:客户端发起请求---》DNS解析---》CDN分发---》负载均衡---》WEB服务器。
DNS解析
本地解析/dns服务器
把域名解析为IP,解析好事在10-100毫秒不等。
爬虫方面dns优化:requests.get(url='https://www.xxxxxxx.com')
直接请求IP,绕过DNS域名解析环节
搜索引擎爬虫会维护dns池
定向爬虫不用维护dns池,使用IP直接访问。
抓国外网站的时候。
CDN分发:
正常请求:客户端请求——》服务器
CDN分发:客户端请求----》选择物理位置最近的CDN(CDN上缓存了服务器上的网页数据)----》服务器
如何确定对方使用CDN:
方法1:用两个省份的IP去ping域名
方法2:观察域名或response的header
CDN注意事项:CDN一般针对图片和视频,也有部分网站全站使用CDN
爬虫方面的CDN优化:
CDN特点:每个CDN节点的IP不同,一个请求IP在这个节点被频率限制了,在其他CDN节点还能用。
结合DNS解析直接请求IP的办法,如果网站有10个CDN节点,一个IP可以比以前多请求10倍才报废。
发现网站域名对应的IP工具:https://www.17ce.com/
网站知识相关抓取优化
1、一个网站可能有PC、移动网站、APP三套网站,三个域名。
PC:www.XXX.com
移动:m.XXX.com
APP:app.XXXX.com
极限利用IP,让每一个IP的抓取最大化利用。每一套网站后面可能是一套独立的IP效率控制系统。
当在PC端IP被限制了,在m端/app端可能还没被限制。如此,同一个IP访问三个终端,一个IP可以比以前多利用2次才报废。
2、关注SEO的网站,网站会有sitemap
尤其是新闻类,漫画类,小说类网站。
抓sitemap的好处:可以提供大量的种子URL,甚至全站的URL都有;方便抓取网站新增URL
3、网站可能有测试、临时站
因为是测试用,测试站/临时站的IP限制或者反爬会很弱。
测试站/临时站,一般是建立在子域名下面。
二级域名扫描:子域名扫描工具:
https://xiaix.me/zi-yu-ming-fa-xian-gong-ju/
http://tools.bugscaner.com/subdomain/
4、网站借口扫描,发现未对外提供的api。(数据返回可能更全,反爬更弱)
5、URL规律抓取
降低抓取次数和难度。容易抓取新增。
URL里的id号自增:https://www.bilibili.com/video/av69365368
URL有关联关系:https://www.qimai.cn/app/rank/appid/797346491/country/cn
URL能遍历完:http://www.dianping.com/shop/23093707
6、分析网站结构关系
(1)对比各种端的数据完整性
1.1 用户评论数据
pc端需要登陆查看更多,app端不需要登录可以看全部,而用户页面有该用户的所有评论,无需登录,点评小程序的评论数据也不需要登陆。
1.2 商标数据
商标页上的URL点进去可以查看该公司的所有商标数据,无需登录。官方信息页面查看商标需要登陆。
7、抓需要登陆的数据
(1)实打实的登陆抓取
解决自动注册账号,自动登录等工作比较繁琐,可能有难度较大的验证码
(2)手动注册账号,手动登陆
抓包拿到账号cookie,维护一系列账号cookie,cookie会过期,定期更新。
向上反馈,发动公司群众,帮忙登陆。
购买账号
PS:账号要养
(3)研究抓取对象终端数据差异/研究抓取对象页面结构组成关系
降低抓取次数,降低被频率控制的概率(即降低抓取数据难度)
8、出现验证码
降低爬虫难度,爬虫尽可能不要触发验证码,少去对抗对方的反爬系统/风控系统,尽可能模拟正常访问行为
容易有验证码的几种情况:
header(头)信息始终不变;
账号异地登陆(IP的地区控制不住);
脏IP(ipip);
抓取对方的搜索接口。
解决方法:
对抗破解:图片上的数字;点击图片里的目标;图片补缺口;滑条拖动。
研究图像识别/借助三方工具(各大公司提供的开放平台API);尝试便利对方图片验证,人工标记所有图片特征(对动态生成的图片无效);自动化测试工具自动拖拽(selenium,puppetteer)
打码平台:http://yundama.com/ http://www.fateadm.com
IP切换:ads拨号 代理IP
寻找绕过方法
抓取性能提升
性能优化:
性能优化体现在大规模抓取,小规模抓取体现不出来
单线程抓取100万次:每次抓取耗时300毫秒,30万秒,3.47天;每次抓取耗时600毫秒,60万秒,6.94天。
网络性能:
单次网络请求耗时:由dns查询(域名解析为IP);tcp连接(跟服务器IP建立连接);http请求相应(发送http请求与响应)。受网络性能与对方服务器响应性能影响。
反爬比爬虫难,反爬没有KPI、没绩效、没动力。
增加爬虫技术难度和成本,但阻止不了爬去。
后端发爬伤害性能;前端反爬,伤害搜索引擎。
低版本浏览器,高级JS特性,CSS特性浏览器不支持。
脏IP越来越对,被屏蔽,黑名单越多,常遇到登陆。
换IP不要再一个望断。
大规模IP获取与使用
爬虫现状:IP抓取频率控制严格,单IP抓取几乎不可行。
https://www.cnblogs.com/panxuejun/p/10293149.html
IP的几种方式:ppoe家庭带宽,IPv6,中国只有ipv4,lp3亿多。
多IP获取:高匿名代理IP、家庭带宽、电话卡、网站/APP内嵌
多IP-数量的定义:
1、高匿名代理IP:
http://h.zhimaruanjian.com/getapi/
特点:一次能提取数十/百个IP
优势:使用最方便,调用商家API借口,即可提取代理IP使用
劣势:质量最不好,扫描IP/鱼目混珠,海量抓取时成本高。
费用:20/s换一次IP,4320IP/天,0.04元/ip,172元/天,5000元/月
使用方法:
proxy_q = Queue.Queue()
def get_proxy():
if proxy_q.empty():
res = requests.get("http://XXXXXX.com").text
res_data = json.loads(res)
for i in res_data['proxy']:
proxy_q.put(i)
else:
return proxy_q.get()
def crawl():
proxy = get_proxy()
r = requests.get(url="", proxies=proxy, verify=False, headers=header)
2、借助VPS主机进行ads拨号huanIP
特点:使用adsl拨号一次,就切换一次ip
优势:成本低,质量比高匿好,也可配制成代理IP
劣势:使用配置相对麻烦,性能收到VPS主机影响较多(短时间高频拨号会失败,vps主机长时间运行无响应,拨号等待时间长等。)
费用:固定费用80-150元/月/台 IP无限制切换
配置:http://www.sunnet365.com/ http://www.5jwl.com/pppoevps/
购买vps主机,vps主机上可以使用ads拨号
ads拨号方法:(每个商家的拨号方法不一致,现在商家网站上问询商家)
linux上一般的设置方法:通过pppoe-setup命令配置配置ads账号密码;使用pppoe-start拨号切换IP;使用pppoe-stop关闭拨号。
使用方法:
方法一:把抓取程序放在vps主机上运行
需要在vps主机上配置你的爬虫环境
特点:vps主机的配置差,不稳定,抓取程序和数据可能会丢失;适合非超长时间运行的爬虫;总抓取量应在千万级以内。
适合范围:适合在vps主机上运行爬虫程序;适合单台vps主机
class Crawler:
def __init__(self):
self._vrawl_count = 0
def _do_request(self, url):
try:
r = requests.get("", headers=header)
return r.status_code, r.text
except Exception as e:
return 0, ''
def _readsl(self):
# windows
os.popen('rasdial 网络名称 /disconnect')
time.sleep(6)
os.popen('rasdial 网络名称 adsl账号名 adsl密码')
# linux
code = os.system('ifdown 网络连接名称')
time.sleep(6)
code = os.system('ifup 网络连接名称')
def start(self):
while True:
status, text = self._do_request(url)
self._crawl_count += 1
if self._crawl_count > 100:
self._readsl()
self._crawl_count = 0
方法二:把vps主机配制成http代理服务器(一些商家不再支持自建http代理)
自建http代理方法:在vps主机上安装tinyproxy或squid软件作为http代理服务。vps主机的linux一般是centos
安装python3:
yum install gcc make -y
yum install zlib-devel -y
wget http://python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz
tar xf Python-3.6.1.tar.xz
cd Python-3.6.1
./configure --prefix=/usr/local/python3
make
make install
ln -s /usr/local/python3.6/bin/python3.6/usr/bin/python3
安装tinyproxy:
centos系统使用yum命令安装软件
1.安装wget:yum install wget -y
2.把安装源换成阿里云的安装源(可跳过)
备份:cp /etc/yum/repos.d/CentOS-Base.repo /etc/yum/repos.d/CentOS-Base.repo.backup
下载阿里云安装源:wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
清空yum缓存:yum clean all
3.安装epel-release(前置包)
yum install epel-release -y
4.安装tinyproxy
yum install tinyproxy
5.安装openssl(支持https)
yum -y install openssl
6.测试
service tinyproxy start(出现Redirecting to /bin/systemctl start tinyproxy.service则为成功)
配置tinyproxy:
1.安装vim:yum install vim -y
2.用vim打开配置文件:vim /etc/tinyproxy/tinyproxy.conf
可修改端口:Port xxxx
运行指定IP访问代理:Allow xxx.xxx.xxx.xxx
3.重启tinyproxy:service tinyproxy restart(查看运行状态systemctl status tinyproxy)
4.测试代理:curl -x ip:port www.baidu.com
5.若代理不可用:关闭防火墙(systemctl stop firewalld systemctl disable firewalld);询问上架是否支持在服务器上建立http代理
PS:要让tinyproxy每天稳定运行,每天都重启1-2次比较好。
管理VPS(代理IP)主机群
方法一:单独配置一台IP管理服务器(各服务器间通过socket来通信)
adsl重新拨号,IP改变后,增设一台IP管理服务器。
IP管理服务器的配置:购买云服务器最低配版本(几十-上百/月)服务器质量要好(阿里云,ucloud,腾讯云)等。
socket网络编程:服务端绑定指定IP和端口,listen监听IP和端口,接收请求后与客户端数据交互。爬虫程序向IP管理服务器请求可用的代理IP,代理拨号服务器运行客户端向IP服务器发送拨号后的IP。
方法二:利用dns解析
利用dns解析远离,给每个代理IP都绑定一个域名,爬虫程序只需要解析域名就知道代理IP服务器的IP是多少。
代理服务器每次拨号后向dns服务器上报自己的IP;爬虫程序做dns解析,获取代理服务器的IP;使用代理IP抓数据。
DNS服务使用第三方服务:阿里云、dnspod(腾讯)等。使用付费的dns解析功能,ttl延迟才足够低。
操作:
1、爬虫程序获取域名对应的IP:
import socket
addr = socket.gethostbyname('p1.xxxxxxx.com')
2、每次拨号后,向dns服务器更新ip
调用dns服务商提供的api
步骤:在阿里云注册账号,并实名认证(https://www.aliyun.com);向阿里云申请api AccessKey(https://usercenter.console.aliyun.com);下载阿里云python sdk并安装(yum install python3-pip -y pip3 install aliyun-python-sdk-core pip3 install aliyun-python-sdk-slidns 阿里云的github:https://github.com/aliyun/aliyun-openapi-python-sdk/blob/master/README_zh.md);每次拨号后,向阿里云dns提交拨号后的IP
3、域名:在万网购买,需要实名认证(https://wanwang.aliyun.com/)
proxy_q = queue.Queue()
def get_proxy():
if proxy_q.empty():
proxy_q.put(socket.gethostbyname('p1.xxxxx.com'))
proxy_q.put(socket.gethostbyname('p2.xxxxx.com'))
proxy_q.put(socket.gethostbyname('p3.xxxxx.com'))
proxy_q.put(socket.gethostbyname('p4.xxxxx.com'))
proxy_q.put(socket.gethostbyname('p5.xxxxx.com'))
else:
return proxy_q.get()
def crawl():
proxy = get_proxy()
r = requests.get(url='', proxies=proxy, verify=False, headers=header)
screen远程会话管理(让远程执行的程序,在远程连接推出时,执行的程序不退出)
vps主机安装screen:yum install screen -y
云主机安装:apt-get install screen
使用方法:
新建:screen -S give a name
关闭(程序不退出):ctrl a + d
连接screen
screen -ls 查看要链接screen的id号
screen -r screen id