精华内容
下载资源
问答
  • webmagic入门demo

    2018-11-21 22:21:43
    webmagic入门demo,需要相关jar包,前往https://blog.csdn.net/qq_40374604
  • webmagic入门

    2016-07-25 19:47:55
  • 初学爬虫,WebMagic作为一个Java开发的爬虫框架很容易上手,下面就通过一个简单的小例子来看一下。 WebMagic框架简介 WebMagic框架包含四个组件,PageProcessor、Scheduler、Downloader和Pipeline。 这四大组件...

     初学爬虫,WebMagic作为一个Java开发的爬虫框架很容易上手,下面就通过一个简单的小例子来看一下。

    WebMagic框架简介

    WebMagic框架包含四个组件,PageProcessorSchedulerDownloaderPipeline。

    这四大组件对应爬虫生命周期中的处理管理下载持久化等功能。

    这四个组件都是Spider中的属性,爬虫框架通过Spider启动和管理。

    WebMagic总体架构图如下:

    四大组件

    PageProcessor 负责解析页面,抽取有用信息,以及发现新的链接。需要自己定义。

    Scheduler 负责管理待抓取的URL,以及一些去重的工作。一般无需自己定制Scheduler。

    Pipeline 负责抽取结果的处理,包括计算、持久化到文件、数据库等。

    Downloader 负责从互联网上下载页面,以便后续处理。一般无需自己实现。

    用于数据流转的对象

    Request 是对URL地址的一层封装,一个Request对应一个URL地址。

    Page 代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。

    ResultItems 相当于一个Map,它保存PageProcessor处理的结果,供Pipeline使用。

    环境配置

    使用Maven来添加依赖的jar包。

    <dependency>
        <groupId>us.codecraft</groupId>
        <artifactId>webmagic-core</artifactId>
        <version>0.7.3</version>
    </dependency>
    <dependency>
        <groupId>us.codecraft</groupId>
        <artifactId>webmagic-extension</artifactId>
        <version>0.7.3</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    或者直接摸我下载。

    添加完jar包就完成了所有准备工作,是不是很简单。

    下面来测试一下。

    package edu.heu.spider;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.pipeline.ConsolePipeline;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    /**
     * @ClassName: MyCnblogsSpider
     * @author LJH
     * @date 2017年11月26日 下午4:41:40
     */
    public class MyCnblogsSpider implements PageProcessor {
    
        private Site site = Site.me().setRetryTimes(3).setSleepTime(100);
    
        public Site getSite() {
            return site;
        }
    
        public void process(Page page) {
            if (!page.getUrl().regex("http://www.cnblogs.com/[a-z 0-9 -]+/p/[0-9]{7}.html").match()) {
                page.addTargetRequests(
                        page.getHtml().xpath("//*[@id=\"mainContent\"]/div/div/div[@class=\"postTitle\"]/a/@href").all());
            } else {
                page.putField(page.getHtml().xpath("//*[@id=\"cb_post_title_url\"]/text()").toString(),
                        page.getHtml().xpath("//*[@id=\"cb_post_title_url\"]/@href").toString());
            }
        }
    public static void main(String[] args) { Spider.create(new MyCnblogsSpider()).addUrl("http://www.cnblogs.com/justcooooode/") .addPipeline(new ConsolePipeline()).run(); } }

    输出结果:

    如果你和我一样之前没有用过log4j,可能会出现下面的警告:

    这是因为少了配置文件,在resource目录下新建log4j.properties文件,将下面配置信息粘贴进去即可。

    目录可以定义成你自己的文件夹。

    # 全局日志级别设定 ,file
    log4j.rootLogger=INFO, stdout, file
    
    # 自定义包路径LOG级别
    log4j.logger.org.quartz=WARN, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{MM-dd HH:mm:ss}[%p]%m%n
    
    # Output to the File
    log4j.appender.file=org.apache.log4j.FileAppender
    log4j.appender.file.File=D:\\MyEclipse2017Workspaces\\webmagic\\webmagic.log
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%n%-d{MM-dd HH:mm:ss}-%C.%M()%n[%p]%m%n

    现在试一下,没有警告了吧?。

    爬取列表类网站例子

    列表爬取的思想都很类似,首先判定是否为列表页,若是的话将文章url加入爬取队列,不是的话就代表此时为文章页,直接爬取你要的内容就可以。

    选择一个列表类文章的网站:https://voice.hupu.com/nba

    首先判断是文章还是列表,查看几个页面后可以找到规律,利用正则表达式区分。

    page.getUrl().regex("https://voice\\.hupu\\.com/nba/[0-9]{7}\\.html").match()

    如果满足上面的正则表达式,则该url对应的是一个文章页面。

    接下来要对需要爬取的内容进行抽取,我选择了xPath(浏览器自带直接粘贴就可以)。

    WebMagic框架支持多种抽取方式,包括xPath、css选择器、正则表达式,还可以通过links()方法选择所有链接。

    记住抽取之前要获得通过getHtml()来获取html对象,通过html对象来使用抽取方法。

    ps:WebMagic好像不支持xPath中的last()方法,如果用到的话可以想其他方法代替。

    然后利用page.putFiled(String key, Object field)方法来将你想要的内容放到一个键值对中。

    page.putField("Title", page.getHtml().xpath("/html/body/div[4]/div[1]/div[1]/h1/text()").toString());
    page.putField("Content", page.getHtml().xpath("/html/body/div[4]/div[1]/div[2]/div/div[2]/p/text()").all().toString());

    如果不满足文章页的正则,就说明这是一个列表页,此时要通过xPath来定位页面中文章的url。

    page.getHtml().xpath("/html/body/div[3]/div[1]/div[2]/ul/li/div[1]/h4/a/@href").all();

    这时,你已经得到要爬取url的list,把他们通过addTargetRequests方法加入到队列中即可。

    最后实现翻页,同理,WebMagic会自动添加到爬取队列中。

    page.getHtml().xpath("/html/body/div[3]/div[1]/div[3]/a[@class='page-btn-prev']/@href").all()

    下面是完整代码,自己实现了一个MysqlPipeline类,用到了Mybatis,可以将爬下来的数据直接持久化到数据库中。

    也可以用自带的ConsolePipeline或者FilePipeline等。

    package edu.heu.spider;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import edu.heu.domain.News;
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.ResultItems;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.Task;
    import us.codecraft.webmagic.pipeline.Pipeline;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    /**
     * @ClassName: HupuNewsSpider
     * @author LJH
     * @date 2017年11月27日 下午4:54:48
     */
    public class HupuNewsSpider implements PageProcessor {
    
        // 抓取网站的相关配置,包括编码、抓取间隔、重试次数等
        private Site site = Site.me().setRetryTimes(3).setSleepTime(100);
    
        public Site getSite() {
            return site;
        }
    
        public void process(Page page) {
            // 文章页,匹配 https://voice.hupu.com/nba/七位数字.html
            if (page.getUrl().regex("https://voice\\.hupu\\.com/nba/[0-9]{7}\\.html").match()) {
                page.putField("Title", page.getHtml().xpath("/html/body/div[4]/div[1]/div[1]/h1/text()").toString());
                page.putField("Content",
                        page.getHtml().xpath("/html/body/div[4]/div[1]/div[2]/div/div[2]/p/text()").all().toString());
            }
            // 列表页
            else {
                // 文章url
                page.addTargetRequests(
                        page.getHtml().xpath("/html/body/div[3]/div[1]/div[2]/ul/li/div[1]/h4/a/@href").all());
                // 翻页url
                page.addTargetRequests(
                        page.getHtml().xpath("/html/body/div[3]/div[1]/div[3]/a[@class='page-btn-prev']/@href").all());
            }
        }
    public static void main(String[] args) { Spider.create(new HupuNewsSpider()).addUrl("https://voice.hupu.com/nba/1").addPipeline(new MysqlPipeline()) .thread(3).run(); } } // 自定义实现Pipeline接口 class MysqlPipeline implements Pipeline { public MysqlPipeline() { } public void process(ResultItems resultitems, Task task) { Map<String, Object> mapResults = resultitems.getAll(); Iterator<Entry<String, Object>> iter = mapResults.entrySet().iterator(); Map.Entry<String, Object> entry; // 输出到控制台 while (iter.hasNext()) { entry = iter.next(); System.out.println(entry.getKey() + ":" + entry.getValue()); } // 持久化 News news = new News(); if (!mapResults.get("Title").equals("")) { news.setTitle((String) mapResults.get("Title")); news.setContent((String) mapResults.get("Content")); } try { InputStream is = Resources.getResourceAsStream("conf.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession session = sessionFactory.openSession(); session.insert("add", news); session.commit(); session.close(); } catch (IOException e) { e.printStackTrace(); } } }

    查看数据库:?

    爬好的数据已经静静地躺在数据库中了。

    官方文档中还介绍了通过注解来实现各种功能,非常简便灵活。

    使用xPath时要留意,框架作者自定义了几个函数:

    ExpressionDescriptionXPath1.0
    text(n)第n个直接文本子节点,为0表示所有text() only
    allText()所有的直接和间接文本子节点not support
    tidyText()所有的直接和间接文本子节点,并将一些标签替换为换行,使纯文本显示更整洁not support
    html()内部html,不包括标签的html本身not support
    outerHtml()内部html,包括标签的html本身not support
    regex(@attr,expr,group)这里@attr和group均可选,默认是group0not support

     使用起来很方便。


    转载请注明原文链接:http://www.cnblogs.com/justcooooode/p/7913365.html

    参考资料 

    官方文档:https://github.com/code4craft/webmagic

    http://webmagic.io/docs/zh/

    xPath教程:http://www.w3school.com.cn/xpath/index.asp

    转载于:https://www.cnblogs.com/justcooooode/p/7913365.html

    展开全文
  • WebMagic入门介绍

    2020-09-01 16:10:52
    WebMagic入门介绍1.WebMagic概览1.1 设计思想1.2 总体架构1.3 项目组成 1.WebMagic概览 WebMagic项目代码分为核心和扩展两部分。核心部分(webmagic-core)是一个精简的、模块化的爬虫实现,而扩展部分则包括一些便利...

    1.WebMagic概览

    WebMagic项目代码分为核心和扩展两部分。核心部分(webmagic-core)是一个精简的、模块化的爬虫实现,而扩展部分则包括一些便利的、实用性的功能。WebMagic的架构设计参照了Scrapy,目标是尽量的模块化,并体现爬虫的功能特点。

    这部分提供非常简单、灵活的API,在基本不改变开发模式的情况下,编写一个爬虫。

    扩展部分(webmagic-extension)提供一些便捷的功能,例如注解模式编写爬虫等。同时内置了一些常用的组件,便于爬虫开发。

    另外WebMagic还包括一些外围扩展和一个正在开发的产品化项目webmagic-avalon。

    1.1 设计思想

    1. 一个框架,一个领域

    一个好的框架必然凝聚了领域知识。WebMagic的设计参考了业界最优秀的爬虫Scrapy,而实现则应用了HttpClient、Jsoup等Java世界最成熟的工具,目标就是做一个Java语言Web爬虫的教科书般的实现。

    如果你是爬虫开发老手,那么WebMagic会非常容易上手,它几乎使用Java原生的开发方式,只不过提供了一些模块化的约束,封装一些繁琐的操作,并且提供了一些便捷的功能。

    如果你是爬虫开发新手,那么使用并了解WebMagic会让你了解爬虫开发的常用模式、工具链、以及一些问题的处理方式。熟练使用之后,相信自己从头开发一个爬虫也不是什么难事。

    因为这个目标,WebMagic的核心非常简单——在这里,功能性是要给简单性让步的。

    2. 微内核和高可扩展性

    WebMagic由四个组件(Downloader、PageProcessor、Scheduler、Pipeline)构成,核心代码非常简单,主要是将这些组件结合并完成多线程的任务。这意味着,在WebMagic中,你基本上可以对爬虫的功能做任何定制。

    WebMagic的核心在webmagic-core包中,其他的包你可以理解为对WebMagic的一个扩展——这和作为用户编写一个扩展是没有什么区别的。

    3. 注重实用性

    虽然核心需要足够简单,但是WebMagic也以扩展的方式,实现了很多可以帮助开发的便捷功能。例如基于注解模式的爬虫开发,以及扩展了XPath语法的Xsoup等。这些功能在WebMagic中是可选的,它们的开发目标,就是让使用者开发爬虫尽可能的简单,尽可能的易维护。

    1.2 总体架构

    WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。WebMagic的设计参考了Scapy,但是实现方式更Java化一些。

    而Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心。

    WebMagic总体架构图如下:

    在这里插入图片描述

    1.2.1 WebMagic的四个组件

    1.Downloader

    Downloader负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

    2.PageProcessor

    PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。

    在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

    3.Scheduler

    Scheduler负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。

    除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。

    4.Pipeline

    Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。

    Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

    1.2.2 用于数据流转的对象

    1. Request

    Request是对URL地址的一层封装,一个Request对应一个URL地址。

    它是PageProcessor与Downloader交互的载体,也是PageProcessor控制Downloader唯一方式。

    除了URL本身外,它还包含一个Key-Value结构的字段extra。你可以在extra中保存一些特殊的属性,然后在其他地方读取,以完成不同的功能。例如附加上一个页面的一些信息等。

    2. Page

    Page代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。

    Page是WebMagic抽取过程的核心对象,它提供一些方法可供抽取、结果保存等。在第四章的例子中,我们会详细介绍它的使用。

    3. ResultItems

    ResultItems相当于一个Map,它保存PageProcessor处理的结果,供Pipeline使用。它的API与Map很类似,值得注意的是它有一个字段skip,若设置为true,则不应被Pipeline处理。

    1.2.3 控制爬虫运转的引擎–Spider

    Spider是WebMagic内部流程的核心。Downloader、PageProcessor、Scheduler、Pipeline都是Spider的一个属性,这些属性是可以自由设置的,通过设置这个属性可以实现不同的功能。Spider也是WebMagic操作的入口,它封装了爬虫的创建、启动、停止、多线程等功能。下面是一个设置各个组件,并且设置多线程和启动的例子。详细的Spider设置请看第四章——爬虫的配置、启动和终止。

    public static void main(String[] args) {
        Spider.create(new GithubRepoPageProcessor())
                //从https://github.com/code4craft开始抓    
                .addUrl("https://github.com/code4craft")
                //设置Scheduler,使用Redis来管理URL队列
                .setScheduler(new RedisScheduler("localhost"))
                //设置Pipeline,将结果以json方式保存到文件
                .addPipeline(new JsonFilePipeline("D:\\data\\webmagic"))
                //开启5个线程同时执行
                .thread(5)
                //启动爬虫
                .run();
    }
    

    1.2.4 快速上手

    上面介绍了很多组件,但是其实使用者需要关心的没有那么多,因为大部分模块WebMagic已经提供了默认实现。

    一般来说,对于编写一个爬虫,PageProcessor是需要编写的部分,而Spider则是创建和控制爬虫的入口。在第四章中,我们会介绍如何通过定制PageProcessor来编写一个爬虫,并通过Spider来启动。

    1.3 项目组成

    WebMagic项目代码包括几个部分,在根目录下以不同目录名分开。它们都是独立的Maven项目。

    1.3.1 主要部分

    WebMagic主要包括两个包,这两个包经过广泛实用,已经比较成熟:

    webmagic-core
    webmagic-core是WebMagic核心部分,只包含爬虫基本模块和基本抽取器。WebMagic-core的目标是成为网页爬虫的一个教科书般的实现。

    webmagic-extension
    webmagic-extension是WebMagic的主要扩展模块,提供一些更方便的编写爬虫的工具。包括注解格式定义爬虫、JSON、分布式等支持。

    1.3.2 外围功能

    除此之外,WebMagic项目里还有几个包,这些都是一些实验性的功能,目的只是提供一些与外围工具整合的样例。因为精力有限,这些包没有经过广泛的使用和测试,推荐使用方式是自行下载源码,遇到问题后再修改。

    webmagic-samples
    这里是作者早期编写的一些爬虫的例子。因为时间有限,这些例子有些使用的仍然是老版本的API,也可能有一些因为目标页面的结构变化不再可用了。最新的、精选过的例子,请看webmaigc-core的us.codecraft.webmagic.processor.example包和webmaigc-core的us.codecraft.webmagic.example包。

    webmagic-scripts
    WebMagic对于爬虫规则脚本化的一些尝试,目标是让开发者脱离Java语言,来进行简单、快速的开发。同时强调脚本的共享。

    目前项目因为感兴趣的用户不多,处于搁置状态,对脚本化感兴趣的可以看这里:webmagic-scripts简单文档

    webmagic-selenium
    WebmMgic与Selenium结合的模块。Selenium是一个模拟浏览器进行页面渲染的工具,WebMagic依赖Selenium进行动态页面的抓取。

    webmagic-saxon
    WebMagic与Saxon结合的模块。Saxon是一个XPath、XSLT的解析工具,webmagic依赖Saxon来进行XPath2.0语法解析支持。

    1.3.3 webmagic-avalon

    webmagic-avalon是一个特殊的项目,它想基于WebMagic实现一个产品化的工具,涵盖爬虫的创建、爬虫的管理等后台工具。Avalon是亚瑟王传说中的“理想之岛”,webmagic-avalon的目标是提供一个通用的爬虫产品,达到这个目标绝非易事,所以取名也有一点“理想”的意味,但是作者一直在朝这个目标努力。

    展开全文
  • 9 WebMagic 入门案例

    2019-07-31 18:13:09
    -- webmagic核心包 --> < dependency > < groupId > us.codecraft groupId > < artifactId > webmagic-core artifactId > < version > 0.7.3 version > dependency > <!-- webmagic扩展包 -->...

    0 环境准备

    创建 maven 工程,加入依赖:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.ys</groupId>
        <artifactId>crawler-webmagic</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <!-- webmagic核心包 -->
            <dependency>
                <groupId>us.codecraft</groupId>
                <artifactId>webmagic-core</artifactId>
                <version>0.7.3</version>
            </dependency>
            <!-- webmagic扩展包 -->
            <dependency>
                <groupId>us.codecraft</groupId>
                <artifactId>webmagic-extension</artifactId>
                <version>0.7.3</version>
            </dependency>
    
        </dependencies>
    
    </project>
    

    注意:0.7.3 版本对 SSL 的并不完全,如果是直接从 Maven 中央仓库下载依赖,在爬取只支持 SSL v1.2 的网站时会有 SSL 的异常抛出。
    解决方案:1、等作者的 0.7.4 的版本发布;2、直接从 github 上下载最新代码,安装到本地仓库;3、也可以参考以下资料自己修复:https://github.com/code4craft/webmagic/issues/701

    加入日志配置文件

    WebMagic 使用 slf4j-log4j12 作为 slf4j 的实现。

    添加 log4j.properties

    log4j.rootLogger = DEBUG,A1
    
    log4j.appender.A1 = org.apache.log4j.ConsoleAppender
    log4j.appender.A1.layout = org.apache.log4j.PatternLayout
    log4j.appender.A1.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
    

    1 测试

    需求:编写爬虫程序,爬取 CSDN 中博客 —— 人工智能 的内容。
    网址https://blog.csdn.net/nav/ai

    在这里插入图片描述

    package cn.ys.webmagic.test;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class JobProcessor implements PageProcessor {
    
        //解析页面
        public void process(Page page) {
    
            //解析返回的数据page,并且把解析的结果放到ResultItems中
            page.putField("div", page.getHtml().css("div.unin_reason_dialog h3").all());
        }
    
        private Site site = Site.me();
        public Site getSite() {
            return site;
        }
    
        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
                    .run();                                  //执行爬虫
        }
    }
    
    

    控制台打印:

    get page: https://blog.csdn.net/nav/ai
    div:	[<h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>]
    2019-07-31 15:55:18,138 [main] [us.codecraft.webmagic.Spider]-[INFO] Spider blog.csdn.net closed! 1 pages downloaded.
    
    

    注意:Spider 是爬虫启动的入口。在启动爬虫之前,我们需要使用一个 PageProcessor 创建一个 Spider 对象,然后使用 run() 进行启动。

    2 实现 PageProcessor

    2.1 抽取元素 Selectable

    WebMagic 里面主要使用类三种抽取技术:XPath、正则表达式和CSS选择器。另外,对于 JSON 格式的内容,可使用 JsonPath 进行解析。

    1⃣️ XPath

    XPath,即为XML路径语言(XMLPathLanguage),它是一种用来确定XML文档中某部分位置的语言。XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。

    以上是获取属性 class=mt 的 div 标签,里面的 h1 标签的内容。

    page.putField("div2",page.getHtml().xpath("//div[@class=title]/h2/a"));
    

    2⃣️ CSS 选择器

    CSS 选择器是与 XPath 类似的语言。它比 XPath 写起来要简单一些,但是如果写复杂一点的抽取规则,就相对麻烦一些。

    div.mt > h1:表示 class 为 mt 的 div 标签下的直接子元素 h1 标签。

    3⃣️ 正则表达式

    package cn.ys.webmagic.test;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class JobProcessor implements PageProcessor {
    
        //解析页面
        public void process(Page page) {
    
            //解析返回的数据page,并且把解析的结果放到ResultItems中
            page.putField("div", page.getHtml().css("div.unin_reason_dialog h3").all());
    
            //XPath
            page.putField("div2",page.getHtml().xpath("//div[@class=title]/h2/a"));
    
            //正则表达式
            page.putField("div3",page.getHtml().css("div.title h2 a").regex(".*数学.*").all());
        }
    
        private Site site = Site.me();
        public Site getSite() {
            return site;
        }
    
        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
                    .run();                                  //执行爬虫
        }
    }
    
    

    控制台打印:

    get page: https://blog.csdn.net/nav/ai
    div:	[<h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>, <h3>选择理由,精准屏蔽</h3>]
    div2:	<a href="https://blog.csdn.net/qq_40798435/article/details/95489469" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_40798435/article/details/95489469&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;0&quot;}"> 建筑施工借助物联网卡保障高楼安全 </a>
    div3:	[<a href="https://blog.csdn.net/qq_40798435/article/details/95489469" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_40798435/article/details/95489469&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;0&quot;}"> 建筑施工借助物联网卡保障高楼安全 </a>, <a href="https://blog.csdn.net/yyykj/article/details/95322311" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/yyykj/article/details/95322311&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;1&quot;}"> 转战物联网·基础篇02-物联网中的角儿 </a>, <a href="https://blog.csdn.net/weixin_43532158/article/details/95323836" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_43532158/article/details/95323836&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;2&quot;}"> 基于物联网的智能家居 </a>, <a href="https://blog.csdn.net/weixin_44452342/article/details/95049283" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_44452342/article/details/95049283&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;3&quot;}"> ZT交易所即将上线BRC(贝尔链) </a>, <a href="https://blog.csdn.net/ss5214423/article/details/96136274" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/ss5214423/article/details/96136274&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;4&quot;}"> Unity3D游戏开发笔记-2【优化】 </a>, <a href="https://blog.csdn.net/qq_40798435/article/details/95628250" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_40798435/article/details/95628250&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;5&quot;}"> 医疗行业需要物联网卡能做什么? </a>, <a href="https://blog.csdn.net/weixin_43830887/article/details/96835533" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_43830887/article/details/96835533&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;6&quot;}"> 在新加坡成立基金会做ICO交易所合规白皮书你应该知道的几个要点 </a>, <a href="https://blog.csdn.net/qq_36075612/article/details/97110898" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_36075612/article/details/97110898&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;7&quot;}"> 关注物联网、关注NB-IoT </a>, <a href="https://blog.csdn.net/bemfa/article/details/96564875" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/bemfa/article/details/96564875&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;8&quot;}"> MQTT物联网通信协议概论 </a>, <a href="https://blog.csdn.net/COMC1DU/article/details/94866252" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/COMC1DU/article/details/94866252&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;9&quot;}"> 社链生态全球发布会圆满成功,共建社链梦! </a>, <a href="https://blog.csdn.net/qq_34229678/article/details/96156404" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_34229678/article/details/96156404&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;10&quot;}"> Unity3D Network如何限制玩家人数 </a>, <a href="https://blog.csdn.net/qq_42992919/article/details/95343296" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_42992919/article/details/95343296&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;11&quot;}"> Python图形用户界面和游戏开发 </a>, <a href="https://blog.csdn.net/weixin_42411153/article/details/94840046" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_42411153/article/details/94840046&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;12&quot;}"> 物联网协议--MQTT整理 </a>, <a href="https://blog.csdn.net/kaihuiguoji/article/details/90671898" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/kaihuiguoji/article/details/90671898&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;13&quot;}"> 区块链对区块链金融有什么作用? </a>, <a href="https://blog.csdn.net/weixin_43272781/article/details/94891083" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_43272781/article/details/94891083&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;14&quot;}"> 物联网的发展与应用 </a>, <a href="https://blog.csdn.net/weixin_44452342/article/details/96572844" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_44452342/article/details/96572844&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;15&quot;}"> ZT交易所OTC商家火热招募中 </a>, <a href="https://blog.csdn.net/qq_34229678/article/details/96970866" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_34229678/article/details/96970866&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;16&quot;}"> Unity3D ()SteamVR 2.0手柄输入与震动 </a>, <a href="https://blog.csdn.net/qq_31243065/article/details/97119523" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/qq_31243065/article/details/97119523&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;17&quot;}"> Win32 游戏开发:贪吃蛇 上篇 </a>, <a href="https://blog.csdn.net/LEON1741/article/details/96888960" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/LEON1741/article/details/96888960&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;18&quot;}"> 【三分钟讲清区块链/比特币】之一:区块链入门教程 </a>, <a href="https://blog.csdn.net/PyhtonChen/article/details/96149214" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/PyhtonChen/article/details/96149214&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;19&quot;}"> Python图形界面游戏开发 </a>, <a href="https://blog.csdn.net/weixin_36628778/article/details/96507085" target="_blank" data-report-click="{&quot;mod&quot;:&quot;popu_459&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/weixin_36628778/article/details/96507085&quot;,&quot;strategy&quot;:&quot;none&quot;,&quot;index&quot;:&quot;20&quot;}"> day-012--图形用户界面和游戏开发 </a>]
    2019-07-31 16:02:53,547 [main] [us.codecraft.webmagic.Spider]-[INFO] Spider blog.csdn.net closed! 1 pages downloaded.
    
    

    2.2 抽取元素 API

    Selectable 相关的抽取元素链式 API 是 WebMagic 的一个核心功能。使用 Selectable 接口,可以直接完成页面元素的链式抽取,也无需关心抽取的细节。

    上例中可以看到,page.getHtml() 返回的是一个 html 对象,它实现类 Selectable 接口。这个接口包含的方法分为两类:抽取部分获取结果部分

    方法说明示例
    xpath(String xpath)使用 XPath 选择html.xpath("//div[@class='title']")
    $(String selector)使用 css 选择器选择html.$("div.title")
    $(String selector,String attr)使用 css 选择器选择html.$("div.title","text")
    css(String selector)功能同 $() ,使用 css 选择器选择html.css("div.title")
    links()选择所有链接html.links()
    regex(String regex)使用正则表达式抽取html.regex("\(.\*?)\")

    这部分抽取 API 返回的都是一个 Selector 接口,意思是说,是支持链式调用的。

    2.3 处理结果 API

    下面的方法是选择抽取一个或多个元素:

    方法说明示例
    get()返回一条 String 类型的结果String link = html.links().get()
    toString()get() ,返回一条 String 类型的结果String link = html.links().toString()
    all()返回所有抽取的结果List links = html.links().all()

    说明:当有多条数据时,使用 get() 或 toString() 都是获取第一个 url 地址。

    2.4 获取链接

    1⃣️ 添加目标地址,目标地址正则匹配

    我们可以通过添加目标地址,从种子页面爬取到更多的页面

    package cn.ys.webmagic.test;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class JobProcessor implements PageProcessor {
    
        //解析页面
        public void process(Page page) {
    
            //解析返回的数据page,并且把解析的结果放到ResultItems中
            page.putField("div", page.getHtml().css("div.unin_reason_dialog h3").all());
    
            //XPath
            page.putField("div2",page.getHtml().xpath("//div[@class=title]/h2/a"));
    
            //正则表达式
            page.putField("div3",page.getHtml().css("div.title h2 a").regex(".*数学.*").all());
    
            //获取链接
            page.addTargetRequests(page.getHtml().css("div.title").links().regex(".*9$").all());//以9结尾的
            page.putField("url",page.getHtml().css("div.article-title-box h1"));
        }
    
        private Site site = Site.me();
        public Site getSite() {
            return site;
        }
    
        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
                    .run();                                  //执行爬虫
        }
    }
    
    

    3 Pipeline

    • ConsolePipeline:控制台输出
    • FilePipeline:文件保存
    • JsonFilePipeline:以 JSON 方式保存
    package cn.ys.webmagic.test;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.pipeline.ConsolePipeline;
    import us.codecraft.webmagic.pipeline.FilePipeline;
    import us.codecraft.webmagic.pipeline.JsonFilePipeline;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class JobProcessor implements PageProcessor {
    
        //解析页面
        public void process(Page page) {
    
            //解析返回的数据page,并且把解析的结果放到ResultItems中
            page.putField("div", page.getHtml().css("div.unin_reason_dialog h3").all());
    
            //XPath
            page.putField("div2",page.getHtml().xpath("//div[@class=title]/h2/a"));
    
            //正则表达式
            page.putField("div3",page.getHtml().css("div.title h2 a").regex(".*数学.*").all());
    
            //获取链接
            page.addTargetRequests(page.getHtml().css("div.title").links().regex(".*9$").all());//以9结尾的
            page.putField("url",page.getHtml().css("div.article-title-box h1"));
        }
    
        private Site site = Site.me();
        public Site getSite() {
            return site;
        }
    
        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
    //                .addPipeline(new ConsolePipeline())
    //                .addPipeline(new FilePipeline("/Users/yangshuo/jd/")) //设置结果输出到文件
                    .addPipeline(new JsonFilePipeline("/Users/yangshuo/jd/")) //以 JSON 方式保存
                    .thread(5)                               //设置5个线程执行
                    .run();                                  //执行爬虫
        }
    }
    
    

    3.1 定制 Pipeline

    如果以上 Pipeline 都不能满足你的需要,你可以定制 Pipeline

    1⃣️ 创建类MyPipeline实现接口Pipeline

    package cn.ys.demo;
    import us.codecraft.webmagic.ResultItems;
    import us.codecraft.webmagic.Task;
    import us.codecraft.webmagic.pipeline.Pipeline;
    
    public class MyPipeline implements Pipeline {
    
        public void process(ResultItems resultItems, Task task) {
            String title = resultItems.get("title");
            System.out.println("我的定制的 title:"+title);
        }
    }
    

    2⃣️ 修改 main 方法

        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
    //                .addPipeline(new ConsolePipeline())
    //                .addPipeline(new FilePipeline("/Users/yangshuo/jd/")) //设置结果输出到文件
                    .addPipeline(new JsonFilePipeline("/Users/yangshuo/jd/")) //以 JSON 方式保存
                    .addPipeline(new MyPipeline())//定制化输出
                    .thread(5)                               //设置5个线程执行
                    .run();                                  //执行爬虫
        }
    

    4 Spider 方法详解

    方法说明示例
    create(PageProcessor)创建SpiderSpider.create(new GithubRepoProcessor())
    addUrl(String…)添加初始的URLspider.addUrl("http://webmagic.io/docs/")
    thread(n)开启n个线程spider.thread(5)
    run()启动,会阻塞,当前线程执行spider.run()
    start()/runAsync()异步启动,当前线程继续执行spider.start()
    stop()停止爬虫spider.stop()
    addPipeline(Pipeline)添加一个Pipeline,一个Spider可以有多个Pipelinespider .addPipeline(new ConsolePipeline())
    setScheduler(Scheduler)设置Scheduler,一个Spider只能有个一个Schedulerspider.setScheduler(new RedisScheduler())
    setDownloader(Downloader)设置Downloader,一个Spider只能有个一个Downloaderspider .setDownloader( new SeleniumDownloader())
    get(String)同步调用,并直接取得结果ResultItems result = spider.get("http://webmagic.io/docs/")
    getAll(String…)同步调用,并直接取得一堆结果List results = spider.getAll("http://webmagic.io/docs/","http://webmagic.io/xxx")

    同时Spider的其他组件(Downloader、Scheduler、Pipeline)都可以通过set方法来进行设置。

    Page代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。Page是WebMagic抽取过程的核心对象,它提供一些方法可供抽取、结果保存等。

    爬虫配置 Site

    Site用于定义站点本身的一些配置信息,例如编码、HTTP头、超时时间、重试策略等、代理等,都可以通过设置Site对象来进行配置。

    方法说明示例
    setCharset(String)设置编码site.setCharset("utf-8")
    setUserAgent(String)设置UserAgentsite.setUserAgent("Spider")
    setTimeOut(int)设置超时时间, 单位是毫秒site.setTimeOut(3000)
    setRetryTimes(int)设置重试次数site.setRetryTimes(3)
    setCycleRetryTimes(int)设置循环重试次数site.setCycleRetryTimes(3)
    addCookie(String,String)添加一条cookiesite.addCookie("dotcomt_user","code4craft")
    setDomain(String)设置域名,需设置域名后,addCookie才可生效site.setDomain("github.com")
    addHeader(String,String)添加一条addHeadersite.addHeader("Referer","https://github.com")
    setHttpProxy(HttpHost)设置Http代理site.setHttpProxy(new HttpHost("127.0.0.1",8080))

    5 Scheduler

    我们刚才完成的功能,每次运行可能会爬取重复的页面,这样做是没有任何意义的。

    Scheduler(URL管理) 最基本的功能是实现对已经爬取的URL进行标示。可以实现URL的增
    量去重。

    目前scheduler主要有三种实现方式:

    • 内存队列 QueueScheduler
    • 文件队列 FileCacheQueueScheduler
      使用文件保存抓取URL,可以在关闭程序并下次启动时,从之前抓取到的URL继续抓取
    • Redis队列 RedisScheduler
      使用Redis保存抓取队列,可进行多台机器同时合作抓取

    使用 setScheduler 来设置Scheduler

        //主函数,执行爬虫
        public static void main(String[] args) {
            Spider.create(new JobProcessor())
                    .addUrl("https://blog.csdn.net/nav/ai")  //设置爬取数据的页面
    //                .addPipeline(new ConsolePipeline())
    //                .addPipeline(new FilePipeline("/Users/yangshuo/jd/")) //设置结果输出到文件
                    .addPipeline(new JsonFilePipeline("/Users/yangshuo/jd/")) //以 JSON 方式保存
                    .thread(5)                               //设置5个线程执行
    //                .setScheduler(new QueueScheduler())      //设置内存队列
    //                .setScheduler(new FileCacheQueueScheduler("/Users/yangshuo/jd/")) //设置文件队列
                    .setScheduler(new RedisScheduler("127.0.0.1")) //设置Redis队列
                    .run();                                  //执行爬虫
        }
    
    展开全文
  • 在b站学习的webmagic代码 整体结构图 #= maven依赖 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=...
  • WebMagic入门案例与WebMagic功能 一、入门案例 加入依赖 创建Maven工程,并加入以下依赖 <dependencies> <!-- https://mvnrepository.com/artifact/us.codecraft/webmagic-core --> <dependency>...
  • WebMagic入门案例

    2020-10-04 15:41:20
    WebMagic总体架构图如下: 项目结构图 配置文件 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=...
  • 做这个工具的主要原因是,我们单位的工作环境一般要求断网,菜鸟教程上的教学作为入门一般不错,为了方便离线学习,做了这个应用;现在写了主要为了分享和自己学习总结; 第一次写博文,不完善的地方请见谅 关于 **...
  • WebMagic入门记录

    2020-11-07 18:58:00
    核心简单但是涵盖爬虫的全部流程,灵活而强大,也是学习爬虫入门的好材料。 提供丰富的抽取页面API。 无配置,但是可通过POJO 注解形式实现一个爬虫。 支持多线程。 支持分布式。 支持爬取js动态渲染的页面。 ...
  • Java网络爬虫之Webmagic快速入门

    千次阅读 2019-07-05 10:23:59
    Webmagic简介 WebMagic是一个简单灵活的Java爬虫框架。基于WebMagic,你可以快速开发出一个高效、易维护的爬虫。 以上是webmagic的官方简介,webmagic是一个用于开发网络爬虫的Java框架,底层是httpclient和jsoup...
  • 该文章仅用于自己学习整理,大部分内容来自转载 maven配置 ...webmagic-core</artifactId> <version>0.7.3</version> </dependency> <dependency> <groupId>us.c
  • WebMagic爬虫入门教程(一)简介

    万次阅读 2017-10-30 15:21:07
    webmagic是一个国内的java开源爬虫框架,它采用完全模块化的设计,功能覆盖整个爬虫的生命周期(链接提取、页面下载、内容抽取、持久化等),也支持多线程抓取、分布式抓取,并支持自动重试、自定义UA/cookie等功能。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 422
精华内容 168
关键字:

webmagic入门