java實(shí)現(xiàn)爬蟲(chóng)爬網(wǎng)站圖片的實(shí)例代碼
第一步,實(shí)現(xiàn) LinkQueue,對(duì)url進(jìn)行過(guò)濾和存儲(chǔ)的操作
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class LinkQueue {
// 已訪問(wèn)的 url 集合
private static Set<String> visitedUrl = Collections.synchronizedSet(new HashSet<String>());
// 未訪問(wèn)的url
private static List<String> unVisitedUrl = Collections.synchronizedList(new ArrayList<String>());
// 未訪問(wèn)的URL出隊(duì)列
public static String unVisitedUrlDeQueue() {
if (unVisitedUrl.size() > 0) {
String url = unVisitedUrl.remove(0);
visitedUrl.add(url);
return url;
}
return null;
}
// 新的url添加進(jìn)來(lái)的時(shí)候進(jìn)行驗(yàn)證,保證只是添加一次
public static void addUnvisitedUrl(String url) {
if (url != null && !url.trim().equals("") && !visitedUrl.contains(url)
&& !unVisitedUrl.contains(url))
unVisitedUrl.add(url);
}
// 判斷未訪問(wèn)的URL隊(duì)列中是否為空
public static boolean unVisitedUrlsEmpty() {
return unVisitedUrl.isEmpty();
}
}
第二步,收集每一個(gè)url下的鏈接進(jìn)行過(guò)濾產(chǎn)生新的鏈接
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;
/**
* 過(guò)濾http的url,獲取可以符合規(guī)則的url
* @author Administrator
*
*/
public class ParserHttpUrl {
// 獲取一個(gè)網(wǎng)站上的鏈接,filter 用來(lái)過(guò)濾鏈接
public static Set<String> extracLinks(String url, LinkFilter filter) {
Set<String> links = new HashSet<String>();
try {
Parser parser = new Parser(url);
// 過(guò)濾 <frame >標(biāo)簽的 filter,用來(lái)提取 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 來(lái)設(shè)置過(guò)濾 <a> 標(biāo)簽,和 <frame> 標(biāo)簽
OrFilter linkFilter = new OrFilter(new NodeClassFilter(
LinkTag.class), frameFilter);
// 得到所有經(jīng)過(guò)過(guò)濾的標(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;
}
}
第三步,實(shí)現(xiàn)圖片下載功能
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();
}
}
}
}
實(shí)在Filter接口,定義過(guò)濾接口:
public interface Filter {
public boolean accept(String url);
}
第四步,過(guò)濾規(guī)則的實(shí)現(xiàn):
public class Crawler {
/**
* 抓取過(guò)程
*
* @return
* @param seeds
*/
public void crawling(String url) { // 定義過(guò)濾器
Filter filter = new Filter() {
public boolean accept(String url) {
//這里過(guò)濾規(guī)則隨需要爬的網(wǎng)站的規(guī)則進(jìn)行改變,推薦使用正則實(shí)現(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 隊(duì)列
LinkQueue.addUnvisitedUrl(url);
// 循環(huán)條件,待抓取的鏈接不空
while (!LinkQueue.unVisitedUrlsEmpty()) {
// 隊(duì)頭URL出隊(duì)列
String visitUrl = (String) LinkQueue.unVisitedUrlDeQueue();
if (visitUrl == null)
continue;
DownLoadPic.downloadPic(visitUrl);
// 提取出下載網(wǎng)頁(yè)中的 URL
Set<String> links = ParserHttpUrl.extracLinks(visitUrl, filter);
// 新的未訪問(wèn)的 URL 入隊(duì)
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實(shí)現(xiàn)爬蟲(chóng)爬網(wǎng)站圖片的實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Java 爬蟲(chóng)如何爬取需要登錄的網(wǎng)站
- Java 網(wǎng)絡(luò)爬蟲(chóng)新手入門(mén)詳解
- Java 網(wǎng)絡(luò)爬蟲(chóng)基礎(chǔ)知識(shí)入門(mén)解析
- JAVA使用HtmlUnit爬蟲(chóng)工具模擬登陸CSDN案例
- Java實(shí)現(xiàn)的爬蟲(chóng)抓取圖片并保存操作示例
- springboot+webmagic實(shí)現(xiàn)java爬蟲(chóng)jdbc及mysql的方法
- JAVA爬蟲(chóng)實(shí)現(xiàn)自動(dòng)登錄淘寶
- Java 爬蟲(chóng)服務(wù)器被屏蔽的解決方案
相關(guān)文章
Java連接mysql數(shù)據(jù)庫(kù)代碼實(shí)例程序
這篇文章主要介紹了java連接mysql數(shù)據(jù)庫(kù)代碼實(shí)例程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java實(shí)現(xiàn)分布式鎖的3種方法總結(jié)
分布式鎖是一種用于保證分布式系統(tǒng)中多個(gè)進(jìn)程或線程同步訪問(wèn)共享資源的技術(shù),同時(shí)它又是面試中的常見(jiàn)問(wèn)題,所以我們本文就重點(diǎn)來(lái)看分布式鎖的具體實(shí)現(xiàn),希望對(duì)大家有所幫助2023-09-09
Spring中@Controller和@RestController的區(qū)別詳解
這篇文章主要介紹了Spring中@Controller和@RestController的區(qū)別詳解,@RestController?是?@Controller?和?@ResponseBody?的結(jié)合體,單獨(dú)使用?@RestController?的效果與?@Controller?和?@ResponseBody?二者同時(shí)使用的效果相同,需要的朋友可以參考下2023-10-10

