HttpClient使用第一弹,多线程+IP代理扫描未注册域名
2015-11-08 21:29
1351 查看
一、简介
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 (GA) (2015-09-11)
二、准备工作
通过搜索我们得到查询域名是否注册的万网官方API接口http://panda.www.net.cn/cgi-bin/check.cgi?area_domain=。通过测试,我们得到返回xml值
返回 XML 结果说明:
returncode=200 表示接口返回成功
key=***.com表示当前check的域名
original=210 : Domain name is available 表示域名可以注册
original=211"" : Domain name is not available 表示域名已经注册
original=212 : Domain name is invalid 表示域名参数传输错误
三、编写代码
首先我们要从本地读取拼音并组装成需要的域名(也可以用英文字母组合,这个可以自行发挥,这里使用两拼拼音进行组合)
经过组合我们得到大约15万个域名,单个线程就显得效率略微低下,如果是同一个ip发送大量请求到万网……几分钟就把你ip禁封了,所以迫不得已要使用代理IP进行访问。
在上面这个类中还用到了我写的一个HttpUtils工具类,其实这个工具类很简单,这里只用到了里面的两个方法。
接着我们开启多个线程进行访问
最后我们编写一个测试方法
ok,到此大功告成。
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 (GA) (2015-09-11)
二、准备工作
通过搜索我们得到查询域名是否注册的万网官方API接口http://panda.www.net.cn/cgi-bin/check.cgi?area_domain=。通过测试,我们得到返回xml值
<?xml version="1.0" encoding="gb2312"?> <property> <returncode>200</returncode> <key>baidu.com</key> <original>211 : Domain exists</original> </property>
返回 XML 结果说明:
returncode=200 表示接口返回成功
key=***.com表示当前check的域名
original=210 : Domain name is available 表示域名可以注册
original=211"" : Domain name is not available 表示域名已经注册
original=212 : Domain name is invalid 表示域名参数传输错误
三、编写代码
首先我们要从本地读取拼音并组装成需要的域名(也可以用英文字母组合,这个可以自行发挥,这里使用两拼拼音进行组合)
1 //存放从文件中读取到的原始字符 2 ArrayList<String> pinyin = new ArrayList<String>(); //这里用队列来存放组合好的域名 ArrayBlockingQueue<String> taskQueue = new ArrayBlockingQueue<String>(163620); //读取硬盘上的文件 BufferedReader reader = new BufferedReader(new FileReader("E:\\拼音.txt")); String str; while(( str=reader.readLine() )!= null){ pinyin.add(str); } reader.close(); //组合域名 for(String pinyin1 : pinyin){ for(String pinyin2 : pinyin){ taskQueue.add(pinyin1+pinyin2+domainNameSuffix);//domainNameSuffix是指域名后缀 } }
经过组合我们得到大约15万个域名,单个线程就显得效率略微低下,如果是同一个ip发送大量请求到万网……几分钟就把你ip禁封了,所以迫不得已要使用代理IP进行访问。
package cn.dsx.ali; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.concurrent.ArrayBlockingQueue; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import cn.dsx.utils.HttpUtils; public class DomainRunner implements Runnable { private CloseableHttpClient httpClient; //模拟客户端 private CloseableHttpResponse response; //返回 private String domain,uri="http://panda.www.net.cn/cgi-bin/check.cgi?area_domain="; private ArrayBlockingQueue<String> taskQueue; //存储测试的域名 private String ip[]; //存放IP的数组 private int size; //IP的个数 private int index; //要使用的IP下标 /** * 初始化 * @param taskQueue 域名队列 * @param ip */ public DomainRunner(ArrayBlockingQueue<String> taskQueue, String[] ip){ httpClient = HttpClients.createDefault(); this.taskQueue = taskQueue; index = size = ip.length; this.ip = ip; } @Override public void run() { while(( domain=taskQueue.poll() ) != null){ HttpGet get = null; try { get = new HttpGet(uri+domain); HttpClientContext context = HttpClientContext.create(); get.setHeader("Connection", "close"); //循环取得IP index--; if(index<=0){ index = size; } //分割出IP和端口 String []str = ip[index].split(":"); HttpHost proxy = new HttpHost(str[0], Integer.parseInt(str[1])); //设置请求延迟和代理IP RequestConfig config = RequestConfig.custom() .setProxy(proxy) .setSocketTimeout(3000) .setConnectTimeout(3000) .build(); get.setConfig(config); //发送请求 response = httpClient.execute(get,context); int status = response.getStatusLine().getStatusCode(); if (status >= 200 && status < 300) { String resultXml = EntityUtils.toString(response.getEntity(),"gb2312"); if(resultXml.contains("<original>210")){ //以追加的形式写入 BufferedWriter writer = new BufferedWriter(new FileWriter("E:\\domain.txt",true)); resultXml = HttpUtils.myRegex("<key>.*?</key>", resultXml).get(0); resultXml = HttpUtils.mid(resultXml, "<key>", "</key>"); System.err.println(Thread.currentThread().getName()+"未注册"+resultXml); writer.write(resultXml); writer.newLine(); writer.flush(); writer.close(); } else if(resultXml.contains("<original>211") || resultXml.contains("<original>212") || resultXml.contains("<original>214")){ System.out.println(Thread.currentThread().getName()+"已注册"+domain); } else { System.out.println(Thread.currentThread().getName()+"恭喜你中奖了,"+str[0]+"被封"); } } else { System.out.println(domain + "验证错误"); } } catch (Exception e) { System.err.println(Thread.currentThread().getName()+"异常"); //如果产生异常则代表没有成功发送请求,而domain已经出栈,所以要重新压栈。 taskQueue.add(domain); } finally{ //必须释放掉资源,不然Booming~ try { get.releaseConnection(); if (response != null) { response.close(); } } catch (IOException e) { e.printStackTrace(); } } } } }
在上面这个类中还用到了我写的一个HttpUtils工具类,其实这个工具类很简单,这里只用到了里面的两个方法。
package cn.dsx.utils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.HttpEntity; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.message.BasicNameValuePair; /** * Http相关处理的类 */ public class HttpUtils { /** * map转换成entity * @param map 待处理的 * @return 处理后的数据 */ public static HttpEntity mapToEntity(HashMap<String,String> map) throws Exception{ BasicNameValuePair pair = null; List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>(); for(Map.Entry<String, String> m : map.entrySet()){ pair = new BasicNameValuePair(m.getKey(),m.getValue()); params.add(pair); } HttpEntity entity = new UrlEncodedFormEntity(params,"UTF-8"); return entity; } /** * 取文本之间的字符串 * @param string 源字符串 * @param start 开始字符串 * @param end 结束字符串 * @return 成功返回中间子串,失败返回null */ public static String mid(String string, String start, String end) { int s = string.indexOf(start) + start.length(); int e = string.indexOf(end, s); if (s > 0 && e > s) return string.substring(s, e); return null; } /** * * @param regex 正则表达式 * @param input 待匹配的字符串 * @return 返回的是匹配的list集合(可能由于正则表达式的不同有多条记录) */ public static ArrayList<String> myRegex(String regex, String input) { ArrayList<String> list = new ArrayList<String>(); Pattern p = Pattern.compile(regex); Matcher m = p.matcher(input); while (m.find()) { list.add(m.group()); } return list; } }
接着我们开启多个线程进行访问
//开启线程 DomainRunner runner = new DomainRunner(taskQueue,ip); ExecutorService threadPool = Executors.newFixedThreadPool(threadNum); for(int i=1; i<=threadNum; i++){ System.err.println("线程"+i+"开启。"); threadPool.execute(runner); } threadPool.shutdownNow();
最后我们编写一个测试方法
public static void main(String args[]){ String ip[] = { "58.214.5.229:80","58.220.2.132:80", "58.220.2.133:80","58.220.2.134:80", "58.220.2.135:80","58.220.2.136:80", "58.220.2.137:80","58.220.2.138:80", "58.220.2.139:80","58.220.2.140:80", "58.220.2.141:80","58.220.2.142:80", "58.220.2.145:80","58.220.2.147:80", "58.220.2.148:80","58.220.2.153:80" }; //3个参数分别是域名后缀,线程数,IP数组 Ali ali = new Ali(".cn",4,ip); ali.domainGenerator(); }
ok,到此大功告成。
相关文章推荐
- Android 如何根据网络地址获取网络图片方法
- Winfrom 基于TCP的Socket 编程
- java网络编程学习笔记(一)
- http method&header+php+取证分析
- Android开发获取网络图片时提示java.net.unknownhosteception
- 一封来自网络的情书
- Python通用网络爬虫脚本
- 简易TCP
- HttpClient3.0入门1
- linux网络配置
- GET http://test01.com/jquery-1.9.1.min.js [HTTP/1.1 404 Not Found 3ms]
- java网络编程(三):一个类似QQ的聊天程序
- 容量测试之tcpcopy引流模式
- TCP打洞技术
- Protocol Informatics【基于网络轨迹的协议逆向工程文献学习】
- We7<001>--We7 CMS之报错: HTTP 错误 404.0 - Not Found 您要找的资源已被删除、已更名或暂时不可用。
- Linux(Centos6.5)下安装svn服务器,并通过http访问
- 建立网络连接的基本步骤及NSJSONSerialization(苹果自带)——JSON解析
- Unix c 网络编程 UDP
- Unix c 网络编程 TCP