爬虫获取图片,
第一步:获取网页源代码。
第二步:获取源代码里的图片URL(img标签的src属性值)
第三部:下载图片。
获取网页源代码需要一个工具:java selenium。它有两部分,一个是:驱动浏览器的插件,还有一个就是jar包
下载时注意浏览器所对应的驱动版本,把它存在某个目录里。驱动是一个.exe文件,谷歌浏览器的是:chromedriver.exe
jar包的依赖:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
整个爬虫的maven依赖:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.7.3</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
获取网页源代码:需要网页的URL
private String webDriverGetSourceHtml(String url){
//运行chromedriver.exe
System.setProperty("webdriver.chrome.driver", "D:\\Google\\webdriver\\chromedriver.exe");
//获取浏览器驱动驱动
WebDriver driver = new ChromeDriver();
System.out.println("【myReptile-1号】已被唤醒");
System.out.println("【myReptile-1号】的任务:从:"+url+"网页获取图片下载到:"+filePath);
//将浏览器窗口最大化
driver.manage().window().maximize();
//
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);//设置元素定位等待时间
// driver.manage().timeouts().pageLoadTimeout(10,TimeUnit.SECONDS);//设置页面加载等待时间
// driver.manage().timeouts().setScriptTimeout(10,TimeUnit.SECONDS);//设置脚本运行等待时间
//打开指定的网页
driver.get(url);
System.out.println("【myReptile-1号】开始工作···");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//让浏览器执行一个js脚本:将网页滚动条滑到最底(部分网页源代码需要滑动滚动条后才加载出来)
((JavascriptExecutor) driver).executeScript("window.scrollTo(0,document.body.scrollHeight)");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//获取网页源代码
String s = driver.getPageSource();
System.out.println("【myReptile-1号】已获取目标网页源代码");
return s;
}
获取图片地址:参数html为网页源代码,参数url与上个方法参数一样
private Set<String> getImgsrc(String html , String url){
//hashset相同的元素只算一个。有些网页的图片有大量重复的,避免图片地址重复
Set<String> list = new HashSet();
System.out.println("【myReptile-1号】正在收集图片地址···");
String img = "";
//用正则表达式获取源代码里的<img>标签代码
Pattern p_image;
Matcher m_image;
String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
m_image = p_image.matcher(html);
while (m_image.find()) {
// 得到<img />数据
img = m_image.group();
// 匹配<img>中的src数据
Matcher matcher = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
while (matcher.find()) {
String imgSrc = matcher.group(1);
if ((imgSrc!=null)) {
// imgSrc以"http://"或https开头,表示完整的图片URL地址
if((imgSrc.startsWith("http://") || imgSrc.startsWith("https://"))){
System.out.println("【myReptile-1号】直接获得图片地址:" + imgSrc);
list.add(imgSrc);
}else if(imgSrc.startsWith("//")){
// imgSrc以"//"开头,图片URL地址缺少协议,默认协议是http协议,把http补上
imgSrc="http:"+imgSrc;
System.out.println("【myReptile-1号】加协议获得图片地址:" + imgSrc);
list.add(imgSrc);
}else if(imgSrc.startsWith("/")){
// imgSrc以"/"开头,图片URL地址只有地址部分,缺少协议以及域名,把协议和域名补上。协议和域名在url里有
//例如百度里的某图片src为"/aaa/bbb.jpg",我们需要加上http://ww.baidu.com,让它变成"http://ww.baidu.com/aaa/bbb.jpg"
String pattern = "^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(url);
if(m.find()){
String s = m.group();
imgSrc=s+imgSrc;
System.out.println("【myReptile-1号】加域名("+s+")获得图片地址:" + imgSrc);
list.add(imgSrc);
}
}else {
}
}
else {
System.out.println("【myReptile-1号】获取失败的图片地址"+imgSrc);
}
}
}
System.out.println("【myReptile-1号】在:"+url+"获取了 ("+list.size()+") 个图片地址");
return list;
}
下载图片:参数imgList就是图片地址的集合。参数filePath为下载的图片存放的位置
private void downImages(Set<String> imgList , String filePath){
//创建文件的目录结构
System.out.println("【myReptile-1号】正在磁盘寻找文件夹( "+filePath+" )");
File files = new File(filePath);
if(!files.exists()){// 判断文件夹是否存在,如果不存在就创建一个文件夹
System.out.println("【myReptile-1号】找不到文件夹( "+filePath+" )");
System.out.println("【myReptile-1号】正在创建文件夹( "+filePath+" )");
files.mkdirs();
System.out.println("【myReptile-1号】创建文件夹( "+filePath+" )完毕");
}else {
System.out.println("【myReptile-1号】已经找到文件夹( "+filePath+" )");
}
int j = 1;
int t = 1;
//获取图片后缀名
Pattern p2 = Pattern.compile("((.png)|(.jpg)|(.gif)|(.bmp)|(.psd)|(.tiff)|(.tga)|(.eps))");
// 截取图片的名称
System.out.println("【myReptile-1号】开始盗图···");
for(String img : imgList){
try {
String fileSuffix = null;
Matcher m2 = p2.matcher(img);
if(m2.find()){
fileSuffix = m2.group();
}else {
//有些图片地址里没有图片后缀名,我们就直接加上一个后缀名
fileSuffix = ".jpg" ;
}
System.out.println("【myReptile-1号】开始抓捕第 ( "+j+" ) 张图片: "+img);
//创建URL类
URL url = new URL(img);
//获取URL连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置http请求头
connection.setRequestProperty("Charset", "utf-8");
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36");
//打开链接
connection.connect();
//创建字节输入流
InputStream in = connection.getInputStream();
// 创建文件
File file = new File(filePath+"\\"+System.currentTimeMillis()+fileSuffix);
//创建字节输出流
FileOutputStream out = new FileOutputStream(file);
int i = 0;
while((i = in.read()) != -1){
out.write(i);
}
in.close();
out.close();
System.out.println("抓捕成功");
j++;
t++;
} catch (Exception e) {
j++;
System.out.println("抓捕失败");
e.printStackTrace();
}
}
System.out.println("【myReptile-1号】总共获取"+imgList.size()+"张图片地址,实际抓捕"+(t-1)+"张图片");
System.out.println("请到( "+filePath+" )文件夹查看!");
}