java实现专门爬取网页图片的软件

发现我的不足:
1、对awt和swing的使用十分的差劲,时不时就要查一下博客。。。

可以做一个专门爬取网页图片的软件,功能已经实现了,就UI对应的设计一下就好了。
做完了。。虽然有很大的局限,但是功能和界面是有的

Main.java

package crawling.app;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main
{

	//写一个界面
	JFrame frame = new JFrame("图片爬取器");
	JLabel pathlabel = new JLabel("当前保存路径:.");
	JLabel show = new JLabel();
	public static void main(String[] args) throws Exception
	{
		//先把功能写出来。然后在写GUI,这样清晰的多,也容易做
		//以豆瓣的电影排行榜为例
		//我打算先把对应网页直接整个爬下来。存入文本
		//然后在在本地进行正则分析,存入excel和JDBC
		
		/*
		//创建一个Crawling对象
		Crawling craw = new Crawling("https://movie.douban.com/chart");
		craw.getContent("E:\\java\\practice\\seven\\Java爬虫练习\\豆瓣电影排行榜网页源代码.txt");

		//我需要电影封面的url、电影名称、上映年份、演员表、评分、评价人数
		craw.analysis();//爬取图片url
		*/
		Main main = new Main();
		main.init();
		
 	}
	public void init()
	{

		
		frame.setSize(800,600);

		JPanel panel = new JPanel();//用来放网址提示和输入框
		JLabel label = new JLabel("网址:");
		panel.add(label);
		JTextField web = new JTextField(40);
		panel.add(web);
		frame.add(panel, BorderLayout.NORTH);


		JPanel panel2 = new JPanel();
		JButton crawBn = new JButton("开始爬取");
		JButton selectPathBn = new JButton("选择位置");
		panel2.add(selectPathBn);
		panel2.add(crawBn);
		frame.add(panel2,BorderLayout.SOUTH);

		JPanel  panel3 = new JPanel(new BorderLayout());
		
		panel3.add(pathlabel,BorderLayout.NORTH);
		panel3.add(show,BorderLayout.CENTER);
		frame.add(panel3,BorderLayout.CENTER);

		JFileChooser chooser = new JFileChooser(".");
		chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		Action selectFile = new AbstractAction()
		{
			public void actionPerformed(ActionEvent e)
			{
				int result = chooser.showOpenDialog(new JFileChooser("."));
				if(result == JFileChooser.APPROVE_OPTION)
				{
					String name = chooser.getSelectedFile().getPath();
					pathlabel.setText("当前路径:"+name);
				}
			}
		};
		selectPathBn.addActionListener(selectFile);

		Action crawling = new AbstractAction()
		{
			public String url;
			public void actionPerformed(ActionEvent e)
			{
				new Thread(() -> {
					url =  web.getText();//用户输入的网址
					CrawPictures craw = new CrawPictures(url,show);
					craw.analysis(pathlabel.getText().split(":")[1]+"\\");
				}).start();
			}
		};
		
		crawBn.addActionListener(crawling);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);

	}

	
}

CrawPictures.java

package crawling.app;
import java.net.*;
import java.util.*;
import java.io.*;
import java.util.regex.*;
import org.apache.poi.hssf.usermodel.*;
import javax.swing.*;
public class CrawPictures
{
	/**
	* 网站的网址
	*/
	private String web;
	/**
	* URL
	*/
	private URL url;
	/**
	* URL与网站连接
	*/
	private URLConnection conn;

	/**
	* 网页源代码
	*/
	private String sourcecode;

	
	/**
	* 传递过来一个对象
	*/
	private JLabel show;

	/**
	* Crawling的构造器
	* @param web 网站的网址
	*/
	public CrawPictures(String web, JLabel show)
	{
		this.web = web;
		this.show = show;
		try
		{
			url = new URL(web);
			conn = url.openConnection();
			//设置请求头,伪装成浏览器
			conn.setRequestProperty("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64)"+
				" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36");
			conn.connect();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		//System.out.println("这里是Crawling的构造器");
	}	
	//实例初始化块 ,实例初始化块比构造器更早执行。。。
	{
		//System.out.println("这里是Crawling的实例初始化块");
	}
	/**
	* 获取网页源代码,直接下载到本地的指定路径里面
	* @param path 本地路径,保存网页源代码
	* @return 同时将网页源代码以文本形式返回
	*/
	private String getContent(String path)
	{
		//打算采用字符流
		String msg = "";
		try(
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
			PrintStream ps = new PrintStream(new File(path))
		)
		{
			String line = null;
			int count = 0;
			while((line = br.readLine())!=null)
			{
				
				msg+=line;
				ps.println(line);
				count++;
				/*
				try{
					Thread.sleep(1000);
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
				*/
				System.out.println("已下载:"+count+"行");
				show.setText("已下载:"+count+"行");
				
			}
			System.out.println("爬取网页源代码完成!");
			show.setText("爬取网页源代码完成!");

		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
		sourcecode = msg;
		return msg;
	}
	/**
	* 通过用户输入的一段内容进行分析,然后生成对应的正则表达式<br>
	* 1、 用户输入的用例那里替换成(.*?) 先试一下
	* 2、所有\s匹配的地方,替换成\\s*
	* 3、
	*/

	/**
	* 分析网页源代码的方法,取出我所需要的字段,将他们放在ArrayList中
	*/
	public void analysis(String path)
	{
		//先把网页源代码爬下来
		getContent(path+"网页源代码.txt");
		
		//存储爬取图片链接用的ArrayList<String>
		ArrayList<String> pictures = new ArrayList<>();
		//电影的封面url
		String pic_regex = "<img src=\"(https:.*?\\.jpg)\".*?/>";
		getDataById(pic_regex,pictures);//提取出图片的url
		//下载电影封面
		getPicture(pictures,path);
		
	}
	/**
	* 这是一个用正则表达式提取数据的方法,方便复用,只需要传入正则表达式的模式,和存储用的ArrayList<String>
	* @param regex 匹配用的正则表达式
	* @param list 存储数据用的ArrayList<String>
	*/
	private void getDataById(String regex,ArrayList<String> list)
	{
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(sourcecode);
		int i = 0;
		//第一种方式,一个字段一个字段来
		while(m.find())
		{
			int groupCount = m.groupCount();
			String elements = "";
			for( int j = 0; j < groupCount;j++)
			{
				String element = m.group(j+1);//获取匹配对象
				if(j==groupCount-1)
				{
					elements+= element;
				}
				else
				{
					elements += element+":";
				}
			}
				
			list.add(elements);//存入ArrayList<String>中
			i++;
			System.out.println("正在爬取第"+i+"个,请稍等..."+elements);
			show.setText("正在爬取第"+i+"个,请稍等..."+elements);
			
		}
		System.out.println("所有元素爬取完成,共"+i+"个");
		show.setText("所有元素爬取完成,共"+i+"个");
		//另一种方式pattern中是一大串,用group(1),group(2)这样来爬取。
		
	}
	

	/**
	* 根据封面url爬取图片
	* @param pictures 存储图片url的ArrayList<String>
	*/
	private void getPicture(ArrayList<String> pictures,String savepath)
	{
		int i;
		for(i = 0 ; i < pictures.size(); i++)
		{
			
			try{
				String path = pictures.get(i);
				String name = path.split("/")[path.split("/").length-1];
				System.out.println("正在下载第"+(i+1)+"张图片,请稍等..."+name);
				show.setText("正在下载第"+(i+1)+"张图片,请稍等..."+name);
				URL url = new URL(path);
				URLConnection conn = url.openConnection();
				conn.setRequestProperty("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64)"+
				" AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36");
				conn.connect();
				//字节流
				InputStream input = conn.getInputStream();
				byte[] buffer = new byte[1024];
				int hasRead = -1;
				RandomAccessFile raf = new RandomAccessFile(savepath+name,"rw");
				while((hasRead = input.read(buffer)) != -1)
				{
					raf.write(buffer,0,hasRead);
				}
				input.close();
				raf.close();
				
				
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
			
		}
		System.out.println("图片下载完成,共"+i+"张");
		show.setText("图片下载完成,共"+i+"张");
	}


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

细水长流cpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值