在弄一个Nodejs爬虫框架,类似于 alfred workflow,拖拖拽拽加少量的 script就可以写出一个爬虫~

在弄一个Nodejs爬虫框架,类似于 alfred workflow,拖拖拽拽加少量的 script就可以写出一个爬虫~

前两天突发奇想搞了一个爬虫框架,主要思想借鉴了alfred workflow和ios开发里的storyboard。

每一个爬虫只需要一个配置文件,demo在config.yaml里:从点评的搜索结果页开始爬起,抓取每一家商户的信息

components:
initializer:   
  type: initializer
  segues:
    - to: shopList
      func: 
        |
        offer("http://www.dianping.com/search/category/1/0");
shopList:   
  type: pageProcessor
  segues:
    - to: shopList
      func: 
        |
        var nextPage=$(".NextPage");
        if(!nextPage){
           return;
        }         
        offer("http://www.dianping.com"+nextPage.attr("href"));
    - to: shop
      func: 
        |
        $(".BL").each(function() {
           offer("http://www.dianping.com"+($(this).attr("href")));
        })
shop:   
  type: pageProcessor
  segues:
    - to: mongodb
      func: 
        |
        offer({
           shopName:$(".shop-title").text()
        });
mongodb:   
  type: mongodbAdaptor
  host: 127.0.0.1
  port: 27017
  collection: shop

解释一下这个配置文件: component是一个个功能单元,有处理页面的,有把数据持久化到db的 segue是连接各个component的(to:发送到哪个component,func:把什么数据发过去,通过offer函数) 比如shopList的两个segue,第一个segue是把下一页的链接也发给自己处理,第二个是把商户页的链接交给shop这个component处理~

附上项目地址 https://github.com/yucong/spiderman

目前主要的核心逻辑已经都实现了,就差把配置文件弄成像storyboard那样的可视化编辑了~


2 回复

好的,我们可以创建一个类似于 Alfred Workflow 的 Node.js 爬虫框架。该框架允许用户通过简单的拖拽和少量的脚本编写来构建爬虫任务。我们将使用 YAML 文件作为配置文件,并通过 JavaScript 来解析这些配置文件并执行相应的操作。

项目结构

spiderman/
├── config.yaml
├── lib/
│   ├── spiderman.js
│   └── components/
│       ├── initializer.js
│       ├── pageProcessor.js
│       └── mongodbAdaptor.js
└── package.json

配置文件 (config.yaml)

components:
  initializer:   
    type: initializer
    segues:
      - to: shopList
        func: 
          |
          offer("http://www.dianping.com/search/category/1/0");
  shopList:   
    type: pageProcessor
    segues:
      - to: shopList
        func: 
          |
          var nextPage=$(".NextPage");
          if(!nextPage){
            return;
          }         
          offer("http://www.dianping.com" + nextPage.attr("href"));
      - to: shop
        func: 
          |
          $(".BL").each(function() {
            offer("http://www.dianping.com" + $(this).attr("href"));
          })
  shop:   
    type: pageProcessor
    segues:
      - to: mongodb
        func: 
          |
          offer({
             shopName: $(".shop-title").text()
          });
  mongodb:   
    type: mongodbAdaptor
    host: 127.0.0.1
    port: 27017
    collection: shop

核心逻辑 (lib/spiderman.js)

const yaml = require('js-yaml');
const fs = require('fs');

// 加载配置文件
const config = yaml.load(fs.readFileSync('./config.yaml', 'utf8'));

// 初始化组件
const components = {};
config.components.forEach((name, component) => {
  components[name] = require(`./components/${component.type}`);
});

// 开始执行
function start(componentName) {
  const component = components[componentName];
  const segues = config.components[componentName].segues;

  for (let segue of segues) {
    const nextComponent = components[segue.to];
    const result = component(segue.func);
    nextComponent(result);
  }
}

// 启动初始化组件
start('initializer');

示例组件 (lib/components/initializer.js)

module.exports = function(func) {
  // 执行传入的函数
  eval(func);

  // 返回结果供下一个组件使用
  return { result };
};

示例组件 (lib/components/pageProcessor.js)

module.exports = function(func) {
  // 模拟请求并获取 HTML
  const html = getHTMLFromURL(url); // 假设有一个函数可以获取 HTML
  
  // 使用 jQuery 解析 HTML
  const $ = cheerio.load(html);
  
  // 执行传入的函数
  eval(func);

  // 返回结果供下一个组件使用
  return { result };
};

示例组件 (lib/components/mongodbAdaptor.js)

const MongoClient = require('mongodb').MongoClient;

module.exports = function(func) {
  // 连接到 MongoDB
  MongoClient.connect(`mongodb://${func.host}:${func.port}`, (err, client) => {
    if (err) throw err;
    
    const db = client.db();
    const collection = db.collection(func.collection);
    
    // 插入数据
    collection.insertOne(func.offer, (err, res) => {
      if (err) throw err;
      
      console.log("Data inserted successfully!");
      client.close();
    });
  });
};

运行项目

首先安装所需的依赖:

npm install js-yaml cheerio mongodb

然后运行 spiderman.js 脚本:

node lib/spiderman.js

这样,我们就实现了一个简单的 Node.js 爬虫框架,它可以根据配置文件自动生成爬虫任务。


为了实现一个类似于 Alfred Workflow 的 Node.js 爬虫框架,我们可以设计一个配置文件来描述爬虫的工作流程。这个配置文件可以定义不同的组件(如页面处理器、初始化器等),以及这些组件之间的数据传递方式。下面是一个简化的示例,展示如何使用 YAML 配置文件来实现这样的框架。

示例配置文件

components:
  initializer:
    type: initializer
    segues:
      - to: shopList
        func: |
          offer("http://www.dianping.com/search/category/1/0");

  shopList:
    type: pageProcessor
    segues:
      - to: shopList
        func: |
          const nextPage = $(".NextPage");
          if (!nextPage) {
            return;
          }
          offer("http://www.dianping.com" + nextPage.attr("href"));

      - to: shop
        func: |
          $(".BL").each(function() {
            offer("http://www.dianping.com" + $(this).attr("href"));
          });

  shop:
    type: pageProcessor
    segues:
      - to: mongodb
        func: |
          offer({
            shopName: $(".shop-title").text()
          });

  mongodb:
    type: mongodbAdaptor
    host: 127.0.0.1
    port: 27017
    collection: shop

解释

  • Initializer: 这是一个初始化组件,它会启动爬虫并提供初始 URL。
  • PageProcessor: 这是一个页面处理器组件,它会处理页面中的数据,并决定下一步的操作。
  • Segues: 这是不同组件之间的连接,定义了如何将数据从一个组件传递到另一个组件。
  • offer: 这是一个函数,用于传递数据给下一个组件。

实现思路

  1. 读取配置文件:首先需要解析 YAML 文件以获取配置信息。
  2. 创建组件:根据配置文件中定义的类型创建不同的组件实例。
  3. 数据传递:通过 offer 函数将数据传递给下一个组件。
  4. 执行操作:每个组件执行特定的任务,例如抓取页面、处理数据或存储到数据库。

示例代码片段

以下是一个简单的代码片段,展示了如何根据配置文件启动爬虫:

const yaml = require('js-yaml');
const fs = require('fs');

// 读取配置文件
const config = yaml.load(fs.readFileSync('config.yaml', 'utf8'));

// 创建组件实例
const components = {};
for (let componentName in config.components) {
  const componentConfig = config.components[componentName];
  switch (componentConfig.type) {
    case 'initializer':
      components[componentName] = new Initializer(componentConfig);
      break;
    case 'pageProcessor':
      components[componentName] = new PageProcessor(componentConfig);
      break;
    case 'mongodbAdaptor':
      components[componentName] = new MongoDBAdaptor(componentConfig);
      break;
  }
}

// 启动爬虫
components[config.initializer.to].start();

这个简单的示例代码展示了如何根据配置文件创建组件,并启动爬虫流程。实际的实现中还需要处理更多的细节,例如网络请求、DOM 操作和数据存储等。

回到顶部