前言:前几天刚跑完2020男子半程马拉松,对于我一个跑渣来说能够跑完全程已经是善莫大焉了,跑完我累的不要不要的,不是这里痛就是那里痛,还是练少了,平常训练量不够,勉勉强强就上了。
跑的时候不知不觉被偷拍了,后来了解到这个是有专门的人去拍的,会根据你的号码牌识别到你这个人,群里有人说在一个微信公众号里可以查,于是我迫不及待的去搜下我的照片,结果
既然是图片,总归有个后台访问的路径吧,于是我用电脑端的微信打开公众号,左上角的有个复制链接,然后再用谷歌浏览器打开,打开调试模式。
发现真的个后台地址,我尝试着打开链接,然后图片另存为,还真的拿到原图了,但是,一张的复制感觉太慢了,作为一个不入流的程序员的我来说,百度能解决一切问题,搜到了一个篇博客,在基础上稍微做下修改下。
我试着用java自带的 URLConnection 类去连接该网址,发现该网站是有做反爬虫处理的,爬取到是一些js文件,而不是包含图片的那个源码,于是我换个思路,不用网址去爬,直接从谷歌浏览器控制台复制html文本到本地文件,然后利用java的文件流读取,进行解析,过滤,然后再输出到本地。原理就是java流读取,流输出。接下来看我一是如何一步一步实现的。
一.复制html文本到本地
二.利用java 字节流读取,利用正则过滤<img>标签和src路径
利用流读取文件 的方法
public String getFileImage(String path) throws Exception {
File file = new File(path);
InputStream inputStream = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(inputStream);//流的包装
BufferedReader br = new BufferedReader(isr);
String line;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {//整行读取
sb.append(line, 0, line.length());//添加到StringBuffer中
sb.append('\n');//添加换行符
}
//关闭各种流,先声明的后关闭
br.close();
isr.close();
return sb.toString();
}
正则表达式过滤<img>标签的方法
public List getImg(String html) {
List list = new ArrayList();
String regex = "<img.*?>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
list.add(matcher.group());
}
return list;
}
正则表达式获取img标签src属性值
//获取ImageSrc地址
private List<String> getImageSrc(List<String> listimageurl) {
List<String> listImageSrc = new ArrayList<String>();
for (String image : listimageurl) {
Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);
while (matcher.find()) {
listImageSrc.add(matcher.group().substring(0, matcher.group().length() - 1));
}
}
return listImageSrc;
}
测试
String fileImage = getFileImage("C:\\Users\\Desktop\\imagefile.txt");
List img = getImg(fileImage);
List<String> imageSrc = getImageSrc(img);
System.out.println(imageSrc);
结果是个存放src地址的集合
到这一步就已经接近成功了
三.输出流,执行下载
方法
//下载图片
private void download(List<String> listImgSrc) {
try {
String path="D:\\malasongImage";
//开始时间
Date begindate = new Date();
for (String url : listImgSrc) {
//开始时间
Date begindate2 = new Date();
String imageName = url.substring(url.lastIndexOf("/") + 1, url.length());
URL uri = new URL(url);
InputStream in = uri.openStream();
File outFiledir=new File(path);
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy/MM/dd");
String date = dateFormat.format(new Date());
int out=1;
File image=new File(outFiledir.getAbsolutePath()+File.separator+imageName);
if (!outFiledir.exists()){
outFiledir.mkdir();
}
System.out.println(outFiledir.getAbsolutePath());
System.out.println("具体路径:"+image.getName());
FileOutputStream fo = new FileOutputStream(image);//文件输出流
byte[] buf = new byte[1024];
int length = 0;
System.out.println("开始下载:" + url);
while ((length = in.read(buf, 0, buf.length)) != -1) {
fo.write(buf, 0, length);
}
//关闭流
in.close();
fo.close();
System.out.println(imageName + "下载完成");
//结束时间
Date overdate2 = new Date();
double time = overdate2.getTime() - begindate2.getTime();
System.out.println("耗时:" + time / 1000 + "s");
}
Date overdate = new Date();
double time = overdate.getTime() - begindate.getTime();
System.out.println("总耗时:" + time / 1000 + "s");
} catch (Exception e) {
e.printStackTrace();
System.out.println("下载失败");
}
}
执行结果
String fileImage = getFileImage("C:\\Users\\Desktop\\imagefile.txt");
List img = getImg(fileImage);
List<String> imageSrc = getImageSrc(img);
System.out.println(imageSrc);
download(imageSrc);
大功告成,真香警告!
补充: 以上是针对反爬虫的网站,下面提供的方法可以爬取没有做反爬虫的网站上截取图片。
// 获取img标签正则
private static final String IMGURL_REG = "<img.*?>";
// 获取src路径的正则
private static final String IMGSRC_REG = "[a-zA-z]+://[^\\s]*";
//获取HTML内容
private String getHtml(String url) throws Exception {
URL url1 = new URL(url);//使用java.net.URL
URLConnection connection = url1.openConnection();//打开链接
InputStream in = connection.getInputStream();//获取输入流
InputStreamReader isr = new InputStreamReader(in);//流的包装
BufferedReader br = new BufferedReader(isr);
String line;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {//整行读取
sb.append(line, 0, line.length());//添加到StringBuffer中
sb.append('\n');//添加换行符
}
//关闭各种流,先声明的后关闭
br.close();
isr.close();
in.close();
return sb.toString();
}
//获取ImageUrl地址
private 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地址
private List<String> getImageSrc(List<String> listimageurl) {
List<String> listImageSrc = new ArrayList<String>();
for (String image : listimageurl) {
Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);
while (matcher.find()) {
listImageSrc.add(matcher.group().substring(0, matcher.group().length() - 1));
}
}
return listImageSrc;
}