1.学习目的:熟悉java类集以及IO流操作,为图片识别做采集铺垫
2.对象网站:http://www.ivsky.com
3.制作思路: 1. 输入一个网址,获取该网址的html内容.
2. 分析html内容,提取到所有网址和图片地址
3. 如果是遍历网址就循环对每个网址重复做步骤一和步骤2,如果是图片,就下载图片。(所有方法都做函数封装)
没做界面,就一个简单的控制台程序(输入数字即可运行),效果图如下:
源代码和源文件(在最下面)如下:
1.SpiderHelp.java文件(封装各个函数)
package spider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SpiderHelp {
static int cou=0;//记图片的数量
/**
* 下载功能
*
* @param urlString
* @param filename
* @param savePath
* @throws Exception
*/
public static void download(String urlString, String filename, String savePath) {
try {
// 构造URL
URL url = new URL(urlString);
// 打开连接
URLConnection con = url.openConnection();
// 设置请求超时为5s
con.setConnectTimeout(5 * 1000);
// 输入流
InputStream is = con.getInputStream();
// 1K的数据缓冲
byte[] bs = new byte[1024];
// 读取到的数据长度
int len;
// 输出的文件流
File sf = new File(savePath);
if (!sf.exists()) {
sf.mkdirs();
}
OutputStream os = new FileOutputStream(sf.getPath() + "\\" + filename);
// 开始读取
while ((len = is.read(bs)) != -1) {
os.write(bs, 0, len);
}
} catch (Exception e) {
// TODO: handle exception
} finally {
}
}
/**
* 传入一个网址字符串返回网页的html内容
*
* @param webSite
* @return String
* @throws Exception
*/
public static String getWebConcent(String webSite) {
try {
// 定义即将访问的链接
String url = webSite;
// 定义一个字符串用来存储网页内容
String result = "";
// 定义一个缓冲字符输入流
BufferedReader in = null;
// 将url的string字符串转成url对象
URL realUrl = new URL(url);
// 初始化一个连接到那个URL链接
URLConnection connection = realUrl.openConnection();
// 开始实际连接
connection.connect();
// 初始化BufferedReader输入流来读取URL的响应并指定字符串编码为UTF-8
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
// 用来临时存储抓取到每一行的数据
String line;
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
// TODO: handle exception
in.close();
// System.out.println(result);
return result;
} catch (Exception e) {
// TODO: handle exception
}
return "";
}
/**
* 输入字符串和正则匹配字符,返回分割的字符
*
* @param regex
* @param str
* @return String
*/
public static String splitStringOne(String regex, String str) {
try {
Pattern pattern = Pattern.compile(regex); // 定义一个模版
Matcher matcher = pattern.matcher(str);// 定义一个匹配类
String str1 = new String();
if (matcher.find()) { // 开始搜索匹配的字符串
str1 = matcher.group(0);// 将匹配的字符串赋给str1
} else {
str1 = "";
}
return str1;// 返回字符串
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";// 返回字符串
}
/**
* 输入字符串和正则匹配字符,返回分割字符是否成功
*
* @param regex
* @param str
* @return String
*/
public static boolean splitStringOneWithJudge(String regex, StringBuffer strBuf) {
Pattern pattern = Pattern.compile(regex); // 定义一个模版
Matcher matcher = pattern.matcher(strBuf);
// String str1 = new String();
if (matcher.find()) {
String str1 = matcher.group(0);
int strBufLength = strBuf.length();
strBuf.replace(0, strBufLength, "");
strBuf.append(str1);
return true;
}
return false;
}
/**
* 传入一个网址字符串返回分割好的字符串数组
*
* @param webSite
* @return String
* @throws Exception
*/
public static String[] splitStringMany(String regex, String str) {
if (!("".equals(str))) {
Pattern pattern = Pattern.compile(regex); // 定义一个模版
Matcher matcher = pattern.matcher(str);
String[] str1 = new String[0];
// str1=str.split(regex, 20);
while (matcher.find()) {
String[] cloned = new String[str1.length + 1];
System.arraycopy(str1, 0, cloned, 0, cloned.length - 1);
cloned[cloned.length - 1] = matcher.group();
str1 = cloned;
}
// for ( String string2 : str1 )
// {
// System.out.println (string2);
// }
return str1;
} else {
return null;
}
}
/**
* 截取字符串数组中的字符,并返回字符串数组
*
* @param regex
* @param str
* @return 字符串数组
*/
public static String[] splitStringMany(String regex, String str[]) {
// 遍历str[]数组中的每一个元素,根据正则表达式分割
for (int i = 0; i < str.length; i++) {
str[i] = splitStringOne(regex, str[i]);
}
return str;
}
/**
* 对图片天堂网一个进行下载图片网址
*
* @throws Exception
*
*/
public static void imgDownloadToHeavenWeb(String url) {
try {
String regex = "<img.*?>";// 定义获取img标签的正则表达式
String[] str1 = null;// 定义接收img标签的数组
SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
// String str =
// spiHel.getWebConcent("http://www.ivsky.com/tupian/ziranfengguang/");//
// 获取该网站的数据
String str = spiHel.getWebConcent(url);
System.out.println("原始数据为" + str);// 输出原始数据
System.out.println("==================");
str1 = spiHel.splitStringMany(regex, str); // 对数据进行分割并将数据保存在数组里面
for (int i = 0; i < str1.length; i++) { // 输出第一次提取的数据
System.out.println("第" + i + "条数据为" + str1[i]);
}
System.out.println("==================");
str1 = spiHel.splitStringMany("src=\".*?\"", str1);// 在对数据进行第二次提取
for (int i = 0; i < str1.length; i++) {
System.out.println("第" + i + "条数据为" + str1[i]);
}
System.out.println("==================");
str1 = spiHel.splitStringMany("http.+jpg", str1);// 在对数据进行第二次提取
for (int i = 0; i < str1.length; i++) {
System.out.println("第" + i + "条数据为" + str1[i]);
}
System.out.println("==================");
// 下载图片测试
for (int i = 0; i < str1.length; i++) {
String s = getPresentTime() + "第" + cou++ + "张图片.jpg"; // 定义每一张图片名字并设置后缀名
if (!("".equals(str1[i]))) {
System.out.println("第" + cou + "张图片正在下载");
spiHel.download(str1[i], s, "d:\\image\\");// 遍历网址并下载图片
}
System.out.println("==================");
}
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* 对图片天堂网的网址进行分割,如果与原网址相等则返回空
*
* @return
*/
public static String[] htmlDivisionToHeavenWeb(String url) throws Exception {
SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
String[] str1 = null;// 定义接收img标签的数组
String str = spiHel.getWebConcent(url);
// 测试对网址的提取
str1 = spiHel.splitStringMany("<a.*?>", str); // 对数据进行第一次分割并将数据保存在数组里面
if (str1 != null) {
for (int i = 0; i < str1.length; i++) {
System.out.println("第" + i + "条数据为" + str1[i]);
}
System.out.println("==================");
str1 = spiHel.splitStringMany("href=[\'\"].*?[\'\"]", str); // 对数据进行第二次分割并将数据保存在数组里面
for (int i = 0; i < str1.length; i++) {
System.out.println("第" + i + "条数据为" + str1[i]);
}
System.out.println("==================");
str1 = spiHel.splitStringMany("/.*/", str1); // 对数据进行第三次分割并将数据保存在数组里面
for (int i = 0; i < str1.length; i++) {
if ("".equals(str1[i])) {
str1[i] = "";
} else if ("/".equals(str1[i])) {
str1[i] = "";
} else if ("//".equals(str1[i])) {
str1[i] = "";
} else {
str1[i] = "http://www.ivsky.com" + str1[i];
System.out.println("第" + i + "条数据为" + str1[i]);
}
}
return str1;
} else
return null;
}
/**
* 对图片天堂网的网址进行分割,如果与原网址相等则返回空,只返回网址
*
* @return
*/
public static String[] htmlDivisionToHeavenOnly(String url) throws Exception {
if("".equals(url)){
return null;
}
else{
SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
String[] str1 = null;// 定义接收img标签的数组
String str = spiHel.getWebConcent(url);
// 测试对网址的提取
str1 = spiHel.splitStringMany("<a.*?>", str); // 对数据进行第一次分割并将数据保存在数组里面
if (str1 != null) {
// for (int i = 0; i < str1.length; i++) {
// System.out.println("第" + i + "条数据为" + str1[i]);
// }
// System.out.println("==================");
str1 = spiHel.splitStringMany("href=[\'\"].*?[\'\"]", str); // 对数据进行第二次分割并将数据保存在数组里面
// for (int i = 0; i < str1.length; i++) {
// System.out.println("第" + i + "条数据为" + str1[i]);
// }
// System.out.println("==================");
str1 = spiHel.splitStringMany("/.*/", str1); // 对数据进行第三次分割并将数据保存在数组里面
for (int i = 0; i < str1.length; i++) {
if ("".equals(str1[i])) {
str1[i] = "";
} else if ("/".equals(str1[i])) {
str1[i] = "";
} else if ("//".equals(str1[i])) {
str1[i] = "";
} else if ("/img/".equals(str1[i])) {
str1[i] = "";
} else {
str1[i] = "http://www.ivsky.com" + str1[i];
System.out.println("第" + i + "条数据为" + str1[i]);
}
}
return str1;
} else
return null;
}
}
/**
* 获取当前系统时间并返回自定义格式
*
* @return
*/
public static String getPresentTime() {
Calendar calendar = new GregorianCalendar();
StringBuffer strBuf = new StringBuffer();
strBuf.append(calendar.get(Calendar.YEAR) + "年");
strBuf.append(calendar.get(Calendar.MONTH) + "月");
strBuf.append(calendar.get(Calendar.DAY_OF_MONTH) + "日");
strBuf.append(calendar.get(Calendar.HOUR_OF_DAY) + "时");
strBuf.append(calendar.get(Calendar.MINUTE) + "分");
strBuf.append(calendar.get(Calendar.SECOND) + "秒");
strBuf.append(calendar.get(Calendar.MILLISECOND) + "毫秒");
String str = strBuf.toString();// 将时间转化为字符串
return str;
}
/**
* 对全景网一个进行下载图片网址
*
* @throws Exception
*
*/
public static void imgDownloadToanoramaWeb(String url, int number) {
try {
SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
// 获取该网站的数据
// 下载图片测试
for (int i = 0; i < number; i++) {
String s = getPresentTime() + "第" + i + "张验证码.gif"; // 定义每一张图片名字并设置后缀名
System.out.println("第" + i + "张验证码正在下载");
spiHel.download(url, s, "d:\\image\\VerificationCode\\");// 遍历网址并下载图片
System.out.println("==================");
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
2.主函数(程序运行入口)Main.java
package spider;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.SpinnerListModel;
import com.spider.web.model.*;
public class Main {
public static void main(String[] args) throws Exception {
SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
// spiHel.imgDownloadToHeavenWeb("http://www.ivsky.com/tupian/banshanbandao_v24024/");
// SpiderWeb spiWeb=new SpiderWeb();
// WebNode node=new WebNode("http://www.ivsky.com/");
// spiWeb.buildSpiderWebTwoLayer(node);
// 遍历测试
int n ;
System.out.println("0.输入0表示遍历天堂图片网");
System.out.println("1.输入1表示下载图片到D盘下image文件夹");
System.out.println("2.输入2表示下载验证码到D盘image文件夹下的子文件夹");
System.out.println("请输入0或者1或者2");
Scanner scan =new Scanner(System.in);
n=scan.nextInt();
switch (n) {
case 0: { // 遍历网站
int count = 0;
System.out.println(
"==========================================第一次遍历的网站=============================================");
String str[] = spiHel.htmlDivisionToHeavenOnly("http://www.ivsky.com/");// 开始下载该网址的图片
String str1[] = null;
System.out.println(
"==========================================第二次遍历的网站=============================================");
for (int i = 0; i < str.length; i++) {
System.out.println("==========================================第二层第" + i
+ "次遍历的网站=============================================");
str1 = spiHel.htmlDivisionToHeavenOnly(str[i]);
if (str1 != null && str1.length != 0) {
for (int j = 0; j < str1.length; j++) {
System.out.println("==========================================第三层第" + count++
+ "次读取网址=============================================");
if (!("".equals(str1[j]))) {
spiHel.htmlDivisionToHeavenOnly(str1[j]);
}
}
}
}
}
;
case 1: { // 下载图片
String str2[] = spiHel.htmlDivisionToHeavenWeb("http://www.ivsky.com/tupian/chengshilvyou/");// 开始下载该网址的图片
if (str2 != null) { // 循环下载图片
for (int i = 0; i < str2.length; i++) {
if (!("".equals(str2[i]))) {
spiHel.imgDownloadToHeavenWeb(str2[i]);
}
}
}
}
break;
case 2: { // 下载验证码
spiHel.imgDownloadToanoramaWeb("http://www.quanjing.com/createImg.aspx", 200);// 下载验证码
}
break;
case 3: {
}
break;
default:
break;
}
}
}
3.爬虫遍历算法没写完,后面再上传
4.源代码下载地址如下
Spider.rar链接:http://pan.baidu.com/s/1kVge1KF 密码:syua
Spider.exe链接(运行即可看到效果):
链接:http://pan.baidu.com/s/1pLHjVWf 密码:amxu