初次尝试WebMagic来编写一个爬取CSDN单页面的Demo

        作为一名小菜鸡,经常看到很多博客在说python的爬虫的优点以及好处,但是由于工作比较忙,以及暂时不想把重心转移到新的语言的学习上,去百度了java的爬虫框架.

        结果找到了这一款WebMagic框架,基于Java,由国人编写,功能很完善,所以尝试一下.

        本例使用Idea编译器,基于Maven创建了项目,引入了WebMagic的相关包以及log4j,因为考虑到后期考虑到数据的存储,所以直接在pom中配置了spring+springMVC+MyBatis的相关包,使用MySql5.5数据库.

         下面贴上pom.xml的代码

         




  4.0.0

  cn.com.zach.webMagic
  WebMagic
  1.0-SNAPSHOT
  war

  WebMagic Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.7
    1.7
    
    5.0.5.RELEASE
    
    3.2.6
    
    1.7.7
    1.2.17
  

  
    
    
      org.springframework
      spring-core
      ${spring.version}
    

    
      org.springframework
      spring-web
      ${spring.version}
    
    
      org.springframework
      spring-oxm
      ${spring.version}
    
    
      org.springframework
      spring-aspects
      ${spring.version}
    
    
      org.springframework
      spring-tx
      ${spring.version}
    

    
      org.springframework
      spring-jdbc
      ${spring.version}
    

    
      org.springframework
      spring-webmvc
      ${spring.version}
    
    
      org.springframework
      spring-aop
      ${spring.version}
    


    
      org.springframework
      spring-context-support
      ${spring.version}
    

    
      org.springframework
      spring-test
      ${spring.version}
    
    
    
      org.mybatis
      mybatis
      ${mybatis.version}
    

    
    
      org.mybatis
      mybatis-spring
      1.2.2
    

    
    
      mysql
      mysql-connector-java
      5.1.30
    

    
      c3p0
      c3p0
      0.9.1.2
    

    
    
      jstl
      jstl
      1.2
    
    
    
    
      log4j
      log4j
      ${log4j.version}
    


    
    
      com.alibaba
      fastjson
      1.1.41
    


    
      org.slf4j
      slf4j-api
      ${slf4j.version}
    

    
      org.slf4j
      slf4j-log4j12
      ${slf4j.version}
    
    
    
    
      org.codehaus.jackson
      jackson-mapper-asl
      1.9.13
    
    
    
      commons-fileupload
      commons-fileupload
      1.3.1
    
    
      commons-io
      commons-io
      2.4
    
    
      commons-codec
      commons-codec
      1.9
    

    
    
      commons-dbcp
      commons-dbcp
      1.4
    

    
      jetty
      servlet-api
      2.5-6.0.2
    

    
    
      junit
      junit
      4.0
    
    
    
      us.codecraft
      webmagic-core
      0.6.1
    

    
      us.codecraft
      0.6.1
      webmagic-extension
    

    
      us.codecraft
      webmagic-selenium
      0.6.1
    

  

  
    WebMagic
    
      
        
          maven-clean-plugin
          3.0.0
        
        
        
          maven-resources-plugin
          3.0.2
        
        
          maven-compiler-plugin
          3.7.0
        
        
          maven-surefire-plugin
          2.20.1
        
        
          maven-war-plugin
          3.2.0
        
        
          maven-install-plugin
          2.5.2
        
        
          maven-deploy-plugin
          2.8.2
        
      
    

    
      
        src/main/java
        
          **/*.xml
        
      
    
  


考虑到Demo中集成了log4j的相关包,所以需要配置一下log4j,在resources下创建log4j.propertise文件

初次尝试WebMagic来编写一个爬取CSDN单页面的Demo_第1张图片

log4j.propertise的配置如下:

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到= F://webMagic爬虫/log/log.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = F://webMagic爬虫/log/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到= F://webMagic爬虫/log/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = F://webMagic爬虫/log/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

基本配置就这些,由于是第一次尝试,没有考虑存储数据库,仅仅试试是否可行

配置完成后,开始创建class进行爬虫的编写

WebMagic的基本使用方式十分简单:

                  创建一个类-->这个类实现PageProcessor接口 --> 重写process方法以及getSite方法

process方法:编写爬虫的主要逻辑

getSite方法:不需要写什么东西,把Site对象返回就好(理解可能不太对,但是初步这样写就好)

在这些之外,我们还需要了解一下我们如果想爬取网页相关信息,最少需要掌握或者知道的东西

    1.网站url你得知道,并且确定自己的ip是可以访问的

    2.不求html大成精通,但是你最起码得知道网站结构,不要给你一个网站你都看不懂html,无从下手

    3.要对css了解,因为可能会根据它来筛选,当然,如果从事web开发或者大学毕设涉及到web开发,应该都会一些

    4.正则表达式,xpath得了解,因为css筛选的局限性还是有的

现在看下代码,在类的开头,我先初始化了一点数据

private static HashMap rtnMap = new HashMap();
    private static Spider spider = Spider.create(new GetCsdn());
    private Site site = Site.me()
            .setDomain("www.baidu.com")
            .setSleepTime(1131)
            .setCharset("utf-8")
            .setRetrySleepTime(3)
            .setTimeOut(1000)//设置超时
            .setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");

 

Spider用于初始化爬虫的相关信息

创建了一个Map用于存储查到的数据

初始化了Site对象,这个Site对象是WebMagic的配置对象

具体的配置如下图

初次尝试WebMagic来编写一个爬取CSDN单页面的Demo_第2张图片

配置完成后,来书写process逻辑方法

String list = page.getHtml().xpath("*[@id=\"mainBox\"]/aside/div[1]/div[1]/div[2]/p/a/text()").toString();//账号名
        String PageTitle = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/div[1]/div[1]/div[1]/h1/text()").toString();//文章标题
        String time = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/div[1]/div[1]/div[2]/div[1]/span[2]/text()").toString();//时间
        String content = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/article/div[1]/div[1]/span/text()").toString();//内容
        rtnMap.put("username",list);
        rtnMap.put("PageTitle",PageTitle);
        rtnMap.put("time",time);
        rtnMap.put("title",content);

 

这是根据网页的结构去获取信息,使用xpath,不多赘述

最后写main方法,执行:

public static void main(String[] args){
        spider
                .thread(5)//线程数控制在10以内差不多,否则极易出现read time out
                .addUrl("https://blog.csdn.net/yinbucheng/article/details/71023037")
                .run();

//        rtnMap.forEach((key, value) -> {
//            System.out.println("**key的值为" + key);
//            System.out.println("VALUE的值为" + rtnMap.get(key));
//        });
    }

 

最后的结果为:

初次尝试WebMagic来编写一个爬取CSDN单页面的Demo_第3张图片

需要注意的是,代码中使用的遍历方法为java8的lambda表达式,若报错请自行更改遍历方法

下面贴上全部代码:

package WebMagicForCSDN;


import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;

import java.util.HashMap;
import java.util.function.BiConsumer;

/**
 * 解析单页面多信息的Demo
 *
 * 这个Demo的作用是利用WebMagic下载并解析一个单页面的有用信息,并按照Map格式存储,没有进行多页面的关联以及处理.
 *
 * 算是对XPath这种筛选器的一个练习
 */
public class GetCsdn implements PageProcessor {
    private static HashMap rtnMap = new HashMap();
    private static Spider spider = Spider.create(new GetCsdn());
    private Site site = Site.me()
            .setDomain("www.baidu.com")
            .setSleepTime(1131)
            .setCharset("utf-8")
            .setRetrySleepTime(3)
            .setTimeOut(1000)//设置超时
            .setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");
    @Override
    public void process(Page page) {
        String list = page.getHtml().xpath("*[@id=\"mainBox\"]/aside/div[1]/div[1]/div[2]/p/a/text()").toString();//账号名
        String PageTitle = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/div[1]/div[1]/div[1]/h1/text()").toString();//文章标题
        String time = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/div[1]/div[1]/div[2]/div[1]/span[2]/text()").toString();//时间
        String content = page.getHtml().xpath("*[@id=\"mainBox\"]/main/div[1]/article/div[1]/div[1]/span/text()").toString();//内容
        rtnMap.put("username",list);
        rtnMap.put("PageTitle",PageTitle);
        rtnMap.put("time",time);
        rtnMap.put("title",content);
    }

    @Override
    public Site getSite() {
        return site;
    }

    public static void main(String[] args){
        spider
                .thread(5)//线程数控制在10以内差不多,否则极易出现read time out
                .addUrl("https://blog.csdn.net/yinbucheng/article/details/71023037")
                .run();

        rtnMap.forEach(new BiConsumer() {
            @Override
            public void accept(String key, String value) {
                System.out.println("**key的值为" + key);
                System.out.println("VALUE的值为" + rtnMap.get(key));
            }
        });
    }
}

 

你可能感兴趣的:(WebMagic)