这里使用了两个接口来反查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 getDomains(String ip){
		Set set = new HashSet();
		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*
  • 1.(.*)?";  //匹配到目标行 while((line = reader.readLine()) != null){ if(line.matches(reg)){ inputStream.close(); reader.close(); connection.disconnect(); return line.replaceFirst("\\s*
    • 1.", "");  //返回包含目标的字符串 } } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return ""; } /**  * 正则匹配出需要的一个个域名  * @param data 包含所有结果的字符串  *   * @return 目标域名的List集合  * */ private Set getDomainByChinaz(String data){ String reg = "target=_blank>(.*?)
    • ";  //准确匹配出查到的域名 Pattern pattern = Pattern.compile(reg); Matcher matcher = pattern.matcher(data); Set set = new HashSet(); 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 = "共有  (\\d*)? 个域名解析到该IP"; String domainReg = "\\s*\\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\">(.*)?"); 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 set = new HashSet();
		set = searchDomain.getDomains("162.211.183.152");

		Iterator 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)