java爬取网络资源实战

说到爬虫,第一个想到的编程语言大都是Python,的确,在爬取网络资源方面,Python确实有着巨大的优势,但是在爬取一些小的资源,比如说一个视频、音频、图片等比较单一的资源的时候,java也是完全可以胜任的,下面我就来介绍一下使用java基础来爬取一些网络资源。

在java.net包下封装了很多关于网络方面的类,他们使用的技术是比较成熟的,他屏蔽了嶙峋的网络连接方面的操作,提供给开发人员一个比较友好的开发接口。java.net包中有一个功能强大的类URL,他代表的就资源地址,通过他可以得到一个输入流对象,从而将资源下载到内存或磁盘中。

我们可以通过URL url = new URL(strURL);获取一个URL对象,再根据InputStream is = url.openStream();获取一个输入流对象。我们只需要这两个简单的操作,就能下载网络上的很多资源了。下面是我自己实现一个java爬虫的例子。

首先我们找到一个素材源网站,这里我找到的是一个音频素材网https://www.huiyi8.com/yinxiao/

至于为什么要爬取音频素材,以后有机会在给大家介绍。

按下F12,打开调试界面(推荐大家使用Google、Firefox浏览器),找到media,看资源的URL。这就是我们构造URL对象时用的字符串。

这个是通过手动找到的,这样只能一个一个的爬取,速度太慢。如果我们想要找到这个网页里所有的音频文件的URL,打开网站的源代码Ctrl+U。

我们会得到这样的源代码,这个也是该资源的文本表示。我们可以通过先获得该资源的源码,再通过解析其中mp3格式的字符串,就能得到对应的资源文件,通过下面的文件名称能够得到文件的名字。我们将一个网页的所有的mp3资源存到一个map集合中,用资源地址和文件名称表示key和value。

然后我们再根据URL,通过map获取这些资源的地址以及文件名,就能够以文件的形式保存到本地了。

 

以下是我的代码:

package python;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo03python extends Thread{

    public static int threadCount;
    private int page;//表示下载多少页
    private int folder;//表示多少套
    
    public static int getThreadCount() {
        return threadCount;
    }
    
    public static void addThreadCount() {
        threadCount++;
    }
    public static void lessenThreadCount() {
        threadCount--;
    }
    
    
    public Demo03python(int page) {
        super();
        this.page = page;
        this.folder = (page/100)+1;
    }

    public Demo03python() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Demo03python(Runnable target, String name) {
        super(target, name);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(Runnable target) {
        super(target);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(ThreadGroup group, Runnable target, String name, long stackSize) {
        super(group, target, name, stackSize);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(ThreadGroup group, Runnable target, String name) {
        super(group, target, name);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(ThreadGroup group, Runnable target) {
        super(group, target);
        // TODO Auto-generated constructor stub
    }

    public Demo03python(ThreadGroup group, String name) {
        super(group, name);
    }


    @Override
    public void run() {
        super.run();
        addThreadCount();
        System.out.println("当前下载线程数:"+threadCount);
        System.out.println("第"+page+"页开启线程开始下载");
        String pageUrl = "https://www.huiyi8.com/yinxiao/"+page+".html";
        Map<String, String> map = analysis(pageUrl);
        //先为每一页都创建一个文件夹,每个网页下载的内容都放到这个文件夹中
        String folderName = "第"+folder+"套//"+"第"+page+"页";
        File folder = new File(folderName);
        folder.mkdirs();
        //遍历map集合
        Set<Entry<String, String>> entrySet = map.entrySet();
        Iterator<Entry<String, String>> iterator = entrySet.iterator();
        while(iterator.hasNext()) {
            Entry<String, String> next = iterator.next();
            //key是资源地址,value是文件名称
            String key = next.getKey();
            String value = next.getValue();
            download(key,folderName+"//"+value);
        }
        lessenThreadCount();
        System.out.println("当前下载线程数:"+threadCount);
    }
    
    

    //使用一个解析的方法,可以将得到的HTML文件解析成一个map集合
    //map集合中包含了key(文件名file)和value(音频的urlStr)
    public static Map<String,String> analysis(String pageUrl){
        
        Map<String,String> map = new HashMap<String,String>();
        try {
            URL url = new URL(pageUrl);
            InputStream is = url.openStream();
            Scanner sc = new Scanner(is,"utf-8");
            int l = 0;
            String key = null;
            String value = null;
            while(sc.hasNext()) {

//                mp3的文件是这样的:thumb="urlStr"            得到urlStr
//                文件名是这样的:target="_blank">file</a>        得到file
                String thumb = ".*thumb.*";
                String target = ".*<div.*html\" target=\"_blank\">.*</a>.*";
                String result = sc.nextLine();
                //如果包含了thumb或者包含了target的话,就打印出来字符串
                
                if(Pattern.matches(thumb, result)||Pattern.matches(target, result)) {
//                    System.out.println(result);
                    l++;
                }
                //匹配mp3文件资源
                if(Pattern.matches(thumb, result)) {
                    Pattern pattern = Pattern.compile("http.*mp3" );
                    Matcher matcher = pattern.matcher(result);
                    if(matcher.find()) {
                        String group = matcher.group(0);
                        key = group;
                    }else {
                        key = result;
                    }
                }
                //匹配文件名
                if(Pattern.matches(target, result)) {

                    Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
                    Matcher matcher = pattern.matcher(result);
                    if(matcher.find()) {
                        String group = matcher.group(0);
                        value = group+".mp3";
                    }else {
                        value = result;
                    }
                    map.put(key, value);
                }
                
            }
            System.out.println(l);
            sc.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("IO流打开失败。");
            e.printStackTrace();
        }
        
        
        
        return map;
    }
    
    
    
    //一个方法,传入路径,下载文件到本地
    public static void download(String urlStr,String file) {
        InputStream is = null;
        OutputStream os = null;
        try {
            URL url = new URL(urlStr);
            is = url.openStream();
            os = new FileOutputStream(file);
            int t;
            while((t = is.read())!=-1) {
                os.write(t);
            }
            System.out.println("文件"+file+"下载成功!");
        } catch (Exception e) {
            System.out.println("文件"+file+"下载失败!");
        }finally {
            try {
                if(is!=null)
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os!=null)
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
}

 

 

 

 

 

package python;
public class Demo04python {
    public static void main(String[] args) {
        
        for(int i = 544;i<=1920;i++) {
            Demo03python t = new Demo03python(i);
            t.start();
        }
        
        
    }

}

 

在测试的时候我通过一个多线程执行下载的,在网络上进行操作的时候一般都是用的是多线程的方式,大大加快程序速度外还能避免某个资源阻塞导致程序停滞不前。

最后得到的文件目录

具体思路就是这样,我通过这样的一个方法爬取了该网站的四万多个音频文件,一共16G+,大家可以自己试试,或者看看我下的资源。https://download.csdn.net/download/qq_41803278/12201496

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值