一、

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

二、

采集步骤:

1:分析采集内容

      2:发送Http请求

  1. 解析请求返回元素
  2. 存储采集内容
  1. 分析采集内容

Demo:采集肖申克的救赎的影评 (标题、评论)

https://movie.douban.com/subject/1292052/reviews?start=20

 

java实现互联网爬虫

 

分析请求地址

https://movie.douban.com/subject/1292052/reviews?start=20

响应方式:text/html

 

2.发送http请求(get/post)下面的表格比较了两种 HTTP 方法:GET 和 POST。

 

GET

POST

后退按钮/刷新

无害

数据会被重新提交(浏览器应该告知用户数据会被重新提交)。

书签

可收藏为书签

不可收藏为书签

缓存

能被缓存

不能缓存

编码类型

application/x-www-form-urlencoded

application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。

历史

参数保留在浏览器历史中。

参数不会保存在浏览器历史中。

对数据长度的限制

是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。

无限制。

对数据类型的限制

只允许 ASCII 字符。

没有限制。也允许二进制数据。

安全性

与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。

在发送密码或其他敏感信息时绝不要使用 GET !

POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。

可见性

数据在 URL 中对所有人都是可见的。

数据不会显示在 URL 中。


Apache HttpClient

 

HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

<dependency>  

   <groupId>org.apache.httpcomponents</groupId>  

    <artifactId>httpclient</artifactId>  

    <version>4.3.4</version>  

</dependency>  

  

向豆瓣评论发送请求

private  String httpGet(String url) {

    String result = "";

    try {

        result = EntityUtils.toString(new DefaultHttpClient()

                .execute(new HttpGet(url)).getEntity(),

                "utf-8");

    } catch (Exception e) {

        e.printStackTrace();

    }

    return result;

}

3.解析采集内容

 

Jsoup是用于解析HTML,就类似XML解析器用于解析XML。 Jsoup它解析HTML成为真实世界的HTML。 它与jquery选择器的语法非常相似,并且非常灵活容易使用以获得所需的结果

 

选择器例子:

Elements links = doc.select("a[href]"); //带有href属性的a元素

Elements pngs = doc.select("img[src$=.png]"); //扩展名为.png的图片

Element masthead = doc.select("div.masthead").first();//class等于masthead的div标签

Elements resultLinks = doc.select("h3.r > a"); //在h3元素之后的a元素

 

 

解析豆瓣评论返回采集内容

 

Html doubanMoveComment = page.getHtml();

Document doubanMoveDocument = doubanMoveComment.getDocument();

Elements headerElements = doubanMoveDocument.select("div.main-bd");

headerElements.forEach(elements -> {

    String title = elements.select("h2").text();

    String comment = elements.select("div.short-content").text();

    log.info("title:" + title + " comment:" + comment);

});

 

4.完整例子

 

public static void main(String args[]) throws Exception {

        String target = "https://movie.douban.com/subject/1292052/reviews?start=20";

        DoubanSpider1 spider = new DoubanSpider1();

        spider.process(target);

    }

 

    public void process(String target) throws Exception {

        String httpgetRes = httpGet(target);

        Html doubanMoveComment = new Html(httpgetRes);

        Document doubanMoveDocument = doubanMoveComment.getDocument();

        Elements headerElements = doubanMoveDocument.select("div.main-bd");

        headerElements.forEach(elements -> {

            String title = elements.select("h2").text();

            String comment = elements.select("div.short-content").text();

            System.out.println("title:" + title + " comment:" + comment);

        });

    }

 

    private  String httpGet(String url) {

        String result = "";

        try {

            result = EntityUtils.toString(new DefaultHttpClient()

                    .execute(new HttpGet(url)).getEntity(),

                    "utf-8");

        } catch (Exception e) {

            e.printStackTrace();

        }

        return result;

    }

三、存在的问题

1、采集效率低

2、如果采集数据量大,单机难以实现

3、针对每个不同的地址需要写一套采集程序、无法统一管理运行

 

  • 解决方案

解决方案:

1、单线程改成多线程

String target = "https://movie.douban.com/subject/1292052/reviews?start=";

DoubanSpider2 spider = new DoubanSpider2();

ExecutorService executorService = Executors.newFixedThreadPool(threadSize);

CountDownLatch latch = new CountDownLatch(threadSize);

 

for (int index = 0; index < threadSize; index++) {

    int i = index;

    Runnable task = () -> {

        String address = target + i * 20 + 20;

        spider.process(address);

        latch.countDown();

    };

    executorService.submit(task);

}

latch.await();

 

  1. 采用webmagic集成框架(集成多线程+Http)

webmagic是一个开源的Java垂直爬虫框架,目标是简化爬虫的开发流程,让开发者专注于逻辑功能的开发

 

<dependency>

<groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId>

<version>0.5.3</version>

</dependency>

 <dependency>

<groupId>us.codecraft</groupId>

<artifactId>webmagic-extension</artifactId> 

<version>0.5.3</version> 

</dependency>

 

/*设置抓取网站的相关配置*/

private Site site = Site.me().setRetryTimes(3).setSleepTime(100);

/*爬取*/

public static void main(String args[]) {

    String target = "https://movie.douban.com/subject/1292052/reviews?start=20";

    Spider.create(

            new DoubanSpider3())

            .addUrl(target)

            .thread(5)

            .run();

 

}

/*爬取逻辑*/

public void process(Page page) {

    Html doubanMoveComment = page.getHtml();

    Document doubanMoveDocument = doubanMoveComment.getDocument();

    Elements headerElements = doubanMoveDocument.select("div.main-bd");

    headerElements.forEach(elements -> {

        String title = elements.select("h2").text();

        String comment = elements.select("div.short-content").text();

        System.out.println("title:" + title + " comment:" + comment);

    });

}

  1. 动态执行采集任务

private final static String targetPath = "D:/luowang/luowang_spider/out/artifacts/DoubanSpider3/DoubanSpider3.jar";

    public static void main(String args[]) {

        URL[] urls = new URL[]{};

        DoubanClassLoader classLoader = new DoubanClassLoader(urls);

        try {

            classLoader.addJar(new File(targetPath).toURI().toURL());

            Class<?> clazz = classLoader.loadClass("com.css.website.douban.DoubanSpider3");

            DoubanSpider3 spider3 = (DoubanSpider3)clazz.newInstance();

            spider3.runSpider();

            classLoader.close();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    static class DoubanClassLoader extends URLClassLoader {

        DoubanClassLoader(URL[] urls) {

            super(urls);

        }

        public DoubanClassLoader(URL[] urls, ClassLoader parent) {

            super(urls, parent);

        }

        void addJar(URL url) {

            this.addURL(url);

        }

    }

 

  1. 采用分布式调度任务+动态加载采集程序+Webmagic(分布式爬虫系统)
  1. 通过webmagic编写采集程序
  2. 将需要采集地址、编写的采集程序打成jar上传到系统管理中心(可用redis/ftp)存储
  3. 系统接到任务后分片执行采集任务

  

 

 

相关文章:

  • 2021-12-24
  • 2021-12-05
猜你喜欢
  • 2021-07-15
  • 2021-08-24
  • 2021-11-19
  • 2022-01-01
  • 2021-12-24
  • 2021-11-23
  • 2021-05-27
相关资源
相似解决方案