WebMagic爬取网站内容

WebMagic爬取网站内容

一、WebMagic介绍
         WebMagic是一个开源的Java爬虫框架,目标是简化爬虫的开发流程让开发者专注于逻辑功能的开发
         WebMagic采用完全模块化的设计,功能覆盖整个爬虫的生命周期(链接提取、页面下载、内容抽取、持久化),支持多线程抓取,分布式抓取,并支持自动重试、自定义UA/cookie等功能。

1.1、原理介绍
        先来看一下WebMagic的原理图
这里写图片描述

        Downloader(下载器)、PageProcesser(解析器)、Schedule(调度器)和Pipeline(管道)四部分组成。 核心代码非常简单,主要是将这些组件结合并完成多线程的任务。这意味着,在WebMagic中,基本上可以对爬虫的功能做任何定制。

  • 下载器
    webmagic爬取信息首先需要依赖给出的一个初始爬取的地址,下载器会下载这个页面的具体信息:
  • PageProcesser(解析器)
    下载成功后,page信息会传递给解析器,由解析器来定制爬虫模板,通过Xpath、CSS、JSOUP、正则表达式 等解析方法,从页面中提取有用的信息。
  • Schedule(调度器)
    Scheduler主要负责爬虫的下一步爬取的规划,包括一些去重等功能,如果一个页面爬取完成之后,要进行下一个页面的抓取,就由Schedule来调度。
  • Pipeline(管道)
    管道,爬取到的网站内容保存的位置由Pipeline来定义

总结:客户通过Internet发起http请求,到达DownLoader,DownLoader负责下载页面信息,下载完成之后将页面信息封装在page对象中交给PageProcesser解析器处理页面内容,(至于如何处理,可以自己制定规则),处理完成之后,将处理结果resultItems交给Pipeline管道,Pipelline负责将内容存储起来,与此同时,PageProcesser发送一个request请求给Schedule,他负责调度下一个html页面

二、WebMagic爬虫的具体实现

2.1、需求:
通过在eclipse创建maven项目,采集http://sousuo.gov.cn/column/30611/0.htm网站的新闻列表页和新闻详细页,完成实验。

Maven介绍:
Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具
Webmagic使用maven管理依赖,在项目中添加对应的依赖即可使用Webmagic

2.2、新建Maven项目,添加依赖

  1. 打开pom.xml文件,添加Maven依赖
<dependency>  
    <groupId>us.codecraft</groupId>  
    <artifactId>webmagic-core</artifactId>  
    <version>0.6.1</version>  
</dependency>  
<dependency>  
    <groupId>us.codecraft</groupId>  
    <artifactId>webmagic-extension</artifactId>  
    <version>0.6.1</version>  
</dependency> 

选择要刷新的maven项目,右键–>Maven–>Update Project,打开对话框,选择具体要刷新的maven项目,点击OK
2. 代码编写

package com.yxcx.webmagictest;  
import us.codecraft.webmagic.Page;  
import us.codecraft.webmagic.Site;  
import us.codecraft.webmagic.Spider;  
import us.codecraft.webmagic.pipeline.FilePipeline;  
import us.codecraft.webmagic.processor.PageProcessor;  
public class WebMagic implements PageProcessor { 
public static void main(String[] args) {  
        Spider.create(new WebMagic())  
    // 从"http://sousuo.gov.cn/column/30611/0.htm"开始抓  
        .addUrl("http://sousuo.gov.cn/column/30611/0.htm")  
     // 抓取页面的存储路径  
        .addPipeline(new FilePipeline("/data/pachong/govnews"))  
      // 开启5个线程抓取 ,底层处理了线程同步 
        .thread(5)  
       // 启动爬虫  
         .run();  
    }   
    // 第一步:DownLoader加载器下载网页时,抓取网站的相关配置,包括编码、抓取间隔、重试次数等  
    private Site site = Site.me().setRetryTimes(3).setSleepTime(100);  
    //第二步: process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑  
    public void process(Page page) { 
    //每个html网页的url地址 
        System.out.println(page.getUrl());  
     //获取网页的title,该title位于haead标签中,text()方法表示获得文本内容
        String title = page.getHtml().xpath("//head/title/text()").toString();  
        System.out.println(title);  
        if (title == null) {  
        //setSkip这个方法是对resultItems的内容进行忽略,默认设置为false,就是在本层逻辑中,爬取到的信息不进入管道进行保存。
            page.setSkip(true);  
        }  
        page.putField("allhtml", page.getHtml().toString());  
        // 从页面发现后续的url地址来抓取  采用正则表达式去匹配网页名字,分为两种:1、新闻列表项;2、新闻详细页
        // 1、采集该网站新闻列表页 , 
      page.addTargetRequests(page.getHtml().links().regex("(http://sousuo.gov.cn/column/30611/\\d+.htm)").all());  
        // 2、采集该网站每条新闻详细页  
        page.addTargetRequests(  
                page.getHtml().links().regex("(http://www.gov.cn/xinwen/2017-\\d+/\\d+/content_\\d+.htm)").all());  
    } 
    //此方法在Downloader时底层会调用该方法获得site,包括爬虫时的一些设置信息。 
    public Site getSite() {  
        return site;  
    }  
}  

大神请看,菜鸟止步!!!

三、WebMagic源码解析

1、webmagic源码结构图:

这里写图片描述

//1、HttpClientDownloader这个类是下载页面的类,其中的download方法返回page对象,page封装页面的信息。
@Override
    public Page download(Request request, Task task) {
        Site site = null;
        if (task != null) {
            site = task.getSite();
        }
        Set<Integer> acceptStatCode;
        String charset = null;
        Map<String, String> headers = null;
        if (site != null) {
            acceptStatCode = site.getAcceptStatCode();
            charset = site.getCharset();
            headers = site.getHeaders();
        } else {
            acceptStatCode = Sets.newHashSet(200);
        }
        logger.info("downloading page {}", request.getUrl());
        CloseableHttpResponse httpResponse = null;
        int statusCode=0;
        try {
            HttpUriRequest httpUriRequest = getHttpUriRequest(request, site, headers);
            httpResponse = getHttpClient(site).execute(httpUriRequest);
            statusCode = httpResponse.getStatusLine().getStatusCode();
            request.putExtra(Request.STATUS_CODE, statusCode);
            if (statusAccept(acceptStatCode, statusCode)) {
                Page page = handleResponse(request, charset, httpResponse, task);
                onSuccess(request);
                return page;//返回page对象
            } else {
                logger.warn("code error " + statusCode + "\t" + request.getUrl());
                return null;
            }
        } catch (IOException e) {
            logger.warn("download page " + request.getUrl() + " error", e);
            if (site.getCycleRetryTimes() > 0) {
                return addToCycleRetry(request, site);
            }
            onError(request);
            return null;
        } finally {
            request.putExtra(Request.STATUS_CODE, statusCode);
            try {
                if (httpResponse != null) {
                    //ensure the connection is released back to pool
                    EntityUtils.consume(httpResponse.getEntity());
                }
            } catch (IOException e) {
                logger.warn("close response fail", e);
            }
        }
    }

2、以上download方法返回page对象后,执行下面的方法process方法

public interface PageProcessor {

    /**
     * process the page, extract urls to fetch, extract the data and store
     *
     * @param page
     */
     //子类重写该方法,处理页面信息,其中page对象中封装了页面的信息
    public void process(Page page);

    /**
     * get the site settings
     *
     * @return site
     * @see Site
     */
    public Site getSite();
}

3、页面信息交个Pieline,存储起来

public class FilePipeline extends FilePersistentBase implements Pipeline {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * create a FilePipeline with default path"/data/webmagic/"
     */
     //源码中默认存储在linux目录下的/data/webmagic/
    public FilePipeline() {
        setPath("/data/webmagic/");
    }
    //可以自行定义存储目录
    public FilePipeline(String path) {
        setPath(path);
    }

4、WebMagic底层使用线程池处理

public void execute(final Runnable runnable) {

        if (threadAlive.get() >= threadNum) {
            try {
            //底层处理了线程同步  lock锁住
                reentrantLock.lock();
                while (threadAlive.get() >= threadNum) {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                    }
                }
            } finally {
            //解锁
                reentrantLock.unlock();
            }
        }
        threadAlive.incrementAndGet();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } finally {
                    try {
                        reentrantLock.lock();
                        threadAlive.decrementAndGet();
                        condition.signal();
                    } finally {
                        reentrantLock.unlock();
                    }
                }
            }
        });

源码粗略的描述了一遍,感兴趣的同学可以自己查看分析。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java WebMagic是一个开源的Java爬虫框架,可以用于爬取网页数据,包括图片。它提供了简单易用的API,可以方便地定义爬取规则和处理爬取结果。 要使用Java WebMagic进行图片爬取,首先需要添加WebMagic的依赖到你的项目中。然后,你可以按照以下步骤进行操作: 1. 创建一个Java类,作为你的爬虫程序的入口点。 2. 在该类中,使用WebMagic提供的注解和API定义你的爬取规则。你可以指定要爬取的网页URL、要提取的图片链接等信息。 3. 实现一个自定义的处理器(Pipeline),用于处理爬取到的图片数据。你可以将图片保存到本地或者进行其他处理。 4. 创建一个爬虫对象,并设置好爬取规则和处理器。 5. 启动爬虫,开始爬取图片。 以下是一个简单的示例代码,演示了如何使用Java WebMagic进行图片爬取: ```java import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.pipeline.FilePipeline; import us.codecraft.webmagic.processor.PageProcessor; public class ImageSpider { public static void main(String[] args) { // 创建一个PageProcessor对象,用于定义爬取规则 PageProcessor pageProcessor = new MyPageProcessor(); // 创建一个Pipeline对象,用于处理爬取结果 FilePipeline filePipeline = new FilePipeline("保存图片的目录"); // 创建一个Spider对象,并设置好PageProcessor和Pipeline Spider spider = Spider.create(pageProcessor) .addUrl("要爬取的网页URL") .addPipeline(filePipeline); // 启动爬虫 spider.run(); } // 自定义的PageProcessor类,用于定义爬取规则 static class MyPageProcessor implements PageProcessor { @Override public void process(Page page) { // 提取图片链接,并将其添加到爬取队列中 page.addTargetRequests(page.getHtml().$("img[src]").all()); // 获取图片链接,并保存到结果中 page.putField("image", page.getHtml().$("img[src]").all()); } @Override public Site getSite() { return Site.me(); } } } ``` 请注意,上述示例代码中的"要爬取的网页URL"和"保存图片的目录"需要根据实际情况进行替换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值