Web scraper使用Rx.js迭代页面

时间:2015-12-19 07:28:45

标签: javascript asynchronous reactive-programming rxjs

大约一个月前,我构建了this web scraper using Async / Await作为收集网络抓取器信息的异步​​方式。我正在尝试使用Rx.js再次构建相同的刮刀。我已经阅读了文档并且它似乎有意义,从最开始是最困难的一点,但在那个驼峰之后我取得了一些进展。

你可以在这里看到我在网站上找到了第一页(第0页),我需要使用该页面来获取页数(大约6000页)。我有这个数字并使用getPageURI(page)我可以创建每个网页网址,但我的问题是我无法弄清楚如何triggerfire或{{1} }信息回到原始pipe。我有这个页面计数,我需要一种方法来迭代它将数据推回到第一个原始pageRequestStream流。

pageRequestStream

1 个答案:

答案 0 :(得分:2)

看一下subjects,它们可以让你随时发射事件。

也许这可以作为一些灵感

import cheerio from 'cheerio';
import Rx from 'rx';
import fetch from 'isomorphic-fetch';

function getCheerio(url) {
  var promise = fetch(url)
        .then(response => response.text())
        .then(body => cheerio.load(body));
  return Rx.Observable.fromPromise(promise);
}

const DIGITAL_NYC_URI = 'http://www.digital.nyc';

var pageRequest = new Rx.Subject();

pageRequest
  .flatMap(pageUrl => getCheerio(pageUrl))
  .flatMap(page$ => {
    // here we pipe back urls into our original observable.
    var nextPageUrl = page$('ul.pagination li.arrow a').attr('href');
    if(nextPageUrl) pageRequest.onNext(DIGITAL_NYC_URI + '/' + nextPageUrl);

    var profileUrls = page$('h3.node-title a')
          .map(function() {
            var url = page$(this).attr('href');
            return DIGITAL_NYC_URI + '/' + url;
          });
    return Rx.Observable.from(profileUrls);
  })
  .flatMap(url => getCheerio(url))
  .map(profile$ => {
    // build the company profile here
    return profile$('title').text();
  })
  .subscribe(value => console.log('profile ',  value));

pageRequest.onNext(DIGITAL_NYC_URI + '/startups');