元旦放假三天,天气很冷没有打算出去玩,就在家里琢磨着弄一下扒网站新闻,主要是同寝室的一个同事在弄,所以想学点东西,自己也动手写了一个,思路很简单,下面就描述一下是怎么实现的吧!
?
首先进入主页网站中,然后选择自己想“扒”的信息模块,例如是新闻、经济、娱乐等等或者其他什么的,这样就能找到自己需要信息,然后把这个模块的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(); } } }
?
?
备注:上面运行是同步的,为了提高用户体验,可以把上面的方式改为“线程”处理,这样体验会好很多,为了让读者更容易明白,这里就不再赘述了。
?
我这种方法不是通用的,但是可以作为参考,希望大家多提意见!