第一步,實現(xiàn) linkqueue,對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
|
import java.util.arraylist; import java.util.collections; import java.util.hashset; import java.util.list; import java.util.set; public class linkqueue { // 已訪問的 url 集合 private static set<string> visitedurl = collections.synchronizedset( new hashset<string>()); // 未訪問的url private static list<string> unvisitedurl = collections.synchronizedlist( new arraylist<string>()); // 未訪問的url出隊列 public static string unvisitedurldequeue() { if (unvisitedurl.size() > 0 ) { string url = unvisitedurl.remove( 0 ); visitedurl.add(url); return url; } return null ; } // 新的url添加進來的時候進行驗證,保證只是添加一次 public static void addunvisitedurl(string url) { if (url != null && !url.trim().equals( "" ) && !visitedurl.contains(url) && !unvisitedurl.contains(url)) unvisitedurl.add(url); } // 判斷未訪問的url隊列中是否為空 public static boolean unvisitedurlsempty() { return unvisitedurl.isempty(); } } |
第二步,收集每一個url下的鏈接進行過濾產(chǎn)生新的鏈接
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
|
import java.util.hashset; import java.util.set; import org.htmlparser.node; import org.htmlparser.nodefilter; import org.htmlparser.parser; import org.htmlparser.filters.nodeclassfilter; import org.htmlparser.filters.orfilter; import org.htmlparser.tags.linktag; import org.htmlparser.util.nodelist; import org.htmlparser.util.parserexception; /** * 過濾http的url,獲取可以符合規(guī)則的url * @author administrator * */ public class parserhttpurl { // 獲取一個網(wǎng)站上的鏈接,filter 用來過濾鏈接 public static set<string> extraclinks(string url, linkfilter filter) { set<string> links = new hashset<string>(); try { parser parser = new parser(url); // 過濾 <frame >標(biāo)簽的 filter,用來提取 frame 標(biāo)簽里的 src 屬性所表示的鏈接 nodefilter framefilter = new nodefilter() { public boolean accept(node node) { if (node.gettext().startswith( "frame src=" )) { return true ; } else { return false ; } } }; // orfilter 來設(shè)置過濾 <a> 標(biāo)簽,和 <frame> 標(biāo)簽 orfilter linkfilter = new orfilter( new nodeclassfilter( linktag. class ), framefilter); // 得到所有經(jīng)過過濾的標(biāo)簽 nodelist list = parser.extractallnodesthatmatch(linkfilter); for ( int i = 0 ; i < list.size(); i++) { node tag = list.elementat(i); if (tag instanceof linktag) // <a> 標(biāo)簽 { linktag link = (linktag) tag; string linkurl = link.getlink(); // url if (filter.accept(linkurl)) links.add(linkurl); } else // <frame> 標(biāo)簽 { // 提取 frame 里 src 屬性的鏈接如 <frame src="test.html"/> string frame = tag.gettext(); int start = frame.indexof( "src=" ); frame = frame.substring(start); int end = frame.indexof( " " ); if (end == - 1 ) end = frame.indexof( ">" ); string frameurl = frame.substring( 5 , end - 1 ); if (filter.accept(frameurl)) links.add(frameurl); } } } catch (parserexception e) { e.printstacktrace(); } return links; } } |
第三步,實現(xiàn)圖片下載功能
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
113
114
115
116
|
import java.io.file; import java.io.fileoutputstream; import java.io.inputstream; import java.net.url; import java.net.urlconnection; import java.util.arraylist; import java.util.list; import java.util.regex.matcher; import java.util.regex.pattern; /*** * java抓取網(wǎng)絡(luò)圖片 * * @author swinglife * */ public class downloadpic { // 編碼 private static final string ecoding = "utf-8" ; // 獲取img標(biāo)簽正則 private static final string imgurl_reg = "<img.*src=(.*?)[^>]*?>" ; // 獲取src路徑的正則 private static final string imgsrc_reg = "http:"?(.*?)("|>|\s+)" ; public static void downloadpic(string url) { // 獲得html文本內(nèi)容 string html = null ; try { html = downloadpic.gethtml(url); } catch (exception e) { e.printstacktrace(); } if ( null != html && ! "" .equals(html)) { // 獲取圖片標(biāo)簽 list<string> imgurl = downloadpic.getimageurl(html); // 獲取圖片src地址 list<string> imgsrc = downloadpic.getimagesrc(imgurl); // 下載圖片 downloadpic.download(imgsrc); } } /*** * 獲取html內(nèi)容 * * @param url * @return * @throws exception */ private static string gethtml(string url) throws exception { url uri = new url(url); urlconnection connection = uri.openconnection(); inputstream in = connection.getinputstream(); byte [] buf = new byte [ 1024 ]; int length = 0 ; stringbuffer sb = new stringbuffer(); while ((length = in.read(buf, 0 , buf.length)) > 0 ) { sb.append( new string(buf, ecoding)); } in.close(); return sb.tostring(); } /*** * 獲取imageurl地址 * * @param html * @return */ private static list<string> getimageurl(string html) { matcher matcher = pattern.compile(imgurl_reg).matcher(html); list<string> listimgurl = new arraylist<string>(); while (matcher.find()) { listimgurl.add(matcher.group()); } return listimgurl; } /*** * 獲取imagesrc地址 * * @param listimageurl * @return */ private static list<string> getimagesrc(list<string> listimageurl) { list<string> listimgsrc = new arraylist<string>(); for (string image : listimageurl) { matcher matcher = pattern.compile(imgsrc_reg).matcher(image); while (matcher.find()) { listimgsrc.add(matcher.group().substring( 0 , matcher.group().length() - 1 )); } } return listimgsrc; } /*** * 下載圖片 * * @param listimgsrc */ private static void download(list<string> listimgsrc) { for (string url : listimgsrc) { try { string imagename = url.substring(url.lastindexof( "/" ) + 1 , url.length()); url uri = new url(url); inputstream in = uri.openstream(); fileoutputstream fo = new fileoutputstream( new file(imagename)); byte [] buf = new byte [ 1024 ]; int length = 0 ; while ((length = in.read(buf, 0 , buf.length)) != - 1 ) { fo.write(buf, 0 , length); } in.close(); fo.close(); } catch (exception e) { e.printstacktrace(); } } } } |
實在filter接口,定義過濾接口:
1
2
3
|
public interface filter { public boolean accept(string url); } |
第四步,過濾規(guī)則的實現(xiàn):
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
|
public class crawler { /** * 抓取過程 * * @return * @param seeds */ public void crawling(string url) { // 定義過濾器 filter filter = new filter() { public boolean accept(string url) { //這里過濾規(guī)則隨需要爬的網(wǎng)站的規(guī)則進行改變,推薦使用正則實現(xiàn),本人是爬豆瓣網(wǎng)站 if (url.indexof( "douban.com/group/topic" ) != - 1 || url.indexof( "douban.com/group/haixiuzu/discussion?start" ) != - 1 ) return true ; else return false ; } }; // 初始化 url 隊列 linkqueue.addunvisitedurl(url); // 循環(huán)條件,待抓取的鏈接不空 while (!linkqueue.unvisitedurlsempty()) { // 隊頭url出隊列 string visiturl = (string) linkqueue.unvisitedurldequeue(); if (visiturl == null ) continue ; downloadpic.downloadpic(visiturl); // 提取出下載網(wǎng)頁中的 url set<string> links = parserhttpurl.extraclinks(visiturl, filter); // 新的未訪問的 url 入隊 for (string link : links) { linkqueue.addunvisitedurl(link); } } } // main 方法入口 public static void main(string[] args) { crawler crawler = new crawler(); crawler.crawling( "http://www.douban.com/group/haixiuzu/discussion?start=0" ); } } |
總結(jié)
以上所述是小編給大家介紹的java實現(xiàn)爬蟲爬網(wǎng)站圖片的實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!
原文鏈接:https://blog.csdn.net/dingzfeng/article/details/80536987