自己开博客也有将近一年时间了,在这一年中也写了20+博客了,但是经过这么长时间的积累,自己博客的浏览量还不到一万,于是想有什么办法可以快速增加浏览量的呢,刚好看到Java可以直接访问链接,于是就行动起来了,将近两个小时的编程和测试,终于写好了一个满意的程序了(顿时感觉编程还是很有意思的)。以下是程序源码,可能还有很多可以改进的地方,欢迎提出来,如果感觉好的话,点个赞便是最好的鼓励啦。
package sky_100;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Increase blog pageviews
*
* @author Benett (chenpeng)
* @version 1.0
* @date 2017年8月22日 下午10:59:21
*/
public class VisitBlog {
private static String blogName;// The Blog Name
private static String blogHome;// The address of Blog Home
private static String blogUrlPrefix;// Blog address prefix
private static int threadNum;// The number of initial threads
private static int visitNum;// Number of visits required
private static int maxSleepTime;// Maximum sleep time(ms)
private static long eachTaskCycle;// Each task cycle(mimutes)
private static String fileUrl;// Save the path to the file
// Each link corresponds to the total number of visits
private static Map<String, Integer> recordMap;
static {
blogName = "sky_100";// 注意:只需要把这里改成你自己的博客名就好了
StringBuilder sb = new StringBuilder();
blogHome = sb.append("http://blog.csdn.net/").append(blogName).toString();
blogUrlPrefix = sb.append("/article/details/").toString();
threadNum = 5;
visitNum = 1200;
maxSleepTime = 120000;
eachTaskCycle = 150;
fileUrl = new StringBuilder(new File("").getAbsolutePath()).append("/visitBlogRecord.txt").toString();
}
public static void main(String[] args) {
VisitBlog vb = new VisitBlog();
recordMap = new ConcurrentHashMap<String, Integer>();
recordMap = vb.loadMap(recordMap);
vb.shutDownHook();
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(vb.new TimedExecute(vb, recordMap), 0, eachTaskCycle, TimeUnit.MINUTES);
}
private Map<String, Integer> loadMap(Map<String, Integer> recordMap) {
Map<String, Integer> oldMap = convertFile2Map();
if (oldMap == null || oldMap.isEmpty())
return recordMap;
else
return oldMap;
}
class TimedExecute implements Runnable {
VisitBlog vb = null;
Map<String, Integer> recordMap;
public TimedExecute(VisitBlog vb, Map<String, Integer> recordMap) {
super();
this.vb = vb;
this.recordMap = recordMap;
}
@Override
public void run() {
String content = vb.getHtmlContent();
List<String> blogUrls = vb.getBlogUrls(content);
threadNum = blogUrls.size();
vb.visitBlog(blogUrls, recordMap);
}
}
private void visitBlog(List<String> list, Map<String, Integer> recordMap) {
ExecutorService pool = Executors.newFixedThreadPool(threadNum);
for (int i = 0; i < visitNum; i++) {
pool.execute(new VisitMyBlog(blogUrlPrefix + list.get(i % threadNum), recordMap));
}
pool.shutdown();
}
private String getHtmlContent() {
StringBuffer sb = null;
try {
URL url = new URL(blogHome);
URLConnection urlcon = url.openConnection();
int i = urlcon.getContentLength();
sb = new StringBuffer();
if (i > 0) {
InputStream is = urlcon.getInputStream();
int a;
while ((a = is.read()) != -1) {
sb.append((char) a);
}
is.close();
} else {
System.out.println("the response content is null...");
}
} catch (Exception e) {
}
return sb.toString();
}
private List<String> getBlogUrls(String content) {
List<String> list = new ArrayList<String>();
String flag = new StringBuilder(blogName).append("/article/details/").toString();
int i = 0;
while (content.indexOf(flag) != -1) {
int length = content.indexOf(flag) + flag.length();
list.add(content.substring(length, length + 8));
content = content.replaceAll(flag + list.get(i), " ");
i++;
}
return list;
}
class VisitMyBlog implements Runnable {
String url = "";
Map<String, Integer> recordMap;
public VisitMyBlog(String url, Map<String, Integer> recordMap) {
super();
this.url = url;
this.recordMap = recordMap;
}
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(maxSleepTime));
URLConnection oc = new URL(url).openConnection();
InputStream is = oc.getInputStream();
int a;
while ((a = is.read()) != -1) {
System.out.print((char) a);
}
is.close();
addRecord2Map(url, recordMap);
System.out.println(url + "has been visited---");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class PersistenceVisitHistory extends Thread {
@Override
public void run() {
convertMap2File(recordMap);
System.out.println("i am shutdown");
}
}
private void convertMap2File(Map<String, Integer> recordMap) {
ObjectOutputStream objOP = null;
try {
objOP = new ObjectOutputStream(new FileOutputStream(new File(fileUrl)));
objOP.writeObject(recordMap);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (objOP != null)
objOP.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
private Map<String, Integer> convertFile2Map() {
ObjectInputStream objIP = null;
Map<String, Integer> oldRecordMap = null;
try {
File file = new File(fileUrl);
if (file.exists()) {
FileInputStream fis = new FileInputStream(file);
objIP = new ObjectInputStream(fis);
oldRecordMap = (ConcurrentHashMap<String, Integer>) objIP.readObject();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (objIP != null)
objIP.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return oldRecordMap;
}
private void shutDownHook() {
Runtime.getRuntime().addShutdownHook(new PersistenceVisitHistory());
}
private void addRecord2Map(String url, Map<String, Integer> recordMap) {
int num = 1;
if (recordMap.containsKey(url)) {
// Thread safe here, because the ConcurrentHashMap is used
recordMap.put(url, recordMap.get(url) + 1);
} else {
recordMap.put(url, num);
}
}
}
程序后话,因为希望这个程序一直运行,所以就把这个程序放在我云服务器上,怎奈何我买的是1块钱的云服务器,很渣,所以用了线程池来提高访问效率。又想到一直频繁访问自己的博客万一被检查出来了就不好了,于是加了个定时器,每150分钟一次任务,每个任务总访问量为1000,访问一个一篇博客后,再休息2分钟内后继续访问。想到该记录一下自己的博客每篇被程序访问了多少次(方便以后看真实访问的数量,哈哈),于是就想到用map将数据存储起来,因为是多线程,考虑到线程安全,就用了ConcurrentHashMap解决线程安全和效率问题,又想到map是存在缓存里的,万一我一按Ctrl+c,里面的数据不就没了吗,于是就在虚拟机退出的时候注册了关闭钩子,退出时将map中的数据持久化,再次启动时重新加载里面的数据就好了。