java图片爬虫_java实现爬虫爬网站图片

第一步,实现 LinkQueue,对url进行过滤和存储的操作

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 visitedUrl = Collections.synchronizedSet(new HashSet());

// 未访问的url

private static List unVisitedUrl = Collections.synchronizedList(new ArrayList());

// 未访问的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下的链接进行过滤产生新的链接

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 extracLinks(String url, LinkFilter filter) {

Set links = new HashSet();

try {

Parser parser = new Parser(url);

// 过滤 标签的 filter,用来提取 frame 标签里的 src 属性所表示的链接

NodeFilter frameFilter = new NodeFilter() {

public boolean accept(Node node) {

if (node.getText().startsWith("frame src=")) {

return true;

} else {

return false;

}

}

};

// OrFilter 来设置过滤 标签,和 标签

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)// 标签

{

LinkTag link = (LinkTag) tag;

String linkUrl = link.getLink();// url

if (filter.accept(linkUrl))

links.add(linkUrl);

} else// 标签

{

// 提取 frame 里 src 属性的链接如

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;

}

}

第三步,实现图片下载功能

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 = "]*?>";

// 获取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 imgUrl = DownLoadPic.getImageUrl(HTML);

// 获取图片src地址

List 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 getImageUrl(String HTML) {

Matcher matcher = Pattern.compile(IMGURL_REG).matcher(HTML);

List listImgUrl = new ArrayList();

while (matcher.find()) {

listImgUrl.add(matcher.group());

}

return listImgUrl;

}

/***

* 获取ImageSrc地址

*

* @param listImageUrl

* @return

*/

private static List getImageSrc(List listImageUrl) {

List listImgSrc = new ArrayList();

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 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接口,定义过滤接口:

public interface Filter {

public boolean accept(String url);

}

第四步,过滤规则的实现:

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 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");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值