浏览 2205 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-07-06
现在的论坛大家也都了解~ 广告铺天盖地,打开个页面有时候能跳出来3-4个广告 对我来说常去的也就是猪猪字幕,不过那些垃圾广告实在没有办法,再就是垃圾服务器访问速度巨慢无比,点个下一页不知道要等N久~~ 所以想到了 我每次只需要帖子列表 具体想看哪个再打开页面去下载种子(其实再做一个访问帖子链接 下载种子的方法也不难,感觉还是需要看到截图和宣传画才能决定是否下载就没有继续做) 回到技术方面,普通的多线程很难对线程数量进行控制,只要运行,所有队列里面的都会运行,受制约于带宽问题,很多页面本来是可以打开的,因为网络没有读到数据,于是想到了线程池,也就是保证池中每次只有几个线程在运行,早前发现的方法都是用 ThreadGroup 和 WatchThread方法解决这个问题,开发和维护起来就稍显的复杂了。除非是你的线程间要传递数据,否则并行的线程完全够用了 //线程、最大池、存活时间、存活时间单位、队列 ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 20, 1, TimeUnit.HOURS, new LinkedBlockingQueue()); 循环 executor.execute(new XxxThread(xxx,xxx)); 将线程加入池中 我也没有太细致的阅读到这部分的源码,所以就算是抛砖引玉的把方法抛出来供大家使用和研究了。 保存数据库之类的方法我都删除了,毕竟为了这东西没必要再去让运行的人都去装个Mysql之类的数据库 线程入口程序 import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class BbsThread implements Runnable { private int fid; private int lastyear; public int getFid() { return fid; } public void setFid(int fid) { this.fid = fid; } public int getLastyear() { return lastyear; } public void setLastyear(int lastyear) { this.lastyear = lastyear; } public BbsThread(){} public BbsThread(int fid,int lastyear){ this.fid = fid; this.lastyear = lastyear; } //run方法 public void run() { System.out.println("线程启动,开始抓取数据"); BBS.t(1,2,fid,lastyear); //每个线程只抓取1-2页 } @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { // BlockingQueue queue = new LinkedBlockingQueue(); //线程、最大池、存活时间、存活时间单位、队列 ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 20, 1, TimeUnit.HOURS, new LinkedBlockingQueue()); int[] fids = {66,200,168,306}; int lastyear = 2010; //不能是2010年前的,可以是2010 for(int i=0;i<fids.length;i++){ executor.execute(new BbsThread(fids[i],lastyear)); } executor.shutdown(); } } 后面的这个是抓取论坛数据的部分,也可以单独运行,不过那可就真是单线程的了 package com.test; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BBS { //单独运行抓取方法,线程池请运行 BbsThread public static void main(String[] args) { int[] fids = {66,200,168,306}; int lastyear = 2010; //不能是2010年前的,可以是2010 for(int i=0;i<fids.length;i++){ t(1,8,fids[i],lastyear); //抓取页数1-8页 } } public static void t(int from, int end, int fid, int lastyear) { String url = "http://www.subpig.net/forumdisplay.php?fid="+fid+"&page="; if (from > end) return; for (; from <= end; from++) { int i = 1; System.out.println(url+from); String htmltext = gethtml("gbk", url + from).replaceAll("\\t", ""); String regex = "<tbody id=\"[\\w]+_[\\d]+\"(.*?)</tbody>"; Matcher mc = regex(htmltext, regex); while (mc.find()) { String txt = mc.group(1); // 我不看棒子的东西,相关的都过滤 if (txt.indexOf("韩剧") != -1 || txt.indexOf("韩语") != -1 || txt.indexOf("韩国") != -1) continue; Matcher titlemc = regex(txt,"<a href=\"(viewthread\\.php\\?tid=[\\d]+)&extra=[^<>]+>([^<>]+)</a>"); // title Matcher timemc = regex(txt, "<em>([0-9|-]+)</em>"); // time System.out.print(i++ + " "); if (titlemc.find()) { String title = titlemc.group(2) .replaceAll("'", "''") .replaceAll("【", "[") .replaceAll("】", "]"); System.out.print(title + " "); // title String href = titlemc.group(1); String time = ""; if (timemc.find()){ time = timemc.group(1); Integer year = Integer.parseInt(time.substring(0,4)); if(year!=null&&year<lastyear)continue; System.out.print(time+" "); //日期 } System.out.println(reurl(url, href)); } } } } //URL链接拼接 public static String reurl(String url,String href){ String hrefurl = href; if(!href.toLowerCase().startsWith("http://")){ hrefurl = url.substring(0,url.lastIndexOf("/") + 1) + href; } return hrefurl; } //简化正则表达式的使用 public static Matcher regex(String htmltext, String regex) { Pattern spattern = null; Matcher smatcher = null; spattern = Pattern.compile(regex); smatcher = spattern.matcher(htmltext); return smatcher; } //抓取网页 public static String gethtml(String htmltype,String httpurl){ String str = ""; try{ URL urlx = new URL(httpurl); HttpURLConnection uc = (HttpURLConnection) urlx.openConnection(); uc.setDoInput(true); uc.setUseCaches(false); uc.setRequestMethod("GET"); uc.setInstanceFollowRedirects(true); uc.setConnectTimeout(30*1000); uc.setReadTimeout(60*1000); InputStream inputstream = uc.getInputStream(); BufferedReader bufferedreader = null; if(htmltype==null||htmltype.trim().equals(""))bufferedreader = new BufferedReader(new InputStreamReader(inputstream)); else bufferedreader = new BufferedReader(new InputStreamReader(inputstream,htmltype)); String s1; while ((s1 = bufferedreader.readLine()) != null) str = str + s1; }catch (Exception e) { e.printStackTrace(); } return str; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |