Fig (无花果)任务流水线式 多线程框架使用
程序员文章站
2022-07-13 21:12:29
...
介绍
Fig 是为了简化多线程开发和多台服务器间实现数据多流水线运行的平台(需要redis进行多服务器的数据共享)通过Fig可以加快数据的处理速度 尤其适合开发多线程爬虫程序 Fig 在开发多线程程序时 ,需要继承Fig类,并在需要执行的方法上声明@task注解 (Fig 还支持使用JavaScript,jython,Groovy,clojure开发Fig任务模块,使用脚本语言开发模块时,脚本语言中的函数名为任务名,Groovy脚本除外)接下来通过一个demo讲解一下Fig框架在java中的具体使用方法。
Fig git地址 : https://gitee.com/iproject/fig
Fig 的 Demo 讲解
我们先看一下具体的代码:
package com.github.test.price;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.github.taomus.fig.core.engine.Data;
import com.github.taomus.fig.core.engine.Fig;
import com.github.taomus.fig.core.engine.FigEngine;
import com.github.taomus.fig.core.engine.Scheduler;
import com.github.taomus.fig.core.engine.Task;
//定义个Fig模块类 该类必须继承Fig类才能被FigEngine运行引擎识别
public class PriceComparison extends Fig {
public static void main(String[] args) throws InterruptedException {
//向FigEngine引擎注册运行模块
FigEngine.getInstance().addModule(PriceComparison.class);
//通过调取器传入需要执行的第一个任务来触发整个任务的执行,如果有Fig模块类有个多个同名的任务都会被同时触发执行
List<Data> res = Scheduler.getInstance().run(Data.create("start", "铅笔"));
System.out.println(res);
}
//定义一个任务用来从 当当网采集数据
@Task("start")
public Data dd(Data value) {
String dangdang = "http://search.dangdang.com/?key=";
String productName = (String) value.getData();
String url = StringUtils.join(Arrays.asList(dangdang, productName), "");
List<String> res = new Vector<String>();
for (int i = 0; i < 10; i++) {
try {
if (i > 0) {
url = StringUtils.join(Arrays.asList(dangdang, productName, "&act=input&page_index=", i + 1), "");
}
Document document = Jsoup.connect(url).timeout(5000).get();
Elements uls = document.select("ul[class=bigimg cloth_shoplist]");
Iterator<Element> ulIter = uls.iterator();
while (ulIter.hasNext()) {
Element ul = ulIter.next();
Elements lis = ul.select("li");
Iterator<Element> liIter = lis.iterator();
while (liIter.hasNext()) {
Element li = liIter.next();
Elements price = li.select("p[class=price]>span");
String productPrice = price.html().replaceAll("¥", "");
Elements title = li.select("p[class=name]>a");
String productName2 = title.attr("title");
res.add(String.join(",", Arrays.asList(productName2, productPrice)));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//将采集到的数据 通过Data数据类型将包装传递给calc任务进行处理
return Data.create("calc", res);
}
//定义一个任务用来从京东采集数据
@Task("start")
public Data jd(Data value) {
String jdurl = "http://search.jd.com/Search?keyword=";
List<String> res = new Vector<String>();
try {
String productName = (String) value.getData();
String url = jdurl + productName;
for (int i = 0; i < 10; i++) {
try {
if (i > 0) {
url = StringUtils.join(Arrays.asList(jdurl,"&enc=utf-8&page=",i+1),"");
}
Document document = Jsoup.connect(url).timeout(5000).get();
Elements uls = document.select("ul[class=gl-warp clearfix]");
Iterator<Element> ulIter = uls.iterator();
while (ulIter.hasNext()) {
Element ul = ulIter.next();
Elements lis = ul.select("li[data-sku]");
Iterator<Element> liIter = lis.iterator();
while (liIter.hasNext()) {
Element li = liIter.next();
Element div = li.select("div[class=gl-i-wrap]").first();
Elements title = div.select("div[class=p-name p-name-type-2]>a");
String productName2 = title.attr("title"); // 得到商品名称
Elements price = div.select(".p-price>strong>i");
String productPrice = price.text(); // 得到商品价格
res.add(String.join(",", Arrays.asList(productName2, productPrice)));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
}
//将采集到的数据 通过Data数据类型将包装传递给calc任务进行处理
return Data.create("calc", res);
}
//定义一个calc任务,因为采集到的京东和当当的数据都是由start任务进行触发执行的,所以在调用calc任务的时候会将京东和当当的数据已集合的方式合并传递到calc任务
@Task
public Data calc(Data value) {
//这个方法我没有写具体的处理方法,直接将数据类型设置为RESULTS,这样就会将结果直接返回并供调用端使用,调用端现在是将数据打印到控制台显示了
value.setType(Data.Type.RESULTS);
return value;
}
}
执行结果
[Data [
name = "calc"
data = Vector (
Vector (
",5.00",
"【得力618,精品文具不止5折】倾情相伴,不负热爱。,16.60",
"【得力618,精品文具不止5折】倾情相伴,不负热爱。,9.00",
"中华绿杆经典2B铅笔,优质铅芯,涂卡考试美术素描好选择,9.20",
"中华红黑经典款,书写流畅,易写不易断,7.90",
"【得力618,精品文具不止5折】倾情相伴,不负热爱。,19.90",
",9.90",
"三角笔杆,握笔凹洞引导正确握姿,优质铅芯,专为儿童设计推荐:黄杆铅笔,68.00",
"【3件7折!晨光618!青春加油战!】\n优质石墨铅芯,涂写顺滑,木杆材质,耐压耐摔更多钜惠满减单品点击抢购,24.50",
...
),
Vector (
" 猫太子洞洞笔 铅笔小学生无毒2BHB三角杆初学者矫正握姿幼儿园小学学习文具儿童2b考试铅笔48支装,8.90",
" 晨光洞洞铅笔HB/2H/2B三角六角形考试铅笔美术绘图书写铅笔50/桶,6.90",
" 洞洞铅笔矫正握姿得力优+小学生铅笔学生铅笔HB三角杆洞洞笔儿童铅笔幼儿园铅笔初学者一二年级,16.50",
" 铅笔小学生专用HB红杆带橡皮擦头铅笔无铅无毒一年级初学者铅笔考试原木铅笔不易断铅六角儿童学习文具用品,9.00",
" 【每满100减50】得力s928六角铅笔HB小学生书写铅笔 儿童用写字铅笔50支桶装,46.80",
...
)
)
source = null
type = RESULTS
priority = 1
timestamp = 1623552642212
]]