简易Java爬虫制作

一、文章来由

本来最近任务挺多,但是今天想放松一下,正巧Bill喜欢玩英语配音,而配音都是在配音软件的云上,我想把那些都拿到,于是就写一了一个爬虫,接着就有了这篇爬虫教程~~

二、爬虫!!爬虫!!

首先要搞清什么叫爬虫~~

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

当然Java本身应该不算是脚本语言(一个脚本通常是解释运行而非编译,Java是不是解释型语言现在还存在争议),但是做这么高级的事情,确实有点像脚本。

那为什么叫简易爬虫呢,因为是直接用 BufferedReader 读 URL 中的 HTML ,然后用正则表达式去匹配是不是我要的网页。这种简易爬虫,只能用在页面没有特殊限制或者反爬虫机制的地方,如果页面有登陆验证或者是异步等反爬虫,通过这个URL 是不可能一次拿到真实地址的(一般会错误被导到另外一个页面)

通常,爬虫需要一个种子页面,是一个源 URL 地址,通过这个一层层爬下去

Bill 以前用过 httpclient 的 jar 包做过稍微复杂一点的爬虫,这个 jar 包可以把 HTML 用自己的数据结构存起来,形成一棵树结构(HTML 本身就是一种树结构的标记语言),然后提供各种过滤方法,可以找到你要的特定信息。

当然还有各种爬虫框架、模拟用户输入的包,可以完成更高难度的操作,绕过诸如淘宝这类有反爬虫技术的网站,这个大家有兴趣再去研究。

三、虫子制作过程

我提供了源码下载(当然是免金币的~~),所以,在文章中就不复制所有源代码了,只把关键代码、主要思想和关键函数讲一讲。

爬下静态网页的代码,可以很明显看到,只是直接用 BufferedReader 获取 URL 中的 HTML,而这些基本的函数和类,在Java标准类库中都有,不用额外导包。

爬虫的种子地址当然是 bill 希望去爬的趣配音web页面地址,我希望得到这些web页面里面,是我配音的、真实MP4地址~~

代码中我是用 url = “http://video.qupeiyin.cn/index.php?m=home&c=show&a=share&id=4102907“; 开始爬的~~

而且爬虫通常必须用多线程,不用多线程,想想有400w+个页面,一分钟按500个页面算,都要(4000000/500/60)=133个小时,hold不住的~~

// 爬下静态网页
    public String getOneHtml(String htmlurl) throws IOException {
        URL url;
        String temp;
        StringBuffer sb = new StringBuffer();
        try {
            url = new URL(htmlurl);
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));// 读取网页全部内容
            while ((temp = in.readLine()) != null) {
                sb.append(temp);
            }
            in.close();
        } catch (MalformedURLException me) {
            System.out.println("你输入的URL格式有问题!请仔细输入");
            me.getMessage();
            throw me;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }

        // System.out.println(sb.toString()); //成功爬下了静态网页
        return sb.toString();
    }

下面的代码是,通配符匹配的代码:

// 通过通配符匹配
    public String getInfo(String s) {
        String regex;
        String res = "";

        // 通配符
        regex = "This is bill";
        Pattern pa = Pattern.compile(regex, Pattern.CANON_EQ);
        Matcher ma = pa.matcher(s);

        if (ma.find()) {
            // 成功找到

            regex = "http://cdn.qupeiyin.cn/.*?/.*?.mp4";
            pa = Pattern.compile(regex, Pattern.CANON_EQ);
            ma = pa.matcher(s);

            if (ma.find())
                res += (ma.group());

            return res;
        }

        else
            return null;

    }

关于多线程共享,这里要粘贴一段test的代码:

///模拟售票的程序,三个线程共享一个ticket
package robot;

public class Bill implements Runnable {

    public Bill() {

    }

    public Bill(String name) {
        this.name = name;
    }

    private int ticket = 10;

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "--" + this.ticket--);
            }
        }
    }

    public static void main(String[] args) {
        Bill B3 = new Bill();
        new Thread(B3, "线程1").start();
        new Thread(B3, "线程2").start();
        new Thread(B3, "线程3").start();
    }

    private String name;

}

这是一个可能的结果:

我在代码中把,爬到的有用地址写到了txt里面。具体追加过程见附录。

关于多线程,Java提供了不止一种方法,可能你会说,其实继承 Thread 类,跟实现 Runnable 接口差不多,因为 其实Thread中的run方法调用的是Runnable接口的run方法而已。但是他们还是有相当多的不一样,详情可以参考这篇文章,写的不错,但是!!

这篇文章里面也有不少错误,具体需要我们自己仔细分辨!!毕竟自己搞懂的才是真正自己的,如果要看,可以结合评论一起看~~

也差不多就这样了,主要还是读源码,理解,做实验~~

四、小结

要对写出爬虫有信心,其实没那么难~~~好了,2小时就耍完了这个,Bill可以安心去写项目了~bye

源代码下载地址:http://download.csdn.net/detail/scythe666/8973067

五、附:

Java追加文件内容的三种方法

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;

public class AppendFile {

    public static void method1(String file, String conent) {
        BufferedWriter out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
            out.write(conent);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(out != null){
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }   

    /**
     * 追加文件:使用FileWriter
     *
     * @param fileName
     * @param content
     */
    public static void method2(String fileName, String content) {
        FileWriter writer = null;
        try {
            // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
            writer = new FileWriter(fileName, true);
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }   

    /**
     * 追加文件:使用RandomAccessFile
     *
     * @param fileName 文件名
     * @param content 追加的内容
     */
    public static void method3(String fileName, String content) {
        RandomAccessFile randomFile = null;
        try {
            // 打开一个随机访问文件流,按读写方式
            randomFile = new RandomAccessFile(fileName, "rw");
            // 文件长度,字节数
            long fileLength = randomFile.length();
            // 将写文件指针移到文件尾。
            randomFile.seek(fileLength);
            randomFile.writeBytes(content);
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(randomFile != null){
                try {
                    randomFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }  

    public static void main(String[] args) {
        try{
            File file = new File("d://text.txt");
            if(file.createNewFile()){
                System.out.println("Create file successed");
            }
            method1("d://text.txt", "123");
            method2("d://text.txt", "123");
            method3("d://text.txt", "123");
        }catch(Exception e){
            System.out.println(e);
        }
    }
}

—END—


参考文献

[1] http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html

[2] http://blog.csdn.net/liangoo7/article/details/7882773

[3] http://blog.csdn.net/malik76/article/details/6408726

版权声明:欢迎转载,注明出处就好!如果不喜欢请留言说明原因再踩哦,谢谢,我也可以知道原因,不断进步!!

时间: 2024-11-10 03:47:57

简易Java爬虫制作的相关文章

JAVA爬虫 WebCollector

爬虫简介: WebCollector是一个无须配置.便于二次开发的JAVA爬虫框架(内核),它提供精简的的API,只需少量代码即可实现一个功能强大的爬虫. 爬虫内核: WebCollector致力于维护一个稳定.可扩的爬虫内核,便于开发者进行灵活的二次开发.内核具有很强的扩展性,用户可以在内核基础上开发自己想要的爬虫.源码中集成了Jsoup,可进行精准的网页解析. 量级: WebCollector最常用的爬取器BreadthCrawler使用2^24的布隆过滤器进行URL管理,可处理2^24量级

webmagic的设计机制及原理-如何开发一个Java爬虫 转

此文章是webmagic 0.1.0版的设计手册,后续版本的入门及用户手册请看这里:https://github.com/code4craft/webmagic/blob/master/user-manual.md 之前就有网友在博客里留言,觉得webmagic的实现比较有意思,想要借此研究一下爬虫.最近终于集中精力,花了三天时间,终于写完了这篇文章.之前垂直爬虫写了一年多,webmagic框架写了一个多月,这方面倒是有一些心得,希望对读者有帮助. webmagic的目标 一般来说,一个爬虫包括

JAVA爬虫WebCollector教程列表

JAVA爬虫WebCollector教程列表 入门教程: WebCollector入门教程(中文版) 用WebCollector对指定URL进行爬取和解析 JAVA爬虫Nutch.WebCollector的正则约束 实例: 用WebCollector制作一个爬取<知乎>并进行问题精准抽取的爬虫(JAVA) 内核: 利用WebCollector爬虫内核定制自己的爬虫--任务生成器Generator 利用WebCollector爬虫内核定制自己的爬虫--抓取器Fetcher

福利贴——爬取美女图片的Java爬虫小程序代码

自己做的一个Java爬虫小程序 废话不多说,先上图. 文件夹命名是用标签缩写,如果大家看得不顺眼可以等下载完成后手动改一下,比如像有强迫症的我一样... 这是挂了一个晚上下载的总大小,不过还有很多因为一些问题没有遍历下载到,而且会产生很多空文件,最下面我附带了一个递归删除空文件夹的小程序代码. 接下来是文件夹内部~ 图片存放位置默认为d:\picture,可在程序中更改,main函数的开头就是,有注释.爬取的网站为http://www.mmonly.cc/,大家有更好的资源网站可以私我. 爬虫源

Java爬虫

1.昨天复习了Java基础(I/O流)和正则表达式 今天不讲Java中的 I/O 主要用一个实例来爬取网站中的邮箱 代码如下: 1 package com.miao.baba.pacong; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.net.URL;

Java爬虫项目实战(一)

目的: 通过网络爬虫爬取中国最小粒度的区域维度信息,包括省(Province) .市(City).县(County).镇(town).村委会(village) 主网站链接: http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2015/index.html 主要jar包: http://jsoup.org/packages/jsoup-1.8.1.jar 之前一节我们说过java爬虫从网络上利用jsoup获取网页文本,也就是说我们可以有三种方法获取h

Java爬虫框架SeimiCrawler的工程自动打包工具使用

为了便于开发者对使用SeimiCrawler框架开发的爬虫工程的打包部署,SeimiCrawler现已推出maven-seimicrawler-plugin,一个maven工程的自动化打包插件.下面简要介绍下他的使用. 开始 pom添加添加plugin <plugin> <groupId>cn.wanghaomiao</groupId> <artifactId>maven-seimicrawler-plugin</artifactId> <

Java爬虫实战(二):抓取一个视频网站上2015年所有电影的下载链接

前言:这是Java爬虫实战的第二篇文章,在第一篇文章仅仅只是抓取目标网站的链接的基础上,进一步提高难度,抓取目标页面上我们所需要的内容并保存在数据库中.这里的测试案例选用了一个我常用的电影下载网站(http://www.80s.la/).本来是想抓取网站上的所有电影的下载链接,后来感觉需要的时间太长,因此改成了抓取2015年电影的下载链接. 注:文末有我抓取到的整个列表的下载链接(包括:电影名称和迅雷下载链接) 一 原理简介 其实原理都跟第一篇文章差不多,不同的是鉴于这个网站的分类列表实在太多,

关于Java爬虫的研究

起因 最近突然发了羊癫疯,对爬虫十分感兴趣,开始想写几个爬虫练练手,于是,洗手开搞. 像我这种懒人,对爬虫了解个大概之后就开始偷懒了,开始找框架了,Google关键字“Java 爬虫”,第一个搜索结果就是 高票回答推荐的几款爬虫框架:nutch.Heritrix.crawler4j.WebCollector和WebMagic,果断选择了WebMagic,支持国人作品嘛(肯定是中文文档啊) 下手 使用Maven添加框架到项目中,在poxm.xml文件中添加以下依赖.国内的Maven库居然没有Web