在Java Web爬虫中实现线程

在Java Web爬虫中实现线程,java,multithreading,concurrency,jsoup,web-crawler,Java,Multithreading,Concurrency,Jsoup,Web Crawler,这是我写的原始网络爬虫:(仅供参考) 这是一个简单的网络爬虫程序,它访问给定的初始网页,从该网页中删除所有链接,并将它们添加到队列(LinkedList),然后在队列中逐个弹出,每次访问一次,循环再次开始。为了加速我的程序,为了学习,我尝试使用线程来实现,这样我就可以让多个线程同时运行,在更短的时间内索引更多的页面。以下是每节课的内容: 主类 爬虫类(线程) 公共类爬虫程序扩展线程{ /**数据结构实例**/ 数据结构数据; /**程序终止前允许的页面连接数**/ 私有最终整数指数_限制=10;

这是我写的原始网络爬虫:(仅供参考)

这是一个简单的网络爬虫程序,它访问给定的初始网页,从该网页中删除所有链接,并将它们添加到队列(LinkedList),然后在队列中逐个弹出,每次访问一次,循环再次开始。为了加速我的程序,为了学习,我尝试使用线程来实现,这样我就可以让多个线程同时运行,在更短的时间内索引更多的页面。以下是每节课的内容:

主类

爬虫类(线程)

公共类爬虫程序扩展线程{
/**数据结构实例**/
数据结构数据;
/**程序终止前允许的页面连接数**/
私有最终整数指数_限制=10;
/**要访问的初始URL**/
公共爬虫(数据结构d){
数据=d;
}
公开募捐{
//计数器以跟踪索引URL的数量
int计数器=0;
//当URL被留下来访问时

虽然((data.url_to_visit_size()>0)和&counter添加了:查看我的评论,我认为签入爬虫

// While URL's left to visit
        while((data.url_to_visit_size() > 0) && counter<INDEX_LIMIT) {
//当URL被留下来访问时
while((data.url_to_visit_size()>0)和&counter
class控制器{
公共静态void main(字符串args[])引发InterruptedException{
最终整数限值=4;
List seedList=new ArrayList();//1
种子列表。添加(“https://www.youtube.com/");
种子列表。添加(“https://www.digg.com/");
种子列表。添加(“https://www.reddit.com/");
种子列表。添加(“https://www.nytimes.com/");
数据结构[]数据=新数据结构[限制];
对于(int i=0;i
你可以试试这个

  • 创建种子列表

  • 创建datastruc的对象并将种子列表添加到每个对象中

  • 创建爬网数组并将datastruc对象逐个传递给它们
  • 将爬网对象传递给执行器

  • 以的形式提供当前用于多线程的实现,否则我们无法帮助您。在本网站中,通过外部链接提供代码是不可接受的。这个问题在这个时候会很奇怪,但您的CPU有多少内核?我的笔记本电脑是双核的,这可能取决于您与internet的连接。如果u是网络绑定的,那么有几个连接尝试使用连接可能会减慢速度。因为它至少有2个内核,所以每个线程将在一个内核中运行(假设您的操作系统能够很好地处理多线程,并且没有问题)。那么您的问题可能在于绑定到网络访问的I/O操作,正如@Jayde所指出的。使用此策略根本不需要使用任何并发列表。缺点是,当它们运行时,您不会获得太多实时反馈。第一句话是错误的,因为您可以使用并发列表为任务提供数据(以
    Runnable
    Callable
    的形式)。第二句也是错误的,您只需为所有任务定义另一个共享的并发结构,其中每个任务都可以存储消息或信号或其他类型的信息。此外,如果您看到OP的实现,则在更改为线程池策略时,您不会获得太多速度。每个可调用对象都有一个要处理的URL,因此第一句是正确的例如,对于第二句话,是的,你可以为消息定义一个并发结构,但是,如果你不这样做,生活会更简单,但实时反馈会更少。然而,由于OP的爬虫确实相互作用,这种方法可能不太理想。
    public class controller {
    
        public static void main(String args[]) throws InterruptedException {
    
            DataStruc data = new DataStruc("http://www.imdb.com/title/tt1045772/?ref_=nm_flmg_act_12");
    
            Thread crawl1 = new Crawler(data);
            Thread crawl2 = new Crawler(data);
    
            crawl1.start();
            crawl2.start();
       }    
    }
    
    public class Crawler extends Thread {
    
        /** Instance of Data Structure **/
        DataStruc data;
    
        /** Number of page connections allowed before program terminates **/
        private final int INDEX_LIMIT = 10;
    
        /** Initial URL to visit **/
        public Crawler(DataStruc d) {
            data = d;
        }
    
        public void run() {
    
            // Counter to keep track of number of indexed URLS
            int counter = 0;
    
            // While URL's left to visit
            while((data.url_to_visit_size() > 0) && counter<INDEX_LIMIT) {
    
                // Pop next URL to visit from stack
                String currentUrl = data.getURL();
    
                try {
                    // Fetch and parse HTML document
                    Document doc = Jsoup.connect(currentUrl)                 
                            .userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36")
                            .referrer("http://www.google.com")
                            .timeout(12000)
                            .followRedirects(true)
                            .get();
    
                    // Increment counter if connection to web page succeeds
                    counter++;
    
                    /** .select returns a list of elements (links in this case) **/
                    Elements links = doc.select("a[href]"); // Relative URL
    
                    // Add newly found links to stack
                    addLinksToQueue(links);                             
    
                } catch (IOException e) {
                    //e.printStackTrace();
                    System.out.println("Error: "+currentUrl);
                }               
            }       
        }
    
        public void addLinksToQueue(Elements el) {
            // For each element in links
            for(Element e : el) {           
    
                String theLink = e.attr("abs:href"); // 'abs' prefix ensures absolute url is returned rather then relative url ('www.reddit.com/hello' rather then '/hello')
    
                if(theLink.startsWith("http") && !data.oldLink(theLink)) {
                    data.addURL(theLink);
                    data.addVisitedURL(theLink); // Register each unique URL to ensure it isnt stored in 'url_to_visit' again
                    System.out.println(theLink);
                }               
            }   
        }
    }
    
    public class DataStruc {
    
        /** Queue to store URL's, can be accessed by multiple threads **/
        private ConcurrentLinkedQueue<String> url_to_visit = new ConcurrentLinkedQueue<String>();
    
        /** ArrayList of visited URL's **/
        private ArrayList<String> visited_url = new ArrayList<String>();
    
        public DataStruc(String initial_url) {
            url_to_visit.offer(initial_url);
        }
    
        // Method to add seed URL to queue
        public void addURL(String url) {
            url_to_visit.offer(url);
        }
    
        // Get URL at front of queue
        public String getURL() {
            return url_to_visit.poll();
        }
    
        // URL to visit size
        public int url_to_visit_size() {
            return url_to_visit.size();
        }
    
        // Add visited URL
        public void addVisitedURL(String url) {
            visited_url.add(url);
        }
    
        // Checks if link has already been visited
        public boolean oldLink(String link) {
            for(String s : visited_url) {
                if(s.equals(link)) {
                    return true;
                }
            }   
            return false;
        }       
    }
    
    // While URL's left to visit
            while((data.url_to_visit_size() > 0) && counter<INDEX_LIMIT) {
    
    class controller {
    
        public static void main(String args[]) throws InterruptedException {
    
            final int LIMIT = 4;
    
            List<String> seedList = new ArrayList<>(); //1
            seedList.add("https://www.youtube.com/");
            seedList.add("https://www.digg.com/");
            seedList.add("https://www.reddit.com/");
            seedList.add("https://www.nytimes.com/");
    
            DataStruc[] data = new DataStruc[LIMIT];
    
            for(int i = 0; i < LIMIT; i++){
                data[i] = new DataStruc(seedList.get(i)); //2
            }
    
            ExecutorService es = Executors.newFixedThreadPool(LIMIT);
            Crawler[] crawl = new Crawler[LIMIT];
            for(int i = 0; i < LIMIT; i++){
                crawl[i] = new Crawler(data[i]); //3
            }
    
            for(int i = 0; i < LIMIT; i++){
                es.submit(crawl[i]) // 4
            }
        }
    }