这里使用了两个接口来反查IP,分别是“站长工具”和“爱站”的接口,两者各有千秋,结合起来查询就较为准确了。
注:我目前只写了个初始版本,还不太完善,但是可以基本使用了,代码中关键地方有注释,所以我就不多解释了
算法核心:
package NmapTest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SearchDomainByIP { /** * IP反查(旁站查询),综合两个接口的结果 * @param ip 待查IP * * @return 返回结果集 * */ public Set<String> getDomains(String ip){ Set<String> set = new HashSet<String>(); set = getDomainByChinaz(searchDomainByChinaz(ip)); //chinaz接口 try { String[] domainByAiZhan = searchDomainByAiZhan(ip, 1, false).split(" "); //aizhan接口 for(String s : domainByAiZhan){ if(!s.equals("")) set.add(s); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return set; } /** * 使用站长工具的接口,IP反查域名 * @param ip 待查IP * * @return 返回包含结果的字符串 * */ private String searchDomainByChinaz(String ip){ try { URL url = new URL("http://s.tool.chinaz.com/same"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); String str = "s=" + ip; //POST参数 OutputStream outputStream = connection.getOutputStream(); outputStream.write(str.getBytes("UTF-8")); outputStream.flush(); //开始请求 outputStream.close(); //返回数据包 if(connection.getResponseCode() == 200){ InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; String reg = "\\s*<ul><li><span>1.</span>(.*)?"; //匹配到目标行 while((line = reader.readLine()) != null){ if(line.matches(reg)){ inputStream.close(); reader.close(); connection.disconnect(); return line.replaceFirst("\\s*<ul><li><span>1.</span>", ""); //返回包含目标的字符串 } } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return ""; } /** * 正则匹配出需要的一个个域名 * @param data 包含所有结果的字符串 * * @return 目标域名的List集合 * */ private Set<String> getDomainByChinaz(String data){ String reg = "target=_blank>(.*?)</a></li>"; //准确匹配出查到的域名 Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(data); Set<String> set = new HashSet<String>(); while(matcher.find()){ set.add(matcher.group(1)); } return set; } /** * 使用爱站网的接口,IP反查域名 * @param ip 待查IP * @param currentPage 当前页 * @param checkNum 判断域名总数是否已获取 * * @return 返回包含结果的字符串 * @throws IOException * */ private String searchDomainByAiZhan(String ip,int currentPage,boolean checkNum) throws IOException{ URL url = new URL("http://dns.aizhan.com/" + ip + "/" + currentPage +"/"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(10000); //毫秒 connection.setReadTimeout(10000); InputStream inputStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; String numReg = "共有 <font color=\"#FF0000\" id=\"yhide\">(\\d*)?</font> 个域名解析到该IP"; String domainReg = "\\s*<td class=\"dns-links\">\\s*"; //匹配到目标行的上一行 int domainNumber = 0; //查到的域名总数 String domainNames = ""; //查到的所有域名的字符串集 boolean point = false; //从false置为true时,表示已经找到目标行的上一行了,下一次循环即可取出目标行 Pattern pattern = Pattern.compile(numReg); Matcher matcher = null; while((line = reader.readLine()) != null){ //查域名总数 if(!checkNum){ matcher = pattern.matcher(line); if(matcher.find()){ domainNumber = Integer.valueOf(matcher.group(1)); checkNum = true; } } //查域名 if(point){ pattern = Pattern.compile("target=\"_blank\">(.*)?</a>"); matcher = pattern.matcher(line); if(matcher.find()){ // System.out.println(matcher.group(1)); domainNames = domainNames + matcher.group(1) + " "; point = false; } } else if(line.matches(domainReg)){ point = true; } } inputStream.close(); reader.close(); connection.disconnect(); //如果当前页下一页还有内容,则进行递归调用查询 if(domainNumber > (20 * currentPage)){ try { Thread.sleep(1000); //线程休息1秒钟 } catch (InterruptedException e) { e.printStackTrace(); } return domainNames + searchDomainByAiZhan(ip,currentPage+1,true); } else{ return domainNames; } } }
调用测试:
package NmapTest; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class Domains { /** * @param args */ public static void main(String[] args) { SearchDomainByIP searchDomain = new SearchDomainByIP(); Set<String> set = new HashSet<String>(); set = searchDomain.getDomains("162.211.183.152"); Iterator<String> iterator = set.iterator(); System.out.println("一共查到 " + set.size() + "个旁站"); while(iterator.hasNext()){ System.out.println(iterator.next()); } } }
输出:
一共查到 55个旁站
www.anhao.ga
www.3ga.cc
www.xiaotwl.cn
wapfeih.com
www.52zyw.net
lgdyw.pw
xxin888.com
www.hksf-expres.com
www.zbhz.top
yk666.cn
www.mfdhw.cn
danshenwl.com
qq67.cn
gjdc.cc
www.5x2y0.com
www.wz288.com
wapzx.org
85pj.cn
www.txbk.cc
yajie520.com
www.wuyunzhu.top
huanyan520.com
lequk.com
www.ddcd.net
ail.so
3pojie.com
www.hacksg.com
www.yin361.cn
www.wapfeih.com
xg-sfkd.com.cn
www.xuexi47.cn
www.huaxia47.com
wz288.com
www.sucaiziyuan.com
wapsog.com
qm6.cc
www.58dh.cn
hacksg.com
zhuilixiang.com
www.xhhzyw.com
www.360360.pw
www.495o.com
surfs.cn
shineky.cn
www.danshenwl.com
52daizi.com
www.hei-tan.com
xg-sfg.cn
www.qqjudian.com
sucaiziyuan.com
moran.cc
lghk.pw
www.huanyan520.com
hongbao.qq.com.mooyu.pub
lexunc.com
PS:通过IP反查域名本身就没有确定的算法,因此有误差再所难免。这也是我使用两个不同接口来查询的意义所在,可以互相弥补,使结果更加精确
(PS:打个广告,更多原创文章,尽在我的个人博客网站:http://www.zifangsky.cn)