webmagic mysql_WebMagic爬虫框架(爬取前程无忧网站的招聘信息保存到mysql数据库)...

本文介绍了如何使用WebMagic爬虫框架爬取前程无忧网站的招聘信息,并将数据存储到MySQL数据库。文章详细讲解了PageProcessor、Scheduler、Downloader和Pipeline四大组件的职责,以及Request、Page和ResultItems等对象的使用。同时,提供了SpringBoot项目环境搭建、配置文件、实体类、爬虫类和数据存储的实现,还提到了爬虫的去重和代理服务器的使用需求。
摘要由CSDN通过智能技术生成

@PageProcessor、Scheduler、Downloader和Pipeline。

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

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

WebMagic总体架构图

3b4b98f9b277608256444733c974e829.png

一,WebMagic的四大组件

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

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

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

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

二,用于数据流转的对象

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

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

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

三,项目开始前的热身(解析页面的方式)

项目maven添加了下面要求的maven坐标之后就可以写下面的测试代码了。

下面的测试很清楚的讲解了解析页面的方式,以及爬虫的执行。

page.putField()是把爬取到的数据添加到了ResultItems中,默认在控制台打印出来。

public class JobProcessor implements PageProcessor {

//解析页面

public void process(Page page) {

//解析返回的数据page,并且把解析的结果放在resultItems中

//css选择器解析

//page.putField("爬取内容",page.getHtml().css("span.service_txt").all());//all()是返回所有数据,get()是返回第一条数据

//XPath解析

//page.putField("xpath方法解析结果",page.getHtml().xpath("//div[@id=J_cate]/ul/li/a").all());

//正则表达式解析(筛选内容带“装”字的所有信息)

page.putField("正则",page.getHtml().css("div#J_cate ul li a").regex(".*装.*").all());

//获取链接

// page.addTargetRequests(page.getHtml().css("div#shortcut-2014 div.w ul.fl li#ttbar-home a").links().all());

// page.putField("url",page.getHtml().css("div#shortcut div ul li a span").all());

}

private Site site=Site.me()

.setCharset("utf8") //设置编码

.setTimeOut(10000) //设置超时时间 单位是ms毫秒

.setRetrySleepTime(3000) //设置重试的时间间隔

.setSleepTime(3); //设置重试次数

public Site getSite() {

return site;

}

/*设置request请求方式

Request requests=new Request("http://www.12371.cn/cxsm/gzbs/");

requests.setMethod(HttpConstant.Method.GET);

Spider.create(new JobProcessor())

//.addUrl(url)

.addRequest(requests)

.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))

.thread(5)

.addPipeline(this.newsData)

.run();

*/

//主函数,执行爬虫

public static void main(String[] args) {

Spider spider=Spider.create(new JobProcessor()).addUrl("https://www.jd.com")//设置爬取数据的页面

// .addPipeline(new FilePipeline("D:\\result"))//使用Pipeline保存数据到指定文件夹中,自动生成文件

.thread(5) //多线程进行爬取,5个多线程,速度更快

.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000)));//设置布隆去重过滤器,指定最多对1000万数据进行去重操作

//默认HashSet去重

//Scheduler scheduler=spider.getScheduler();

spider.run();//run()执行爬虫

}

}

四,SpringBoot项目环境搭建

首先搭建好一个springboot项目,加入mysql,mybatis,webmagic的核心依赖以及扩展依赖,以及添加WebMagic对布隆过滤器的支持的依赖。

org.springframework.boot

spring-boot-starter-web

2.1.3.RELEASE

mysql

mysql-connector-java

8.0.13

org.mybatis

mybatis

3.4.6

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.0.1

us.codecraft

webmagic-core

0.7.3

org.slf4j

slf4j-log4j12

us.codecraft

webmagic-extension

0.7.3

com.google.guava

guava

16.0

org.apache.commons

commons-lang3

3.9

五,配置文件

在resources文件夹新建log4j.properties文件配置日志

log4j.rootLogger=INFO,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

在新建application.properties文件配置数据库

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC

spring.datasource.username=root

spring.datasource.password=1234

六,Let's go WebMagic!

1,启动类

@SpringBootApplication

@MapperScan("com.qianlong.dao")//扫描mapper文件

@EnableScheduling //开启定时任务,定时抓取数据

@ComponentScan(value = "com.qianlong")//包扫描

public class App {

public static void main(String[] args) {

SpringApplication.run(App.class,args);

}

}

2,实体类(存储到数据库表的字段)

public class JobInfo {

private Integer id;

private String companyName;

private String companyAddr;

private String companyInfo;

private String jobName;

private String jobAddr;

private String salary;

private String time;

}

3,爬虫类

package com.qianlong.task;

import com.qianlong.entity.JobInfo;

import org.jsoup.Jsoup;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

import us.codecraft.webmagic.Page;

import us.codecraft.webmagic.Site;

import us.codecraft.webmagic.Spider;

import us.codecraft.webmagic.processor.PageProcessor;

import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;

import us.codecraft.webmagic.scheduler.QueueScheduler;

import us.codecraft.webmagic.selector.Html;

import us.codecraft.webmagic.selector.Selectable;

import java.util.List;

@Component

public class JobProcessor implements PageProcessor {

//前程无忧网站的职位列表地址

private String url="https://search.51job.com/list/170200,000000,0000,00,9,99,%2B,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=";

@Override

public void process(Page page) {

//解析页面,获取招聘信息详情的url地址

List list = page.getHtml().css("div#resultList div.el").nodes();

//判断集合是否为空

if(list.size()==0){

//如果为空,表示这是招聘详情页,解析页面,获取招聘详情信息,保存数据

this.saveJobInfo(page);

}else {

//如果不为空,表示这是列表页,解析出详情页的url地址,放到任务队列中

for(Selectable selectable:list){

String jobInfoUrl = selectable.links().toString();

//把获取到的详情页的url地址放到任务队列中

page.addTargetRequest(jobInfoUrl);

}

//获取下一页按钮的url

String bkUrl=page.getHtml().css("div.p_in li.bk").nodes().get(1).links().toString();//get(1)拿到第二个

//把下一页的url放到任务队列中

page.addTargetRequest(bkUrl);

}

}

//解析页面,获取招聘详情信息,保存数据

private void saveJobInfo(Page page) {

//创建招聘详情对象

JobInfo jobInfo=new JobInfo();

//拿到解析的页面

Html html = page.getHtml();

//获取数据,封装到对象中

//两种获取的方法,一种是直接html.css,另一种是使用Jsoup.parse解析html字符串

jobInfo.setCompanyName(html.css("div.cn p.cname a","text").toString());

String addrStr = Jsoup.parse(html.css("div.cn p.msg").toString()).text();

String addr=addrStr.substring(0,addrStr.indexOf("|"));

jobInfo.setCompanyAddr(addr);

jobInfo.setCompanyInfo(html.css("div.tmsg","text").toString());

jobInfo.setUrl(page.getUrl().toString());

jobInfo.setJobName(Jsoup.parse(html.css("div.cn h1","title").toString()).text());

jobInfo.setJobAddr(addr);

jobInfo.setSalary(Jsoup.parse(html.css("div.cn strong").toString()).text());

//把结果保存起来

page.putField("jobInfo",jobInfo);

}

private Site site=Site.me()

.setCharset("gbk")//设置编码(页面是什么编码就设置成什么编码格式的)

.setTimeOut(10*1000)//设置超时时间

.setRetrySleepTime(3000)//设置重试的间隔时间

.setRetryTimes(3);//设置重试的次数

@Override

public Site getSite() {

return site;

}

//这里注入SaveData

@Autowired

private SaveData saveData;

//initialDelay当任务启动后,等多久执行方法

//fixedDelay每个多久执行方法

@Scheduled(initialDelay = 1000,fixedDelay = 100*1000)

public void process(){

Spider.create(new JobProcessor())

.addUrl(url)

.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000)))

.thread(10)

.addPipeline(this.saveData)//指定把爬取的数据保存到SaveData类的ResultItems中

.run();

}

}

4,获取爬到的数据并保存到数据库

前面爬取的数据(封装到了实体类)都保存在了ResultItems对象中

57ec4170d5e3c970ec0955369aa51de0.png

这里取出前面保存的数据(实体类),然后把数据存到数据库

package com.qianlong.task;

import com.qianlong.entity.JobInfo;

import com.qianlong.service.Service;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import us.codecraft.webmagic.ResultItems;

import us.codecraft.webmagic.Task;

import us.codecraft.webmagic.pipeline.Pipeline;

@Component

public class SaveData implements Pipeline {

@Autowired

Service service;

@Override

public void process(ResultItems resultItems, Task task) {

//获取封装好的招聘详情对象

JobInfo jobInfo=resultItems.get("jobInfo");

if(jobInfo!=null){

//保存数据到数据库中

service.saveJobInfo(jobInfo);

}

}

}

5,dao和service

public interface Dao {

@Insert(value = "insert into jobinfo(companyName,companyAddr,companyInfo,jobName,jobAddr,salary,url) values(#{companyName},#{companyAddr},#{companyInfo},#{jobName},#{jobAddr},#{salary},#{url});")

int saveJobInfo(JobInfo jobInfo);

}

public interface Service {

int saveJobInfo(JobInfo jobInfo);

}

@Service

public class ServiceImpl implements Service {

@Autowired

private Dao dao;

@Override

public int saveJobInfo(JobInfo jobInfo) {

int i = dao.saveJobInfo(jobInfo);

return i;

}

}

然后运行启动类,控制台出现下图就是爬取成功了

69c972f2bb00c0a5dabf704c195e1e1c.png

爬取的数据保存到数据库成功

dbb4b4b6cbe62a9705ed11dcdb809005.png

七,后话

至于WebMagic的完整使用,还需要涉及到代理服务器,因为有一些网站是禁止爬取的,它会查到你的ip地址并给你禁掉,所以这时就需要代理服务器。以及爬取数据的去重问题,还要借助一些其他的工具平台进行处理整合,所以,有待完善。

a8ee729b4d8be2170ab16ca2948e085c.png

每天进步一点点,有问题留言兄弟盟!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值