爬虫实现:根据IP地址反查域名
域名解析与ip地址
域名解析是把域名指向网站空间ip,让人们通过注册的域名可以方便地访问到网站的一种服务;ip地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替ip地址标识站点地址。域名解析就是域名到ip地址的转换过程,该过程由dns服务器完成(来自百度百科)
先来了解两个知识点
1、一个域名同一时刻只能对应一个ip地址
2、一个ip地址可以解析绑定多个域名,没有限制
基于以上知识点,假如我们已知一个ip地址,我们怎么才能获取解析到该ip地址的所有域名信息呢?一种方式是国家工信部能开放查询接口以供查询(不知道会不会开放?);另外一种方式就是接下来我要分享的——爬虫实现:根据ip地址反查域名。
实现原理
实现原理其实很简单,现在已有网站提供了根据ip地址查询域名的功能,但是需要人为登录网站输入ip地址查询,我想要实现程序自动化查询,所以就想到了爬虫的方式,简单来说,就是模拟人的查询行为,将查询结果解析成我想要的域名列表。
以site.ip138.com
为例,打开f12
,输入一个ip查询,观察控制台请求,看到下图中信息
请求地址为:http://site.ip138.com/119.75.217.109/
请求方式为:get
然后,分析response,可以看到,在页面上看到的绑定域名信息就是下图红框中的内容,所以只要能将response的内容解析出来,获取到的内容就可以得到想要的域名列表。
上述response是html页面,使用jsoup
来解析html简直完美。
jsoup是什么?
jsoup 是一款java 的html解析器,可直接解析某个url地址、html文本内容。它提供了一套非常省力的api,可通过dom,css以及类似于jquery的操作方法来取出和操作数据。
//解析成document对象 document document = jsoup.parse(result); if (document == null) { logger.error("jsoup parse get document null!"); } //根据id属性“list”获取元素element对象(有没有感觉很像jquery?) element listele = document.getelementbyid("list"); //根据class属性和属性值筛选元素element集合,并通过eachtext()遍历元素内容 return listele.getelementsbyattributevalue("target", "_blank").eachtext();
result的内容通过httpclient模拟http请求
httpget httpget = new httpget(url); httpget.setheader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); httpget.setheader("accept-encoding", "gzip, deflate"); httpget.setheader("accept-language", "zh-cn,zh;q=0.9"); httpget.setheader("cache-control", "max-age=0"); httpget.setheader("connection", "keep-alive"); httpget.setheader("cookie", "hm_lvt_d39191a0b09bb1eb023933edaa468cd5=1553090128; baidu_ssp_lcr=https://www.baidu.com/link?url=fs0ccst469d77dpdxpcgyjhf7ostltyk6vcmehxt_9_&wd=&eqid=fa0e26f70002e7dd000000065c924649; pgv_pvi=6200530944; pgv_si=s4712839168; hm_lpvt_d39191a0b09bb1eb023933edaa468cd5=1553093270"); httpget.setheader("dnt", "1"); httpget.setheader("host", host); httpget.setheader("upgrade-insecure-requests", "1"); httpget.setheader("user-agent", "mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/63.0.3239.132 safari/537.36"); string result = httputils.doget(httpget);
http请求工具类
public class httputils { private static logger logger = loggerfactory.getlogger(httputils.class); public static string doget(httpget httpget) { closeablehttpclient httpclient = null; try { httpclient = httpclients.createdefault(); requestconfig requestconfig = requestconfig.custom() .setconnecttimeout(5000).setconnectionrequesttimeout(10000) .setsockettimeout(5000).build(); httpget.setconfig(requestconfig); httpresponse httpresponse = httpclient.execute(httpget); if (httpresponse.getstatusline().getstatuscode() == 200 || httpresponse.getstatusline().getstatuscode() == 302) { httpentity entity = httpresponse.getentity(); return entityutils.tostring(entity, "utf-8"); } else { logger.error("request statuscode={}", httpresponse.getstatusline().getstatuscode()); } } catch (exception e) { logger.error("request exception={}:", e); } finally { if (httpclient != null) { try { httpclient.close(); } catch (ioexception e) { logger.error("关闭httpclient失败", e); } } } return null; } }
新增controller
@restcontroller public class domainspidercontroller { private static logger logger = loggerfactory.getlogger(domainspidercontroller.class); @autowired private domainspiderservice domainspiderservice; /** * @param ip 119.75.217.109 * @return */ @requestmapping("/spider/{ip}") @responsebody public list<string> domainspider(@pathvariable("ip") string ip) { long starttime = system.currenttimemillis(); list<string> domains = domainspiderservice.domainspiderofip138(ip); if(domains == null || domains.size() == 0) { domains = domainspiderservice.domainspiderofaizan(ip); } long endtime = system.currenttimemillis(); logger.info("完成爬虫任务总耗时:{}s", (endtime - starttime) / 1000); return domains; } }
启动spring boot应用,访问浏览器:http://localhost:8080/spider/119.75.217.109
获得返回结果如下:
怎么样?是不是很简单?
优化改进:有时候仅仅通过一个网站查询的域名数据可能不太准确,甚至查询不到数据,我们也没法判断谁才是正确的,所以,可以通过爬取多个网站的结果结合起来使用,例如:dns.aizhan.com
提出疑问:这些提供根据ip反查域名的网站,是怎么实现的呢?我咨询过其他人,他们的回答是这些网站收集了很多ip和域名的对应关系,真实情况是这样的吗?
示例源码
- domain-spider
代码已上传至码云
和github
上,欢迎下载学习
上一篇: 趁毛巾没注意还能多擦几遍
下一篇: 几个有用的php字符串过滤,转换函数代码