第一步,实现 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下的链接进行过滤产生新的链接
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,获取可以符合规则的url * @author administrator * */ public class parserhttpurl { // 获取一个网站上的链接,filter 用来过滤链接 public static set<string> extraclinks(string url, linkfilter filter) { set<string> links = new hashset<string>(); try { parser parser = new parser(url); // 过滤 <frame >标签的 filter,用来提取 frame 标签里的 src 属性所表示的链接 nodefilter framefilter = new nodefilter() { public boolean accept(node node) { if (node.gettext().startswith( "frame src=" )) { return true ; } else { return false ; } } }; // orfilter 来设置过滤 <a> 标签,和 <frame> 标签 orfilter linkfilter = new orfilter( new nodeclassfilter( linktag. class ), framefilter); // 得到所有经过过滤的标签 nodelist list = parser.extractallnodesthatmatch(linkfilter); for ( int i = 0 ; i < list.size(); i++) { node tag = list.elementat(i); if (tag instanceof linktag) // <a> 标签 { linktag link = (linktag) tag; string linkurl = link.getlink(); // url if (filter.accept(linkurl)) links.add(linkurl); } else // <frame> 标签 { // 提取 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; } } |
第三步,实现图片下载功能
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抓取网络图片 * * @author swinglife * */ public class downloadpic { // 编码 private static final string ecoding = "utf-8" ; // 获取img标签正则 private static final string imgurl_reg = "<img.*src=(.*?)[^>]*?>" ; // 获取src路径的正则 private static final string imgsrc_reg = "http:"?(.*?)("|>|\s+)" ; public static void downloadpic(string url) { // 获得html文本内容 string html = null ; try { html = downloadpic.gethtml(url); } catch (exception e) { e.printstacktrace(); } if ( null != html && ! "" .equals(html)) { // 获取图片标签 list<string> imgurl = downloadpic.getimageurl(html); // 获取图片src地址 list<string> imgsrc = downloadpic.getimagesrc(imgurl); // 下载图片 downloadpic.download(imgsrc); } } /*** * 获取html内容 * * @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); } |
第四步,过滤规则的实现:
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) { //这里过滤规则随需要爬的网站的规则进行改变,推荐使用正则实现,本人是爬豆瓣网站 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); // 循环条件,待抓取的链接不空 while (!linkqueue.unvisitedurlsempty()) { // 队头url出队列 string visiturl = (string) linkqueue.unvisitedurldequeue(); if (visiturl == null ) continue ; downloadpic.downloadpic(visiturl); // 提取出下载网页中的 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" ); } } |
总结
以上所述是小编给大家介绍的java实现爬虫爬网站图片的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://blog.csdn.net/dingzfeng/article/details/80536987