前几天灵机一动想学学如何从网站上爬取表情包,我想到了之前看到过的jsoup(没用python是因为不会,目前刚刚找到工作,学习安排是先稳固java,之后在学python,所以就用了java的jsoup)。当然这个使用起来很简单,代码写得也很烂。
最开始写的时候是把爬到的图片保存在本地,但是为了学到更多,今天就使用了阿里云的oss(对象存储)来保存图片。总的来说是很简单的,这相当于一个入门。话不多说,下面就记录一下笔记:
Jsoup解析网页拿到图片
- 首先找到一个特定的网站(小人不才,找了个粗暴方法,哎,我就爬你一个,因为简单哈哈哈)
- 程序员传统艺能,按下F12,找到包裹这些图片的容器的class或者id值。
拿到class或者id之后就可以在程序中解析出来,下面上代码: - 首先使用Jsoup将网页html解析为java可操作的文档
//url这样写是因为这个网站图片是分页的,
//我每次要拿100张图片
//网站每一页大概50张左右,所以要拿好几页图片
//页数改变url也会变,所以就循环这样取
//keyword为搜索的关键字,这里是---生气
String url = "https://www.fabiaoqing.com/search/bqb/keyword/"+keyword+"/type/bqb/page/" + pagenum + ".html";
Document html = Jsoup.parse(new URL(url), 10000);
- 接下来用刚刚看到的class或者id获取到dom元素(该网站用的class)
Elements contents = html.getElementsByClass("bqppdiv");
- 遍历contens,获取img标签,通过img标签再拿到它的src值既是我们想要的东西
for (Element content : contents) {
Elements img = content.getElementsByTag("img").eq(0);
String src = img.attr("data-original");
ok,以上我们就拿到了图片的地址了,梳理一下:
完整代码:(图片保存到本地版)
public class GetImageUtil {
public static String getImage(String keyword,int id,int pagenum) throws IOException {
String url = "https://www.fabiaoqing.com/search/bqb/keyword/"+keyword+"/type/bqb/page/" + pagenum + ".html";
Document html = Jsoup.parse(new URL(url), 10000);
Elements contents = html.getElementsByClass("bqppdiv");
for (Element content : contents) {
Elements img = content.getElementsByTag("img").eq(0);
String src = img.attr("data-original");
//System.out.println(img);
if (src == null) continue;
URL target = new URL(src);
URLConnection urlConnection = target.openConnection();
InputStream inputStream = urlConnection.getInputStream();
File file=new File("D:\\pics\\"+keyword);
if (id == 101) return "完成";
//文件夹不存在就创建一个
if(!file.exists()){
file.mkdir();
}
OutputStream outputStream = new FileOutputStream(file);
int bt = 0;
while ((bt = inputStream.read()) != -1) {
outputStream.write(bt);
}
System.out.println("第" + id + "张图片下载完毕!");
id++;
inputStream.close();
outputStream.close();
}
if(id<101){
getImage(keyword,id,++pagenum);
//test(id,pagenum);
}
return "ok";
}
}
我的总结就是:
- 创建oss操作对象
//几个必要参数可参考上面链接就不一一叙述了
public static OSS oss = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
- 我使用的是流上传,这里就要创建输入流。本地文件的话就直接new File(要上传的文件地址)
//src即为图片地址
InputStream inputStream = new URL(src).openStream();
3.上传
//参数1->要上传到的bucket
//参数2->要保存到那里(该路劲包含了图片名,比如:a/b/c.jpg,我这里直接放到根目录)
//参数3->输入流
oss.putObject(bucketName,id+keyword+".jpg",inputStream);
- 关闭
oss.shutdown();
最后,完整代码-------------->是不是很简单?
@Component
public class GetImageOssUtil {
public static String endpoint = "oss-cn-chengdu.aliyuncs.com";
public static String bucketName = "bqb1";
public static String accessKeyId = "LTAI5tB18nBPjAGt5aG1Q8Lc";
public static String accessKeySecret = "5lnA8YBkyVHe1Ta3hrhXMXR9BJgGOX";
public static OSS oss = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
public static String getImage(String keyword,int id,int pagenum) throws IOException {
String url = "https://www.fabiaoqing.com/search/bqb/keyword/"+keyword+"/type/bqb/page/" + pagenum + ".html";
//解析网页,得到document对象
Document html = Jsoup.parse(new URL(url), 10000);
//通过类选择器名获取到dom对象组
Elements contents = html.getElementsByClass("bqppdiv");
//遍历每一个dom对象,拿到img标签,再获取图片地址
for (Element content : contents) {
//拿到img标签
Elements img = content.getElementsByTag("img").eq(0);
//拿到图片地址
String src = img.attr("data-original");
if (src == null) continue;
//创建输入流
InputStream inputStream = new URL(src).openStream();
if (id == 101) return "完成";
//上传
oss.putObject(bucketName,id+keyword+".jpg",inputStream);
System.out.println("第" + id + "张图片下载完毕!");
id++;
//关闭输入流
inputStream.close();
}
if(id<101){
//图片不足100张,迭代该方法
getImage(keyword,id,++pagenum);
}
//关闭oss连接
oss.shutdown();
return "ok";
}
}
去阿里云看看(注意,oss.putObject()中图片保存地址中的图片名一定要写后缀哦,我开始没写.jpg,上传上去的东西是用不了的,文件也要加后缀,比如.txt)