首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

应用线程池ThreadPoolExecutor 抓取论坛帖子列表

2012-11-05 
使用线程池ThreadPoolExecutor 抓取论坛帖子列表早前经常在网站上面下载动画和日剧,后来BT没有了~ 就只能

使用线程池ThreadPoolExecutor 抓取论坛帖子列表
早前经常在网站上面下载动画和日剧,后来BT没有了~ 就只能逛论坛了!
现在的论坛大家也都了解~ 广告铺天盖地,打开个页面有时候能跳出来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年前的,可以是2010for(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 {//单独运行抓取方法,线程池请运行 BbsThreadpublic static void main(String[] args) {int[] fids = {66,200,168,306};int lastyear = 2010; //不能是2010年前的,可以是2010for(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="([^<>]*forum\\.php\\?mod=viewthread&[amp;]*tid=[\\d]+)[^<>]+ class="xst"[\\s]?>([^<]+)</a>"); // [color=red]正则部分替换测试时间2012-06-19可用[/color]Matcher timemc = regex(txt, "<em>([0-9|-]+)</em>"); // timeSystem.out.print(i++ + "");if (titlemc.find()) {String title = titlemc.group(2).replaceAll("'", "''").replaceAll("【", "[").replaceAll("】", "]");System.out.print(title + ""); // titleString 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;}}


1 楼 happysoul 2012-06-19   论坛帖子链接换成了全路径
正则已经修改
<a href="([^<>]*forum\\.php\\?mod=viewthread&[amp;]*tid=[\\d]+)[^<>]+ class="xst"[\\s]?>([^<]+)</a>
通过[^<>]*来匹配 http://http://www.subpig.net/ 部分
附件没有修改
测试时间 2012-06-19

热点排行