探秘WebMagic:爬虫神器

3 篇文章 0 订阅

一、介绍

WebMagic是一款基于Java的开源网络爬虫框架,能够快速、灵活、高效地实现网络数据的爬取和抽取。WebMagic支持多线程、分布式、自动重试等特性,而且使用起来也非常方便。

二、优点

1. 快速:使用了NIO框架,能够高效地进行网络通信,提高爬虫效率。

2. 灵活:支持自定义爬取规则,能够适应不同的网站结构和数据格式。

3. 高效:采用了异步非阻塞的方式,同时支持多线程和分布式部署,提高爬虫的效率和稳定性。

4. 易用:提供了简单易懂的API,开发者能够快速上手。

三、四大组件

1. Downloader(页面下载组件):负责下载网页,可选择不同的下载器。

2. PageProcessor(页面处理组件):对下载的页面进行处理,包括解析页面,提取有用的数据等。

3. Pipeline(结果输出组件):负责对 PageProcessor 处理出的结果进行处理,可以将结果存储在文件、数据库、搜索引擎等地方。

4. Scheduler(URL管理器):用于管理待抓取的 URL 队列,保证数据的准确性和抓取效率,还支持使用Redis等分布式存储来实现分布式抓取。

四、使用场景

1. 数据采集:能够帮助企业或个人快速、高效地获取网络上的数据,用于数据挖掘、业务分析等领域。

2. 站点监测:能够监测特定网站的变化,如新闻、价格、商品等,帮助企业及时了解市场动态。

3. 网络抓取:WebMagic可以模拟人类浏览器从网站抓取页面和内容,在网站的每个层次上收集信息和数据,从而构建完整的产品目录和分类。

五、注意事项

1. 避免反爬虫机制:一些网站会设置反爬虫机制,需要通过模拟浏览器行为、使用代理等方式进行规避。

2. 控制爬取速度:过快的爬取速度会给网站带来负担,同时也容易被网站封禁IP。

六、补充内容

1. 多语言支持:WebMagic有Python和Scala等语言的版本,能够适应不同开发者的需求。

2. 爬虫任务调度:WebMagic能够与Quartz等任务调度框架结合使用,实现定时爬取数据的功能。

3. WebMagic支持多线程:能够利用多核CPU提高爬虫效率。

4. WebMagic支持多种功能:Cookie、代理等功能,能够模拟登录、避免反爬等操作。

5. WebMagic支持多种格式的数据存储:如MySQL、Redis、Elasticsearch等,方便后续数据处理。

6. 处理异常情况:WebMagic能够处理一些异常情况,如页面404、解析错误等,提高爬虫的健壮性。

七、实际场景

1. 案例一

    (1) 场景

    爬取一个简单的页面。

    (2) 代码

    pom.xml

<!--web magic-->
<dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-core</artifactId>
    <version>0.8.0</version>
</dependency>
<dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-extension</artifactId>
    <version>0.8.0</version>
</dependency>

    WebMagicCase1.java

/**
 * 简单的WebMagic爬取页面案例
 *
 * @author wxy
 * @since 2023-05-30
 */
public class WebMagicCase1 {
    public static void main(String[] args) {
        String[] urls = new String[]{
                "https://blog.csdn.net/qq_45871274/article/details/129162237"
        };

        new MyTask().execute(urls);
    }
}

    MyTask.java

import us.codecraft.webmagic.Spider;

/**
 * 爬取任务
 *
 * @author wxy
 * @since 2023-05-30
 */
public class MyTask {
    public void execute(String... url) {
        Spider spider = Spider
                // 指定页面解析器
                .create(new MyProcessor())
                // 指定爬取结果的处理器
                .addPipeline(new MyPipeline())
                .addUrl(url)
                // 创建3个线程
                .thread(3);
        //异步爬取
        spider.start();
    }
}

    PageProcessor.java

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;

import java.util.ArrayList;
import java.util.List;

/**
 * 页面解析
 *
 * @author wxy
 * @since 2023-05-30
 */
public class MyProcessor implements PageProcessor {
    @Override
    public void process(Page page) {
        String pageStrHtml = page.getHtml().get();
        Document pageHtmlDocument = Jsoup.parse(pageStrHtml);
        List<String> contentList = new ArrayList<>();
        // 获取文章标题
        Elements title = pageHtmlDocument
                .select("h1[id=articleContentId]");
        // 写入标题文本内容
        page.putField("title", title.text());

        // 获取文章内容
        Elements contents = pageHtmlDocument
                .select("div[id=content_views]");
        for (Element content : contents) {
            for (Element element : content.children()) {
                // 写入每一个标签中的文本内容
                contentList.add(element.text());
            }
            // 写入文章全部文本内容
            page.putField("contents", contentList);
        }
    }

    @Override
    public Site getSite() {
        //在爬取页面时对http请求的一些设置 例如编码、HTTP头、超时时间、重试策略 等、代理等
        return Site.me()
                // 重试次数
                .setRetryTimes(3)
                // 间隔时间
                .setSleepTime(100)
                // 设置超时时间
                .setTimeOut(10000);
    }
}

    MyPipeline.java

 

import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import java.util.List;

/**
 * 爬取结果的处理
 *
 * @author wxy
 * @since 2023-05-30
 */
public class MyPipeline implements Pipeline {
    @Override
    public void process(ResultItems resultItems, Task task) {
        // 打印文章标题文本内容(在这里解析并保存至数据库)
        System.out.println("文章标题: ");
        System.out.println(resultItems.get("title").toString());
        // 打印文章内容文本内容
        List<String> contents = resultItems.get("contents");
        System.out.println("文章内容: ");
        for (String content : contents) {
            System.out.println(content);
        }
    }
}

最后将爬取的文章标题和内容输出:

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

學陽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值