本文主要講的是如何突破IP限制進行網絡投票。
首先前期的準備工作,第一當然得先去獲取投票的請求接口以及傳參,包括請求頭等各種有關的請求信息;
第二就是準備IP代理,百度裏有很多免費的IP代理,但是其實能用的沒多少,建議還是購買IP代理,購買的IP代理有很多種解析IP的方式,比如網頁表格獲取解析,json解析等。本文采取的是網頁表格獲取解析IP。
所需jar包以及工程結構:
IpInfo類:(可根據具體的表格或者獲取ip方式調整實體類屬性)
public class IpInfo {
private String ipAddress;//ip
private int port;//端口
private String anonymousType;//匿名度
private String type;//類型
private String location;//位置
private String responseSpeed;//響應速度
private String confirmTime;//最後驗證時間
public IpInfo() {
super();
}
public IpInfo(String ipAddress, int port, String anonymousType, String type, String location, String responseSpeed,
String confirmTime) {
super();
this.ipAddress = ipAddress;
this.port = port;
this.anonymousType = anonymousType;
this.type = type;
this.location = location;
this.responseSpeed = responseSpeed;
this.confirmTime = confirmTime;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getAnonymousType() {
return anonymousType;
}
public void setAnonymousType(String anonymousType) {
this.anonymousType = anonymousType;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getResponseSpeed() {
return responseSpeed;
}
public void setResponseSpeed(String responseSpeed) {
this.responseSpeed = responseSpeed;
}
public String getConfirmTime() {
return confirmTime;
}
public void setConfirmTime(String confirmTime) {
this.confirmTime = confirmTime;
}
}
IpCollectTask類:(定時獲取ip地址)
public class IPCollectTask extends TimerTask{
private BlockingQueue<IpInfo> ipInfoQueue; // 連接生產者與消費者的阻塞隊列
private List<IpInfo> historyIpLists; // 記錄已經獲取的ip信息
public IPCollectTask(BlockingQueue<IpInfo> ipInfoQueue) {
this.ipInfoQueue = ipInfoQueue;
this.historyIpLists = new ArrayList<IpInfo>();
}
@Override
public void run() {
System.out.println("開始!!!!");
getKuaiDaiLiFreeIpLists();
}
/**
* 獲取IP代理地址
*/
private void getKuaiDaiLiFreeIpLists(){
try {
// 第一次訪問,需解析總共多少頁
String baseUrl = "http://www.xiongmaodaili.com/freeproxy";//ip地址的頁面
Document doc = getDocumentByUrl(baseUrl);//獲取網頁的對象
Element listNav = doc.getElementById("listnav");//獲取分頁的div
// 獲取listnav下的li列表
Elements liLists = listNav.children().get(0).children();
// 獲取含有多少頁的子元素
Element pageNumberEle = liLists.get(liLists.size() - 2);
// 解析有多少頁
int pageNumber = Integer.parseInt(pageNumberEle.text());
for (int index = 1; index <= pageNumber; index++) {//循環每一頁獲取ip
baseUrl = tempUrl + index;
doc = getDocumentByUrl(baseUrl);
parseKuaiDaiLiIpLists(doc);
Thread.sleep(10000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根據URL解析出dom對象
*/
private Document getDocumentByUrl(String url) {
Document doc = null;
try {
doc = Jsoup.connect(url)
.header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36")
.header("Host", "www.sgedu.gov.cn")
.timeout(5000)
.get();
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 解析IP代理的表格
* @param doc
*/
private void parseKuaiDaiLiIpLists(Document doc) {
Elements eleLists = doc.getElementsByTag("tbody");
Element tbody = eleLists.get(0);//獲取表格
Elements trLists = tbody.children();//獲取tr
for (Element tr : trLists) {//遍歷tr
Elements tdElements = tr.children();//獲取td
String ipAddress = tdElements.get(0).text();
int port = Integer.parseInt(tdElements.get(1).text());
String anonymousType = tdElements.get(2).text();
String type = tdElements.get(3).text();
String location = tdElements.get(4).text();
String responseSpeed = tdElements.get(5).text();
//String confirmTime = tdElements.get(6).text();
String confirmTime = "2018/6/25 0:34:05";
IpInfo ipInfo = new IpInfo
(ipAddress, port, anonymousType,type, location, responseSpeed,confirmTime);
putIpInfo(ipInfo);
}
}
/**
* 將已使用過的IP裝起來
* @param ipInfo
*/
private void putIpInfo(IpInfo ipInfo) {
if (!historyIpLists.contains(ipInfo)) { // 若歷史記錄中不包含ip信息,則加入隊列中
// 加入到阻塞隊列中,用作生產者
try {
ipInfoQueue.put(ipInfo);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 加入歷史記錄中
historyIpLists.add(ipInfo);
}
}
}
VoteThread類:(多線程發起http請求:(投票/刷票))
public class VoteThread extends Thread{
private BlockingQueue<IpInfo> ipInfoQueue;
public VoteThread() {
super();
}
public VoteThread(BlockingQueue<IpInfo> ipInfoQueue) {
this.ipInfoQueue = ipInfoQueue;
}
@Override
public void run(){
HttpClient client = new DefaultHttpClient();//創建httpclient對象
//設置請求超時時間
HttpParams params = client.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 15000);
HttpPost post = null;//post請求
HttpResponse response = null;//返回
HttpHost proxy = null;//ip代理
while(true){
try {
IpInfo ipInfo = ipInfoQueue.take();//取IP代理
System.out.println(ipInfo.getIpAddress());
proxy = new HttpHost(ipInfo.getIpAddress(), ipInfo.getPort());//設置ip地址和端口
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);//設置ip代理
post = new HttpPost("http://www.sgedu.gov.cn/Survey/SurveySave.aspx");//投票接口地址
//請求頭信息
post.addHeader("Host", "www.sgedu.gov.cn");
post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36");
//請求參數
List<NameValuePair>kvList = new ArrayList<>();
kvList.add(new BasicNameValuePair("Q1","2"));
kvList.add(new BasicNameValuePair("Q1Input",""));
kvList.add(new BasicNameValuePair("SurveyID","12"));
kvList.add(new BasicNameValuePair("Submit","提交問卷"));
StringEntity se = new UrlEncodedFormEntity(kvList,"utf-8");
post.setEntity(se);
response = client.execute(post);//發送請求
String string = EntityUtils.toString(response.getEntity());//返回信息
System.out.println(string);
System.out.println("-----------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Vote類:(程序入口)
public class Vote {
private BlockingQueue<IpInfo> ipInfoQueue;
private IPCollectTask ipCollectTask;
private VoteThread voteThread;
public Vote() {
ipInfoQueue = new LinkedBlockingQueue<>();
ipCollectTask = new IPCollectTask(ipInfoQueue);
voteThread = new VoteThread(ipInfoQueue);
}
public void vote() {
Timer timer = new Timer();
long delay = 0;
long period = 1000 * 60 * 60;
// 每一個小時採集一次ip
timer.scheduleAtFixedRate(ipCollectTask, delay, period);
// 開啓投票任務
voteThread.start();
}
public static void main(String[] args) {
Vote vote = new Vote();
vote.vote();
}
VoteStart類:(請求測試類,可以先單條測試通過再開啓刷票,代碼都差不多就不貼了,手動滑稽)
最後PS:此工程是我多年前寫的一個工程,可能會有些小問題,請多多見諒,感謝~