使用WebMagic爬虫框架爬取暴走漫画

来源:互联网 发布:村上春树作品推荐知乎 编辑:程序博客网 时间:2024/06/06 00:16

WebMagic是黄亿华先生开发的一款Java轻量级爬虫框架。我之所以选择WebMagic,因为它非常轻量级,可以学习爬虫的原理,而且用WebMagic非常容易进行功能扩展。也许你会听过另一个爬虫框架,Heritrix。博主一开始也是先入手了Heritrix,但是后来发现Heritrix实在是不够轻量级,因为博主只是想自己做个爬虫玩玩,并且能对爬虫的原理有更深刻的认识,所以,博主后来就开始入手更轻量级的WebMagic。由于博主也是刚接触WebMagic,写博客也只是为了记录我的学习到的知识,文章如有纰漏,敬请指正。


一、首先我们看一下我们要 爬取的网页,这个demo中,我打算爬取暴走漫画的中的笑话,内容包括作者名称(author),笑话内容(xontent),上传日期(time)


二、定义一个实体类封装爬取内容

[java] view plain copy
  1. public class BaozouNews {  
  2. // 作者  
  3. private String author;  
  4. // 提交时间  
  5. private String time;  
  6. // 内容  
  7. private String content;  
  8.   
  9. getter and setter...  
  10. }  



三、WebMagic中最重要的组件就是PageProcessor,它决定了你抓取数据的逻辑。

       1)确定要加入待爬取队列的超链接。

    我们爬取起始位置为第一页,因此我们要将其他页码的超链接加入待爬队列


我们可以清晰看到页码的超链接存放在class为pager-content的div块中,因此可以如下将超链接加入队列中,css选择器详见css参考手册

[java] view plain copy
  1. page.addTargetRequests(page.getHtml().css("div.pager-content").links().all());  


2)确定待爬取数据。

文章内容(content)是class为article article-text的div的data-text属性,因此其xpath为,关于xpath详见xpath教程

[java] view plain copy
  1. String content=page.getHtml().xpath("//div[@class='article article-text']/@data-text").toString()  
作者(author)是class为article-author-name的a的字符串部分

[java] view plain copy
  1. String author=page.getHtml().xpath("//a[@class='article-author-name']/text()").toString()  
依此类推

[java] view plain copy
  1. String time=page.getHtml().xpath("//span[@class='article-date']/text()").toString()  



四、根据第三步的分析,写自己的PageProcessor

[java] view plain copy
  1. public class BaoZouProcessor implements PageProcessor {  
  2.     private Site site = Site.me().setRetryTimes(3).setSleepTime(100);  
  3.   
  4.     @Override  
  5.     public void process(Page page) {  
  6.         page.addTargetRequests(page.getHtml().css("div.pager-content").links().all());  
  7.         BaozouNews news = new BaozouNews();  
  8.         news.setAuthor(page.getHtml().xpath("//a[@class='article-author-name']/text()").toString());  
  9.         news.setContent(page.getHtml().xpath("//div[@class='article article-text']/@data-text").toString());  
  10.         news.setTime(page.getHtml().xpath("//span[@class='article-date']/text()").toString());  
  11.         page.putField("news", news);  
  12.     }  
  13.   
  14.     @Override  
  15.     public Site getSite() {  
  16.         return site;  
  17.     }  
  18.   
  19. }  

五、编写自己的Pipeline,将爬取到的数据保存到数据库

[java] view plain copy
  1. public class BaoZouPipeLine implements Pipeline {  
  2.   
  3.     @Override  
  4.     public void process(ResultItems resultItems, Task task) {  
  5.         BaozouNews news = (BaozouNews) resultItems.get("news");  
  6.         Dao.insert(news);//将数据插入数据库  
  7.     }  
  8.   
  9. }  



六、将对数据库的操作进行简单的封装

[java] view plain copy
  1. public class Dao {  
  2.   
  3.     private static Connection getConn() {  
  4.         String driver = "com.mysql.jdbc.Driver";  
  5.         String url = "jdbc:mysql://localhost:3306/baozou";  
  6.         String username = "root";  
  7.         String password = "";  
  8.         Connection conn = null;  
  9.         try {  
  10.             Class.forName(driver); // classLoader,加载对应驱动  
  11.             conn = (Connection) DriverManager.getConnection(url, username, password);  
  12.         } catch (ClassNotFoundException e) {  
  13.             e.printStackTrace();  
  14.         } catch (SQLException e) {  
  15.             e.printStackTrace();  
  16.         }  
  17.         return conn;  
  18.     }  
  19.   
  20.     public static int insert(BaozouNews news) {  
  21.         Connection conn = getConn();  
  22.         int i = 0;  
  23.         String sql = "insert into baozou (author,time,content) values(?,?,?)";  
  24.         PreparedStatement pstmt;  
  25.         try {  
  26.             pstmt = (PreparedStatement) conn.prepareStatement(sql);  
  27.             pstmt.setString(1, news.getAuthor());  
  28.             pstmt.setString(2, news.getTime());  
  29.             pstmt.setString(3, news.getContent());  
  30.             i = pstmt.executeUpdate();  
  31.             pstmt.close();  
  32.             conn.close();  
  33.         } catch (SQLException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.         return i;  
  37.     }  
  38. }  




七、编写测试类

[java] view plain copy
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         Spider.create(new BaoZouProcessor())  
  4.                 // 从"http://baozoumanhua.com/text"开始抓  
  5.                 .addUrl("http://baozoumanhua.com/text").addPipeline(new BaoZouPipeLine())  
  6.                 // 开启5个线程抓取  
  7.                 .thread(5)  
  8.                 // 启动爬虫  
  9.                 .run();  
  10.     }  
  11. }  



八、查看数据库结果,如图,成功地将网页上的数据保存到了数据库中



这只是一个简单的WebMagic爬虫的实例,但是还是可以学到很多东西。