一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - JAVA 多線程爬蟲實例詳解

JAVA 多線程爬蟲實例詳解

2020-09-18 14:15Java之家 JAVA教程

這篇文章主要介紹了JAVA 多線程爬蟲實例詳解的相關資料,需要的朋友可以參考下

JAVA 多線程爬蟲實例詳解

前言

以前喜歡Python的爬蟲是出于他的簡潔,但到了后期需要更快,更大規模的爬蟲的時候,我才漸漸意識到Java的強大。Java有一個很好的機制,就是多線程。而且Java的代碼效率執行起來要比python快很多。這份博客主要用于記錄我對多線程爬蟲的實踐理解。

線程

線程是指一個任務從頭至尾的執行流。線程提供了運行一個任務的機制。對于Java而言,可以在一個程序中并發地啟動多個線程。這些線程可以在多處理器系統上同時運行。

runnable接口

任務類必須實現runnable接口,它只包含一個run方法。需要實現這個方法來告訴系統線程將如何運行。

Thread類

包含為任務而創建的線程的構造方法,以及控制線程的方法。

synchronized關鍵字

為避免競爭狀態,防止多個線程同時進入程序的某個特定部分,即臨界區,以便一次只有一個線程可以訪問臨界區。

利用加鎖同步

Java可以顯式加鎖,一個鎖是一個Lock接口的實例,它定義了加鎖和釋放鎖的方法。

線程池

線程池是管理開發執行任務個數的理想方法。Java提供Executor接口來執行線程池中的任務,提供ExecutorService接口管理和控制任務。

使用線程池的方法獲取url列表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
/*
 * 獲取京東評論url列表
 */
 
public class MyThreading {
  private static String p_id = null;
  private static Url urls = null;
 
  public MyThreading(String p_id){
    this.p_id = p_id ;   // 京東商品的id
    urls = new Url(p_id);
  }
 
  public List<String> getUriList(){
    ExecutorService executor = Executors.newCachedThreadPool();
    for (int i = 0 ; i < 600 ; i ++){
      executor.execute(new AddUrl(i));    // 添加任務到線程池
    }
    executor.shutdown();
    while (!executor.isTerminated()){}
    return urls.getList();
  }
 
  public static class AddUrl implements Runnable{
    int page;
    public AddUrl(int page){
      this.page = page;
    }
    public void run(){
      urls.addList(page);   // 啟動多線程任務
    }
  }
 
  public static class Url {
 
    private static Lock lock = new ReentrantLock();     // 開啟顯式家鎖
    private static List<String> urlList = new ArrayList();    
    private String p_id;
 
    public Url(String p_id ){
      this.p_id = p_id ;
    }
    public List<String> getList(){
      return urlList;
    }
    public void addList(int page){
      lock.lock();
      try{
        String url = "http://club.jd.com/productpage/p-" + p_id + "-s-0-t-0-p-" + String.valueOf(page) + ".html";
//       Thread.sleep(5);
        urlList.add(url);    //添加url到url列表
      }catch(Exception ex ){
      }
      finally {
        lock.unlock();     // 解鎖
      }
 
    }
  }
  public static void main(String[] args) {
    String p_id = "2441288";
    MyThreading myThreading = new MyThreading(p_id);
    List <String> urlList = myThreading.getUriList();
    for(String url : urlList){
      System.out.println(url);
    }
    System.out.println(urlList.size());
  }
}

代碼分析

  • 代碼的作用:獲取京東評論的url列表
  • 類的說明:MyThreading是主類, AddUrl和Url是它的內部類,AddUrl實現了runnable的接口,主要啟動多線程服務運行Url的addList方法。而Url是最內核的部分 ,他提供addList任務和多線程的共享區域urlList,所以在實現添加url的步驟中,需要對urlList加鎖。
  • 線程池主要有兩種類型,一個是固定線程池,即newFixedThreadPool;另一個是newCachedThreadPool,這個主要利用了緩沖機制,能動態地添加線程。在上述代碼中,我主要使用了newCachedthreadPool.

使用線程池的方法根據url列表爬取網頁元素

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
 
public class ThreadingCrawel {
  private static Content content = null;
  private static List<String> urlList = null;
 
  public ThreadingCrawel(List<String> urlList){
    this.urlList = urlList;
    content = new Content();
  }
  public List<String> getContent(){
 
    ExecutorService executor = Executors.newCachedThreadPool();
    for (String url : urlList){
      executor.execute(new AddContent(url));
    }
    executor.shutdown();
    while(!executor.isTerminated()){}
    return content.getContent();
 
  }
 
  public static class AddContent implements Runnable{
    String url;
    public AddContent(String url){
      this.url = url;
    }
    public void run(){
      content.addContent(url);
    }
  }
 
  public static class Content {
 
    private static Lock lock = new ReentrantLock();
    private static List<String> contentList = new ArrayList();
 
    public void addContent(String url){
 
      String content = "";
      BufferedReader in = null;
      try{
        URL realUrl = new URL(url);
        URLConnection connection = realUrl.openConnection();
        in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "gbk"));
        String line;
        while( (line = in.readLine()) != null){
          content += line +"\n";
        }
      }catch(Exception e){
        e.printStackTrace();
      }
      finally{
        try{
          if (in != null){
            in.close();
          }
        }catch(Exception e2){
          e2.printStackTrace();
        }
      }
 
      Pattern p = Pattern.compile("content\":\".*?\"");
      Matcher match = p.matcher(content);
      String tmp;
       lock.lock();
      while(match.find()){
        tmp = match.group();
        tmp = tmp.replaceAll("\"", "");
        tmp = tmp.replace("content:", "");
        tmp = tmp.replaceAll("<.*?>", "");
        contentList.add(tmp);
        try {
          Thread.sleep(1);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
      lock.unlock();
 
    }
    public List getContent(){
      return contentList;
    }
  }
  public static void main(String[] args){
    long start = System.currentTimeMillis();
    String p_id = "2441288";
    MyThreading myThreading = new MyThreading(p_id);
    List <String> urlList = myThreading.getUriList();
    ThreadingCrawel threadingCrawel = new ThreadingCrawel(urlList);
    List <String> contentList = threadingCrawel.getContent();
    for(String content : contentList){
      System.out.println(content);
    }
    long end = System.currentTimeMillis();
    System.out.println(end - start);
  }
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

原文鏈接:http://blog.csdn.net/qq_30843221/article/details/52486735

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 帅小伙和警官同性3p | 茄子视频懂你更多apl | 啪啪大幂幂被c | 美女岳肉太深了使劲 | 欧美午夜精品久久久久久黑人 | 精品国产影院 | 2021国产精品成人免费视频 | 日产乱码卡一卡2卡三卡四福利 | 天天久久综合网站 | 俄罗斯毛片免费大全 | 女暴露狂校园裸露小说 | gav男人天堂 | 久久99精品国产免费观看 | 2019午夜福合集高清完整版 | 翁熄性放纵交换01 | 日本高清视频网址 | 亚洲第一综合天堂另类专 | 亚洲精品AV无码永久无码 | 国产成人在线小视频 | 亚洲欧美日韩国产一区二区精品 | 嗯啊在线观看免费影院 | 深夜福利入口 | 亚欧洲乱码专区视频 | 国产18在线 | w7w7w7w7w免费| 国产亚洲精品一区在线播 | 日剧整部剧护妻狂魔免费观看全集 | 免费视频 久久久 | 日韩欧美高清一区 | 国产精品九九免费视频 | 强女明星系列小说 | 精品久久久久免费极品大片 | 精灵之森高清在线 | 52av我爱avhaose01好 | 大象传媒免费网址 | 国产清纯91天堂在线观看 | 四虎影视免费观看免费观看 | 97视频久久久 | 7777奇米影视 | 四川女人偷人真实视频 | 美女被躁了在线观看视频 |