zoukankan      html  css  js  c++  java
  • JAVA爬虫实践(实践三:爬虫框架webMagic和csdnBlog爬虫)

    WebMagic

    WebMagic是一个简单灵活的Java爬虫框架。基于WebMagic,你可以快速开发出一个高效、易维护的爬虫。

    采用HttpClient可以实现定向的爬虫,也可以自己编写算法逻辑来实现多线程,创建链接池,自动解析网页代码获取请求链接,封装正则表达式等等。

    但是如果使用框架,就不再需要考虑爬虫的逻辑,只需要专注HTML内容的解析和获取。

    引用WebMagic后写一个爬虫只需要编写一个类实现PageProcessor接口,实现两个方法。

    一个WebMagic例子

    package csdnblog;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class MyPageProcessor implements PageProcessor {
    
        @Override
        public Site getSite() {
            // 重试3次,抓取间隔1S
            return Site.me().setRetryTimes(3).setSleepTime(1000);
        }
    
        @Override
        public void process(Page page) {
            page.addTargetRequests(page.getHtml().links().regex("http://blog\.csdn\.net/\?&page=.*").all());
        
            try {
                // 创建新文件
                String path = "D:\testFile\"+getFileName(page.getUrl().toString())+".html";
                PrintWriter printWriter = new PrintWriter(new FileWriter(new File(path)));
                // 写内容
                printWriter.write(page.getHtml().toString());
                printWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            Spider.create(new MyPageProcessor()).addUrl("http://blog.csdn.net").thread(5).run();
        }
    
        public String getFileName(String url) {
            return url.substring(20, url.length()).replace("?", "").replace("&", "");
        }
    }

    这个例子里实现了一个getSite方法,用来获取抓取网站的相关配置,包括:编码、抓取间隔、重试次数等

    还实现了一个process方法,里面除了写文件的部分,就只有一个page.addTargetRequests(),它是用来为链接池添加爬虫需要的链接,当爬虫线程开启后,每个线程会到链接池中取链接,当链接池为空,爬虫结束。

    page.addTargetRequests(page.getHtml().links().regex("http://blog\.csdn\.net/\?&page=.*").all());

    即将所有符合"http:blog.csdn.net?&page=数字"的链接放入链接池中

    例子中可以看到page.getHtml()即获取页面上HTML内容,在此基础上用xpath就可以取得其中想要的数据

    xpath是一种HTML标签元素的路径表达方式

    使用火狐firebug和谷歌浏览器F12都可以右键标签直接复制标签的xpath

    可以采用xpath的方式获取链接池链接

    // 添加所有文章页
    page.addTargetRequests(page.getHtml().xpath("//div[@class='blog_list_wrap']").links()// 限定文章列表获取区域
            .regex("http://blog\.csdn\.net/.*/article/details/.*")
            .all());
    // 添加其他列表页
    page.addTargetRequests(page.getHtml().xpath("//div[@class='page_nav']").links()// 限定其他列表页获取区域
            .regex("http://blog\.csdn\.net.*")
            .all());

    使用xpath获取页面中想要的数据

    package csdnblog;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class MyPageProcessor implements PageProcessor {
    
        @Override
        public Site getSite() {
            // 重试3次,抓取间隔1S
            return Site.me().setRetryTimes(3).setSleepTime(1000);
        }
    
        @Override
        public void process(Page page) {
            // 添加所有文章页
            page.addTargetRequests(page.getHtml().xpath("//div[@class='blog_list_wrap']").links()// 限定文章列表获取区域
                    .regex("http://blog\.csdn\.net/.*/article/details/.*")
                    .all());
            // 添加其他列表页
            page.addTargetRequests(page.getHtml().xpath("//div[@class='page_nav']").links()// 限定其他列表页获取区域
                    .regex("http://blog\.csdn\.net.*")
                    .all());   
            //如果当前页为文章页
            if(page.getUrl().regex("http://blog\.csdn\.net/.*/article/details/.*").match()){
                // 编号
                System.out.println("编号:" + page.getUrl().regex("http://blog\.csdn\.net/.*/article/details/(\d+)").get());
                // 标题
                System.out.println("标题:" + page.getHtml().xpath("//div[@class='article_title']//span[@class='link_title']/a/text()").get());
                // 日期
                System.out.println("日期" + page.getHtml().xpath("//div[@class='article_r']/span[@class='link_postdate']/text()").get());
                // 标签
                System.out.println("标签" + page.getHtml().xpath("//div[@class='article_l']/span[@class='link_categories']/a/allText()").all().toString());
                // 类别
                System.out.println("类别" + page.getHtml().xpath("//div[@class='category_r']/label/span/text()").all().toString());
            }
        }
    
        public static void main(String[] args) {
            Spider.create(new MyPageProcessor()).addUrl("http://blog.csdn.net").thread(5).run();
        }
    }
  • 相关阅读:
    开源围棋A.I. FoolGo
    再写围棋的MC模拟
    棋串的数据结构
    一种Lua到C的封装
    用vim写ios程序
    一种C函数到Lua的封装
    Unix命令
    RSA java rsa加密,解密,生成密钥对工具类
    UOS 开启远程登录
    UOS 设置 java 程序开机启动
  • 原文地址:https://www.cnblogs.com/huangjian2/p/6756582.html
Copyright © 2011-2022 走看看