爬虫的DNS缓存
来源:互联网 发布:vivo手机怎么改mac地址 编辑:程序博客网 时间:2024/06/05 04:37
爬虫中的DNS缓存的实现
一、实验背景
在实现爬虫的过程中,需要对域名进行DNS解析,要向DNS服务器发起请求。当爬虫的量达到十万、千万级别时,这一部分的耗时就非常可观了,同时也给服务器增大了复旦。因此需要对其进行优化,使其能实现DNS缓存,不必发起太多请求。
二、实现方法
首先想到的就是修改hosts文件,这样能直接省下向DNS发起请求的时间。但是缺点是无法实时更新,如果域名和IP发生了变化则需要手动更改。若未及时更新,甚至可能导致爬虫没有结果。
于是我们想到的方法就是每次查询之前查询请求的域名是否存在于缓存中,查阅资料后可以得出代码:
import socket
_dnscache = {}#dns缓存list,用来记录域名和对应的IP
def _setDNSCache():
def igetaddrinfo(*args,**kwargs):
if args in _dnscache: #查询请求的域名是否在DNS缓存中
return_dnscache[args]
else:
_dnscache[args] = socket.igetaddrinfo(*args,**kwargs)
#调用igetaddrinfo将DNS加入缓存
return _dnscache[args]
if not hasattr(socket, 'igetaddrinfo'):
#将socket类的getddrinfo打一个patch,向已知DNS的方向解析
socket.igetaddrinfo =socket.getaddrinfo
socket.getaddrinfo = igetaddrinfo
将上述保存为dnscache.py
在要用到DNS缓存的时候,只需要import dnscache,然后_setDNSCache()即可
三、实现实例
实验环境:WIN10+python3.6+requests 2.8.1
在实验开始之前,需要将windows的DNS缓存功能关闭,否则会影响到后续的实现以及时间对比。在命令提示符(管理员)中输入net stop dnscache,重启即可。
以爬取bilibili视频网站的视频标题为例。
因为实现的是静态页面的爬取,观察网页源代码可以发现视频标题是被<h1>标签所闭合。由此利用requests库可得到爬虫的代码。
# coding: utf-8
if __name__ =="__main__":
import dns_cache
#dns_cache._setDNSCache() #如果需要的话
import time
import requests
i=0
f=open("ans_dns.txt",'w')
number=int(input("How many do youwant to know from no.1?"))
start1 = time.clock()
while i<number:
tem=str(i)
i=i+1
url="http://www.bilibili.com/video/av"+tem
req = requests.post(url).text
h1_start=req.find('<h1')
h1_end=req.find('</h1>')
req=req[h1_start:h1_end]
start=req.find('title=')+7
end=req.find('">')-1
req=req[start:end]
if (h1_start>0):
if.write(req+'\n')
end1 = time.clock()
#print(end1-start1)
times=round(end1-start1,2)
f.write("This program costs"+str(times)+" seconds")
f.close()
爬虫中并未使用正则表达式,利用requests库所发送的请求是基于urllib3的。爬取过程中发现bilibili视频网站的网页是经过gzip加压的,但是好在requests库中已经将其在.text中解压整合在了一起。如果使用urllib库来打开url,则需要经过以下代码解压:
from gzip importGzipFile
from StringIOimport StringIO
def gzip(data):
buf =StringIO(data)
f =gzip.GzipFile(fileobj=buf)
return f.read()
爬取10000条
无DNS缓存:
有DNS缓存:
上述两条都与DNS请求所需要的时间吻合的很好,过程中使用wireshark抓包也能看到明显的对比。
无DNS缓存机制的抓包:
有DNS缓存机制的抓包:
四、实验结论
本次的爬虫DNS缓存的实现思路是请求一个域名时如果本地没有缓存,则调用socket.igetaddrinfo去请求解析;如果有缓存则直接使用缓存中的内容。而实现了DNS缓存的爬虫总体上是要快于普通爬虫的,同时也能降低服务器的负担
五、反思
在实验的过程中,有DNS缓存的爬虫所用的时间超出无DNS缓存的爬虫的程度并不总是与估计值吻合的很好,猜测原因可能是实程中爬虫所能用到的带宽由于其他程序的波动导致也一直在波动从而使得DNS请求的时间并不稳定。
此外,本次只爬取了bilibili视频站下的一部分标题,并没有考察爬取不同域的爬虫所受到的影响,应该在不同域上的爬虫有DNS缓存也能加快速度。- 爬虫的DNS缓存
- Python爬虫——DNS解析缓存
- 缓存的DNS服务器
- 浏览器的DNS缓存
- 浏览器的DNS缓存
- ColdFusion 的DNS缓存问题
- 邪恶的浏览器DNS缓存
- 邪恶的浏览器DNS缓存
- 清除DNS缓存的方法
- 刷新电脑的DNS缓存
- 查看浏览器的DNS缓存
- 清除Ubuntu的DNS缓存
- dns缓存
- DNS缓存
- DNS 缓存
- DNS缓存
- DNS缓存
- DNS 缓存
- 获取当前手机的IMEI串号
- 超级账本-面向企业的分布式账本
- c++ primer 13.13练习(构造,拷贝,析构函数何时发生详解)
- 如何实现反向代理?与正向代理的区别以及Nginx 反向代理优势
- 【Linux基础之简单的日志切割】nginx日志切割及清理
- 爬虫的DNS缓存
- 自学小记_5(网络通信-差错控制技术)
- SILICON LABS收购领先RTOS厂商ucos
- 本机WEB服务器搭建
- sql 列按照字符分割转行
- 随机UUID的生成
- java并发编程实战(二)
- mysql--14000常用函数
- cocos2d-x开发环境搭建