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

news/2024/5/19 9:47:08/文章来源:https://blog.csdn.net/weixin_34474759/article/details/113687512

@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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_844849.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大型网站系统架构演化之路

大型网站系统架构演化之路 前言 一个成熟的大型网站(如淘宝、天猫、腾讯等)的系统架构并不是一开始设计时就具备完整的高性能、高可用、高伸缩等特性的,它是随着用户量的增加,业务功能的扩展逐渐演变完善的,在这个过程…

java支付宝支付,支付手机支付,pc网站支付

1:在撸代码之前 先去开通支付宝支付的账户 提交私钥 公钥一系列反锁的 事情 下面简单介绍一下我的支付过程 以下是整个项目的结构 只是做了个支付的测试 所有结构很简单 大神勿喷: 上面的 lib里面的 jar 大部分都可以在 支付宝的官方dome里面下载 当然 在写完文章 我会附上我…

Instagram.com网站性能优化之路:第一部分

原文:https://instagram-engineering.com/making-instagram-com-faster-part-1-62cc0c327538作者:Glenn Conner翻译:奶爸码农近年来,instagram.com发布了许多功能-我们推出了故事,过滤器,创建工具&#xff…

Instagram.com网站性能优化之路:第二部分 - 数据推送

近年来,Instagram发布了许多功能-我们推出了故事,过滤器,创建工具,通知和消息直递,以及许多其他功能和优化。但是,随着产品功能的增长,一个不幸的副作用是我们的网络性能开始下降。在过去的一年…

Instagram网站性能优化之路:第三部分 - 缓存优先

原文:https://instagram-engineering.com/making-instagram-com-faster-part-3-cache-first-6f3f130b9669作者:Glenn Conner翻译:奶爸码农近年来,Instagram发布了许多功能-我们推出了故事,过滤器,创建工具&…

Instagram.com网站性能优化之路:完结篇-代码大小和执行优化

近年来,Instagram发布了许多功能-我们推出了故事,过滤器,创建工具,通知和消息直递,以及许多其他功能和优化。但是,随着产品功能的增长,一个不幸的副作用是我们的网络性能开始下降。在过去的一年…

让网站更快、更可访问与更安全 - 这里有来自谷歌的新建议

这是奶爸码农第67篇原创文章,点击上方蓝字关注从6月30日到7月2日,Google的网络平台团队将Web.dev LIVE的网络社区召集在一起,这是一个在线技术分享活动,旨在讨论平台和工具生态系统的最新发展,使开发人员有机会相互交流…

aspnet网站开发实例_「前言」网站开发实例:公文处理系统(登记部分)一

需求分析与市场分析(简版)电子公文的归档工作是档案管理工作和电子政务建设的重要内容之一,电子公文归档系统作为一个连接办公自动化系统和数字档案管理系统的桥梁,在文档一体化管理体系中占据着重要位置。与传统纸质文档登记归档相比,电子公…

shell脚本监控网站,异常则进行邮件报警

服务器系统centos7.6 1、安装邮箱服务,一般服务器都已经安装了,查看是否安装。 yum list mailx rpm -qa | grep mail 查看是已经安装了。 未安装的执行命令安装即可。 yum -y install mailx 配置mail,配置文件路径/etc/mail.rc vim /etc/mail.rc 在尾部…

云上网站通用解决方案

在创业型公司或阿米巴模式经营的公司,新项目发布初期存在较大的不确定性,既要考虑项目未来的扩展性,又要衡量项目的运营成本。本解决方案为客户提供低成本,敏捷快捷的最佳实践。 典型行业:传统企业、游戏和零售等行业…

阿里云企业通用场景解决方案--企业建站

业务痛点及解决方案* 从企业前期筹备到创立初期,一站式服务为初创企业提供便利,让初创企业得到省心、省时、省钱的服务 阿里云解决方案 一站式提供从公司注册到财税法等各项代办服务,高效透明,省时省心。 解决方案简介 公司注…

搭建网站的简单粗暴方法概述

作者:fearlazy个人主页:fearlazy.com 对于不懂网站的人来说想要搭建自己的网站还是比较 困难的。好在现在很多东西都可以用现成的,这使得我们要搭建一个网站的时间成本大大降低了。在这里我们使用阿里云服务器wampserverzblog的组合方式简…

记网站由http改为https的几个步骤

环境:centos7 apache 1.申请证书 最新申请证书请参考:https://www.fearlazy.com/index.php/post/315.html 下载证书: 根据自己的web服务器选择下载即可。 2.上传证书到服务器 可以在web服务器程序目录下创建一个目录存放证书 mkdir /et…

微服务接入oauth2_分分钟让自己的网站接入 GitHub 第三方登录功能

今日干货刚刚发表查看:66666回复:666公众号后台回复 ssm,免费获取松哥纯手敲的 SSM 框架学习干货。OAuth2 和小伙伴们已经聊了很多了,咱们来一个实际点的案例练练手。这里我才用 GitHub 来做第三方登录。为什么是 GitHub 呢?有两方面考虑&…

求导数(导数计算器)网站 Derivative Calculator

Derivative Calculator 比如求x的平方的导数, 输入pow(x, 2), 点击go. 点击go, 然后会生成如下结果,包括了响应的函数图形.

LaTex常用技巧7:常用网站(公式和表格编辑器)

本文记录了本人编辑LaTex表格和公式常用的网站: 表格编辑器公式编辑器表格编辑器 网站1: 表格 编辑和生成器 支持LaTex Markdown多种格式 跟Markdown LaTex csv sql等和表格相关的都可以在这个网站里面找到。TableConvert 网站2: Tables G…

一个包含简明教程的网站:cheat-sheets.org

你听过Cheat-Sheets.org吗?在这里可以看到各种简明教程,包含了大部分的编程语言,C、C#、Jave、Python、sql、html、css、matlab、qt、mfc、shell、R……甚至还有photoshop、illustrator各种快键键汇总,真的短小精悍!&a…

科研英文写作常用网站【持续更新】

1. bing词典 https://www.bing.com/dict?FORMZ9LHS4 例句很丰富。还没有广告。 2.英语表达同义替换 2.1 https://kmcha.com/similar 2.2 https://synonym.wordhippo.com/ 2.3 https://www.powerthesaurus.org/

太强了?京东大咖10年经验汇总:亿级流量网站核心架构笔记

经历过“双11”和“618”的同学都知道,在大促时如何保证系统的高并发、高可用是非常重要的事情。因此在备战大促时,有些通用原则和经验可以帮助我们在遇到高并发时,构建更可用的系统,如限流、降级、水平扩展和隔离解耦等。通过这些…

服务器论坛有哪些_网站降权常见的处理方法都有哪些?

要说在网站优化过程中害怕出现的情况,降权就是其中的一个,要知道网站降权会导致网站流量大幅度下降,关键词排名消失等现象,那么大家是否了解网站降权常见的处理方法都有哪些吗?1.网站服务器的稳定性在网站优化的过程中大家都会了…