大家好,今天我和大家分享一下用Java做爬虫爬取王者荣耀的英雄头像。
首先我们需要王者荣耀的网址,然后获取连接,通过IO读取网页的源代码,用正则表达式筛选我们需要的代码,在每个筛选对象(图片的地址)前面加上协议名https:再访问我们筛选的对象(图片),最后用多线程加IO下载到指定的本地目录中。
配置文件:hero.Proprety。写配置文件时注意转义字符
addressURL=https://pvp.qq.com/web201605/herolist.shtml yourPattern=//game\\.gtimg\\.cn/images/yxzj/img201606/heroimg/.+?\\.jpg yourDir=C:\\Users\\HP\\Desktop\\myhero charsetName=GBK protocol=https: spile=/
代码:这里我写了怎么读取配置文件。在获取连接后,我们要判断响应状态码是200才能进行后面的操作。在筛选网页代码时,我这里是通过readLine()每次读取一行来进行正则表达式的匹配的。我用/
截取的筛选的对象的最后一部分当作图片的名称。(如果想要获取英雄的名称,需要单独用一个方法来重新用正则表达式匹配英雄名称。)
public class Worm2 extends Thread { //要爬取的网站网址 private static String addressURL; //要爬取的内容的正则表达式 private static String yourPattern; //爬取后下载到的目录 private static String yourDir; //设置爬取的网页源代码的编码格式 private static String charsetName; //访问要爬取的内容的协议名 private static String protocol; //设置分隔符 private static String spile; //图片 private String img; public Worm2(String img) { this.img = img; } //读取配置文件hero.Proprety static { //读取属性文件为一个字节输入流 //try with(JDK7) try (InputStream is = Worm2.class.getResourceAsStream("/hero.Proprety")) { //创建属性类 Properties prop = new Properties(); //加载输入流 prop.load(is); //读取属性信息 addressURL = prop.getProperty("addressURL"); yourPattern = prop.getProperty("yourPattern"); yourDir = prop.getProperty("yourDir"); charsetName = prop.getProperty("charsetName"); protocol = prop.getProperty("protocol"); spile = prop.getProperty("spile"); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { System.out.println("开始下载:" + img); download(); System.out.println("下载完成:" + img); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { //根据提供URL地址构建一个URL对象 URL url = new URL(addressURL); //打开到此URL的链接,并获取HttpURLConnection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //对正则表达式编译获取匹配模式对象 Pattern p = Pattern.compile(yourPattern); //获取响应状态码 int code = conn.getResponseCode(); if (code == 200) { //获取该链接中的输入流对象 InputStream in = conn.getInputStream(); //将字节输入流转换为字符输入流 InputStreamReader isr = new InputStreamReader(in, charsetName); //将字符输入流包装为缓冲流 BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { //获取匹配器 Matcher m = p.matcher(line); //检索 while (m.find()) { //获取一组匹配文本 String imgPath = m.group(); //启动下载线程 new Worm2(imgPath).start(); } } //关闭缓冲流 br.close(); } } private void download() throws IOException { //根据提供URL地址构建一个URL对象 URL imgURL = new URL(protocol + img); //获取图片地址最后一个"/"出现的位置 int index = img.lastIndexOf(spile); //获取文件名 String imgName = img.substring(index + 1); //获取目标文件的输出流 OutputStream os = new FileOutputStream(new File(yourDir, imgName)); //打开到图片地址的输入流 HttpURLConnection conn = (HttpURLConnection) imgURL.openConnection(); if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { //服务端响应成功之后获取输入流 InputStream in = conn.getInputStream(); byte[] b = new byte[1024 * 1024]; int len = 0; while ((len = in.read(b)) != -1) { os.write(b, 0, len); } //关闭流 os.close(); in.close(); } } }
大家也可以不用配置文件,把上面的内容直接写到下面代码中也行。