WebMagic 爬虫技术

WebMagic

WebMagic 介绍

WebMagic基础架构

Webmagic 的结构分为 Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由 Spider将他们彼此组织起来。这四种组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。Spider将这几个组件组织起来,让他们可以互相交互,流程化的执行,可以认为Spider是一个大容器,也是WebMagic逻辑的核心。架构图如下:

WebMagic总体架构图

WebMagic 的四大组件

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

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

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

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

用于数据流转的对象

Request:是对 URL 地址的一层封装,一个 Request 对应一个 URL 地址。它是 PageProcessor 与 Downloader 交互的载体,也是 PageProcessor 控制 Downloader 唯一方式。在这里插入代码片

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

ResultItems:相当于一个 Map,它保存 PageProcessor 处理的结果,供 Pipeline 使用。(当字段 skip 设置为 true,则不应被 Pipeline 处理)

WebMagic 功能

实现 PageProcessor

抽取元素 Selectable

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

Xpath

page.getHtml().Xpath("//div[@class=mt]/h1/text()")

CSS 选择器

page.getHtml().css("div.p_in li.bk")

正则表达式

html.css("div.t1 span").regex(".*发布")

抽取元素 API

当链式调用结束时,我们一般都想要拿到一个字符串类型的结果。这时候就需要用到获取结果的API了。

方法说明示例
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

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

☆ 当有多条数据的时候,使用get()和toString()都是获取第一个url地址;all()则会获取到所有元素。

获取链接

//  获取下一列的url
String bkUrl = page.getHtml().css("div.p_in li.bk").nodes().get(1).links().toString();
//  把url放到任务队列中
page.addTargetRequest(bkUrl);

使用 Pipeline 保存结果

WebMagic用于保存结果的组件叫做 Pipeline

保存到文件中

public static void main(String[] args) {
    Spider.create(new JobProcessor())
            //初始访问url地址
            .addUrl(url)
            .addPipeline(new FilePipeline("D:/webmagic/"))
            .thread(5)//设置线程数
            .run();
}

保存到数据库中

@Autowired
private SpringDataPipeline springDataPipeline;

//  initialDelay:当任务启动后,等等多久执行方法
//  fixedDelay:每隔多久执行方法
@Scheduled(initialDelay = 1000,fixedDelay = 10000)
public void process(){
    Spider.create(new JobProcess())
            .addUrl(url)
            .thread(10)
            .addPipeline(springDataPipeline)
            .run();
}

SpringDataPipeline 类

@Component
public class SpringDataPipeline  implements Pipeline {

    @Autowired
    private JobInfoService jobInfoService;


    @Override
    public void process(ResultItems resultItems, Task task) {
        //获取封装好的招聘详情对象
        JobInfo jobInfo = resultItems.get("jobInfo");

        //判断数据是否不为空
        if (jobInfo != null) {
            //如果不为空把数据保存到数据库中
            this.jobInfoService.save(jobInfo);
        }
    }
}

爬虫的配置、启动和终止

Spider

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

    public void process(){
    Spider.create(new JobProcess())
            ...
            .run();
}
方法说明示例
create(PageProcessor)创建SpiderSpider.create(new GithubRepoProcessor())
addUrl(String…)添加初始的URLspider .addUrl(spider .addUrl(“https://www.baidu.cn/”))
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”)

爬虫配置Site

Site.me()可以对爬虫进行一些配置配置,包括编码、抓取间隔、超时时间、重试次数等。

private Site site = Site.me()
        .setCharset("gbk")//设置编码
        .setTimeOut(10 * 1000)//设置超时时间
        .setRetrySleepTime(3000)//设置重试的间隔时间
        .setRetryTimes(3);//设置重试的次数
方法说明示例
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))
posted @ 2020-02-29 13:11  追风少年潇歌  阅读(135)  评论(0)    收藏  举报