从网站中“扒”新闻

元旦放假三天,天气很冷没有打算出去玩,就在家里琢磨着弄一下扒网站新闻,主要是同寝室的一个同事在弄,所以想学点东西,自己也动手写了一个,思路很简单,下面就描述一下是怎么实现的吧!

 

首先进入主页网站中,然后选择自己想“扒”的信息模块,例如是新闻、经济、娱乐等等或者其他什么的,这样就能找到自己需要信息,然后把这个模块的url链接地址给读取出来,然后遍历读取到的URL地址,读取信息的内容。

 

现在的网站一般都是动态生成的,也就是说新闻信息页面有自己的模板,那么所有的信息肯定是在某个DIV或者是容器中,只要找到这个控件的ID就能够得到里面的数据,然后把里面的数据找出来。

 

下面的代码是我测试了某网站的信息,已经读取到了信息列表,先弄上去供大家参考,为了防止某些人恶意攻击,因此我删除了具体的链接地址

 

package hb.downweb;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
 * 从网上扒新闻信息
 */
public class Main {

	//显示新闻列表的地址
	private static final String http_url = "显示信息列表的URL地址";
	//找到需要扒的信息模块的ID
	private static final String summaryBlock = "id=\"blist\"";
	//显示的信息以什么HTML标签结束
	private static final String endSummaryBlock = "</table>";
	//存储网页中的链接标签
	public static List<String> list = new LinkedList<String>();

	public static void main(String[] args) {
		//想要抓取信息的页面
		StringBuffer stringBuffer = new StringBuffer();
		try {
			//通过字符串得到URL对象
			URL url = new URL(http_url);
			//远程连接,得到URLConnection对象(它代表应用程序和 URL 之间的通信链接)
			URLConnection conn = url.openConnection();
			int find_flag = 0;		//表示没有找到需要的内容
			//从连接中读取数据流,
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while((line = reader.readLine()) != null){
				//找到了需要下载链接模块
				if(line.indexOf(summaryBlock)!= -1){
					find_flag = 1;//表示找到了需要的内容
				}
				//需要新闻模块的结束标记
				if(line.indexOf(endSummaryBlock) != -1){
					find_flag = 2;//表示需要找的内容结束了
				}
				//将找到的信息放入stringBuffer中
				if(1 == find_flag){
					stringBuffer.append(line);
				}
				//需要找的信息已经结束
				if(2 == find_flag){
					System.out.println("over");
					find_flag = 0;
				}
			}
			
			System.out.println(stringBuffer);
			//使用正则表达式获取想要的字符串
			Pattern pattern = Pattern.compile("[0-9]{5}\\.htm");
			Matcher matcher = pattern.matcher(stringBuffer);
			System.out.println(matcher.find());
			while(matcher.find()) {
				//将连接的地址存储到list容器中
				list.add("显示具体信息地址目录" + matcher.group());
				//下面显示匹配的内容
//				System.out.println(matcher.group());
			}
			//读取具体链接信息内容
			readNews(list);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}

	/*
	 * 读显示新闻的网页
	 */
	public static void readNews(List<String> list){
		String flagName = "news";
		for(int i = 0; i < list.size(); i++){
			//得到的是每篇文章的链接地址
			String temp = list.get(i);
			String filename = "";
			filename = flagName + i+".txt";
			//将下载的网页信息保存到文件中
			getNewsContent(temp,filename);
		}
	}
	
	/*
	 * 将显示新闻的网页的内容存放在本地文件中
	 */
	public static void getNewsContent(String httpLink,String fileName){
		try {
			System.out.println("getNewsContent : " + httpLink);
			//通过URL产生链接到具体的网页,然后读取数据
			URL url = new URL(httpLink);
			URLConnection conn = url.openConnection();
			//这里读取的网页内容一定要注意后面的编码,跟网页的报纸一致,否则在后面存储在文件中的也为乱码
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String tempStr;
			//根据显示具体网页个格式,找到对应的模块,然后读取出来存储在文件中
			File file = new File(fileName);
			FileOutputStream fos = new FileOutputStream(file);
			String class_name = "class=\"content2";
			String end_content = "</div>";
			int readContentFlag = 0;
			StringBuffer strbuf = new StringBuffer();
			while((tempStr = reader.readLine()) != null){
				if(tempStr.indexOf(class_name)!= -1){
					readContentFlag = 1;
				}
				if(tempStr.indexOf(end_content)!= -1){
					readContentFlag = 2;
				}
				if(1 == readContentFlag){
					strbuf.append(tempStr);
//					System.out.println(line);
				}
				if(2 == readContentFlag){
					System.out.println("over");
					readContentFlag = 0;
				}
				
				System.out.println("tempStr.indexOf(class_name)2: "+tempStr.indexOf(class_name));
				fos.write(tempStr.getBytes("utf-8"));
			}
			//一定不要忘记了关闭数据流,否则出现异常情况
			fos.close();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

 

 

备注:上面运行是同步的,为了提高用户体验,可以把上面的方式改为“线程”处理,这样体验会好很多,为了让读者更容易明白,这里就不再赘述了。

posted @ 2012-01-02 18:12  胖鹅  阅读(266)  评论(0编辑  收藏  举报