使用java爬虫爬取网站前台代码(html+css+js+img)

使用java爬虫爬取网站前台代码(html+css+js+img)

一、爬虫

1、什么是爬虫
爬虫主要针对与网络网页,又称网络爬虫、网络蜘蛛,可以自动化浏览网络中的信息,或者说是一种网络机器人。它们被广泛用于互联网搜索引擎或其他类似网站,以获取或更新这些网站的内容和检索方式。它们可以自动采集所有其能够访问到的页面内容,以便程序做下一步的处理。
2、为什么我们要爬取数据
在大数据时代,我们要获取更多数据,就要进行数据的挖掘、分析、筛选,比如当我们做一个项目的时候,需要大量真实的数据的时候,就需要去某些网站进行爬取,有些网站的数据爬取后保存到数据库还不能够直接使用,需要进行清洗、过滤后才能使用,我们知道有些数据是非常珍贵的。

二、Jsoup

1、什么是Jsoup
jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操作方法来取出和操作数据。该版本包含一个支持 HTML5 的解析器分支,可确保跟现在的浏览器一样解析 HTML 的方法,同时降低了解析的时间和内存的占用。
2、Jsoup主要功能
2_1、从一个URL,文件或字符串中解析HTML;
2_2、使用DOM或CSS选择器来查找、取出数据;
2_3、可操作HTML元素、属性、文本
详细介绍参考:https://www.cnblogs.com/zhangyinhua/p/8037599.html

三、创建项目
1、pom文件

 <dependencies>
        <dependency>
            <groupId>com.googlecode.juniversalchardet</groupId>
            <artifactId>juniversalchardet</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.kie.modules</groupId>
            <artifactId>org-apache-commons-httpclient</artifactId>
            <version>6.2.0.CR2</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.0.2</version>
        </dependency>
    </dependencies>

2、以正版中国网站为例,首先我们先获取页面

public class RequestAndResponseTool {


    public static Page  sendRequstAndGetResponse(String url) {
        Page page = null;
        // 1.生成 HttpClinet 对象并设置参数
        HttpClient httpClient = new HttpClient();
        // 设置 HTTP 连接超时 5s
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        // 2.生成 GetMethod 对象并设置参数
        GetMethod getMethod = new GetMethod(url);
        // 设置 get 请求超时 5s
        getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
        // 设置请求重试处理
        getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
        // 3.执行 HTTP GET 请求
        try {
            int statusCode = httpClient.executeMethod(getMethod);
        // 判断访问的状态码
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + getMethod.getStatusLine());
            }
        // 4.处理 HTTP 响应内容
            byte[] responseBody = getMethod.getResponseBody();// 读取为字节 数组
            String contentType = getMethod.getResponseHeader("Content-Type").getValue(); // 得到当前返回类型

            page = new Page(responseBody,url,contentType); //封装成为页面
        } catch (HttpException e) {
        // 发生致命的异常,可能是协议不对或者返回的内容有问题
            System.out.println("Please check your provided http address!");
            e.printStackTrace();
        } catch (IOException e) {
        // 发生网络异常
            e.printStackTrace();
        } finally {
        // 释放连接
            getMethod.releaseConnection();
        }
        return page;
    }
}

3、获取响应内容,放入page

public class Page {

    private byte[] content ;
    private String html ;  //网页源码字符串
    private Document doc  ;//网页Dom文档
    private String charset ;//字符编码
    private String url ;//url路径
    private String contentType ;// 内容类型


    public Page(byte[] content , String url , String contentType){
        this.content = content ;
        this.url = url ;
        this.contentType = contentType ;
    }

    public String getCharset() {
        return charset;
    }
    public String getUrl(){return url ;}
    public String getContentType(){ return contentType ;}
    public byte[] getContent(){ return content ;}

    public void setContent(byte[] content) {
        this.content = content;
    }

    /**
     * 返回网页的源码字符串
     *
     * @return 网页的源码字符串
     */
    public String getHtml() {
        if (html != null) {
            return html;
        }
        if (content == null) {
            return null;
        }
        if(charset==null){
            charset = CharsetDetector.guessEncoding(content); // 根据内容来猜测 字符编码
        }
        try {
            this.html = new String(content, charset);
            return html;
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /*
    *  得到文档
    * */
    public Document getDoc(){
        if (doc != null) {
            return doc;
        }
        try {
            this.doc = Jsoup.parse(getHtml(), url);
            return doc;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }


}

4、储存爬取的网页文本数据,FileTool

public class FileTool {

    private static String dirPath;


    /**
     * getMethod.getResponseHeader("Content-Type").getValue()
     * 根据 URL 和网页类型生成需要保存的网页的文件名,去除 URL 中的非文件名字符
     */
    private static String getFileNameByUrl(String url, String contentType) {
        //去除 http://

        //text/html 类型
        if (contentType.indexOf("html") != -1) {
           url = url.replaceAll("[\\?/:*|<>\"]", "_") + ".html";
           return url;
        }else{
            int i = url.lastIndexOf("/");
            url = url.substring(i+1,url.length());
            return url;
        }
    }

    /*
    *  生成目录
    * */
    private static void mkdir() {
        if (dirPath == null) {
            dirPath = Class.class.getClass().getResource("/").getPath() + "temp\\";
        }
        File fileDir = new File(dirPath);
        if (!fileDir.exists()) {
            fileDir.mkdir();
        }
    }

    /**
     * 保存网页字节数组到本地文件,filePath 为要保存的文件的相对地址
     */

    public static void saveToLocal(Page page) {
        mkdir();
        String fileName = getFileNameByUrl(page.getUrl(), page.getContentType()) ;

        String filePath = dirPath + fileName ;
        byte[] data = page.getContent();
        try {

            DataOutputStream out = new DataOutputStream(new FileOutputStream(new File(filePath)));
            for (int i = 0; i < data.length; i++) {
                out.write(data[i]);
            }
            out.flush();
            out.close();
            System.out.println("文件:"+ fileName + "已经被存储在"+ filePath  );
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

5、主方法,配置网站路径和css,js,img的路径过滤,配置爬取文件存储地址,并获取

public class MyCrawler {

    /**
     * 使用种子初始化 URL 队列
     *
     * @param seeds 种子 URL
     * @return
     */
    private void initCrawlerWithSeeds(String[] seeds) {
        for (int i = 0; i < seeds.length; i++){
            Links.addUnvisitedUrlQueue(seeds[i]);
        }
    }


    /**
     * 抓取过程
     *
     * @param seeds
     * @return
     */
    public void crawling2(String[] seeds) {

        //初始化 URL 队列
        initCrawlerWithSeeds(seeds);

        //定义过滤器,提取以 http://www.baidu.com 开头的链接
        LinkFilter filter = new LinkFilter() {
            public boolean accept(String url) {
                if (url.startsWith("https://getitfree.cn/")) {
                    return true;
                } else {
                    return false;
                }
            }
        };
        URL url;
        int responsecode;
        HttpURLConnection urlConnection;
        BufferedReader reader;
        String line;
        String filePath="F:\\IDEAProject\\crawl\\crawl\\target\\classes\\temp\\index.html";

        //循环条件:待抓取的链接不空且抓取的网页不多于 1000
        while (!Links.unVisitedUrlQueueIsEmpty()  && Links.getVisitedUrlNum() <= 1000) {

            //先从待访问的序列中取出第一个;
            String visitUrl = (String) Links.removeHeadOfUnVisitedUrlQueue();
            if (visitUrl == null){
                continue;
            }
            //根据URL得到page;
            Page page = RequestAndResponseTool.sendRequstAndGetResponse(visitUrl);
            Elements es = PageParserTool.select(page,"img");
            Iterator iterator  = es.iterator();
            while(iterator.hasNext()) {
                Element element = (Element) iterator.next();
                if (element.hasAttr("href")) {
                } else if (element.hasAttr("src")) {
                    String src = element.attr("src");
                    if (src.indexOf("?")!=-1){
                        continue;
                    }
                    src = src.substring(src.lastIndexOf("/") + 1);
                    element.attr("src", src);
                }
            }
            es =PageParserTool.select(page,"link");
            iterator  = es.iterator();
            while(iterator.hasNext()) {
                Element element = (Element) iterator.next();
                if (element.hasAttr("href")) {
                    String href = element.attr("href");
                    if (href.indexOf("?")!=-1){
                        continue;
                    }
                    href = href.substring(href.lastIndexOf("/") + 1);
                    element.attr("href", href);
                } else if (element.hasAttr("src")) {
                    String src = element.attr("src");
                    src = src.substring(src.lastIndexOf("/") + 1);
                    element.attr("src", src);
                }
            }
            es =PageParserTool.select(page,"script");
            iterator  = es.iterator();
            while(iterator.hasNext()) {
                Element element = (Element) iterator.next();
                if (element.hasAttr("href")) {
                    String href = element.attr("href");
                    //System.out.println("src:" + src);
                    href = href.substring(href.lastIndexOf("/") + 1);
                    element.attr("href", href);
                } else if (element.hasAttr("src")) {
                    String src = element.attr("src");
                    //System.out.println("src:" + src);
                    if (src.indexOf("?")!=-1){
                        continue;
                    }
                    src = src.substring(src.lastIndexOf("/") + 1);
                    element.attr("src", src);
                }
            }
            try {
                File file = new File(filePath);
                PrintStream ps = new PrintStream(new FileOutputStream(file));
                ps.append(page.getDoc().toString());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    public void crawling(String[] seeds) {

        //初始化 URL 队列
        initCrawlerWithSeeds(seeds);

        //定义过滤器,提取以 http://www.baidu.com 开头的链接
        LinkFilter filter = new LinkFilter() {
            public boolean accept(String url) {
                if (url.startsWith("https://getitfree.cn/")) {
                    return true;
                } else {
                    return false;
                }
            }
        };

        //循环条件:待抓取的链接不空且抓取的网页不多于 1000
        while (!Links.unVisitedUrlQueueIsEmpty()  && Links.getVisitedUrlNum() <= 1000) {

            //先从待访问的序列中取出第一个;
            String visitUrl = (String) Links.removeHeadOfUnVisitedUrlQueue();
            if (visitUrl == null){
                continue;
            }

            //根据URL得到page;
            Page page = RequestAndResponseTool.sendRequstAndGetResponse(visitUrl);


            //将保存文件
            FileTool.saveToLocal(page);

            //将已经访问过的链接放入已访问的链接中;
            Links.addVisitedUrlSet(visitUrl);

            //得到超链接
            Set<String> links = PageParserTool.getLinks(page,"img");
            for (String link : links) {
                Links.addUnvisitedUrlQueue(link);
                System.out.println("新增爬取路径: " + link);
            }
            links = PageParserTool.getLinks(page,"script");
            for (String link : links) {
                Links.addUnvisitedUrlQueue(link);
                System.out.println("新增爬取路径: " + link);
            }
            links = PageParserTool.getLinks(page,"link");
            for (String link : links) {
                Links.addUnvisitedUrlQueue(link);
                System.out.println("新增爬取路径: " + link);
            }

        }
    }
    //main 方法入口
    public static void main(String[] args) {
        MyCrawler crawler = new MyCrawler();
        crawler.crawling2(new String[]{"https://getitfree.cn/"});
        crawler.crawling(new String[]{"https://getitfree.cn/"});
    }
}

四、爬取结果和dome源码等
1、结果
在这里插入图片描述
在这里插入图片描述
2、该博客只有部分代码,如果需要dome源码,自取

链接:https://pan.baidu.com/s/1THFARMlsbY_s51-LYWZZGw
提取码:nezg

3、路还很长,乘风破浪,各位加油!!!!

发布了13 篇原创文章 · 获赞 48 · 访问量 4300

猜你喜欢

转载自blog.csdn.net/weixin_44209403/article/details/103170308