热门IT资讯网

java之爬虫

发表于:2024-11-25 作者:热门IT资讯网编辑
编辑最后更新 2024年11月25日,近期研究爬虫爬取网站链接:1.需要获取所有超链接2.排除已爬取的链接,去重3.爬虫的广度和深度方向研究(ps:目前没有研究彻底)以下是实现代码:import java.io.BufferedReade

近期研究爬虫爬取网站链接:
1.需要获取所有超链接
2.排除已爬取的链接,去重
3.爬虫的广度和深度方向研究(ps:目前没有研究彻底)
以下是实现代码:

import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.swing.plaf.synth.SynthSpinnerUI;public class study {    private static List waitforUrl=new ArrayList<>();//存储抓取出来的url,等待爬    private static Set goforUrl=new HashSet<>();//存储爬过的url    private static Map allUrldepth=new HashMap<>();//对所有url进行爬去深度判断    private static int Maxdepth=2;    public static void main(String[] args) {        String urlstr="............";        study.gourl(urlstr, 1);    }    public static void gourl(String urlstr,int depath) {        if(!(goforUrl.contains(urlstr)||depath>Maxdepth)) {            goforUrl.add(urlstr);            try {                URL url=new URL(urlstr);                URLConnection urlConn=url.openConnection();//建立url链接                InputStream is=urlConn.getInputStream();//通过链接获取页面内容,为字节流                InputStreamReader isr=new InputStreamReader(is,"utf-8");//将字节流转化为字符流                BufferedReader br=new BufferedReader(isr);//读取字节流                StringBuffer sb=new StringBuffer();//实例化StringBuffer用来存储读取数据                String line=null;                while((line=br.readLine())!=null) {                    sb.append(line);                    //System.out.println(line);                    Pattern p = Pattern.compile("");                    Matcher m=p.matcher(line);                    while(m.find()) {                        String href=m.group();                        href=href.substring(href.indexOf("href="));                        if(href.charAt(5)=='\"'||href.charAt(5)=='\''){                            href=href.substring(6);                          }else{                            href=href.substring(5);                          }                        try {                        href=href.substring(0,href.indexOf("\""));                        }catch(Exception e) {                            href=href.substring(0,href.indexOf("\'"));                        }                        waitforUrl.add(href);                        allUrldepth.put(href, depath+1);                    }                }                is.close();//关闭输出流                isr.close();//关闭字节流读取                br.close();                System.out.println(urlstr);                System.out.println("链接总数:"+waitforUrl.size()+",已爬去链接数:"+goforUrl.size());            }catch(Exception e){                 e.printStackTrace();            }        }        //用递归的方法继续爬取其他链接            String nexturl=waitforUrl.get(0);            waitforUrl.remove(0);            gourl(nexturl,allUrldepth.get(nexturl));    }}


遇到的问题:allUrldepth作为hashmap,当key值即url一样时存在value值即depath被覆盖问题
解决办法:通过判断hashmap里key值是否包含,包含就把原有depath添加进去
if(allUrldepth.containsKey(href)) {
allUrldepth.put(href,depath);
}else {
allUrldepth.put(href, depath+1);
}

问题:通过一个线程执行速度太慢,通过多线程解决

解决办法:

private static int MAX_THREAD=5;//记录总线程数5条private static Object obj=new Object();//Object对象,帮助进行线程的等待操作public class myThread extends Thread{        @Override        public void run()         {            while(true)             {                if(waitforUrl.size()>0)                 {                    String url=waitforUrl.get(0);                    waitforUrl.remove(0);                    gourl(url, allUrldepth.get(url));                }else                 {                    System.out.println("当前线程准备就绪,等待连接爬取:"+this.getName());                      //建立一个对象,让线程进入等待状态,即wait()                      synchronized(obj){                        try{                          obj.wait();                        }catch(Exception e){                        }                }            }        }    }

问题:由于截取的部分a标签之间同时存在单双引号,例如www.baidu.com' > 很赞哦!

0