Nodejs 爬蟲框架,支援佇列

wl879發表於2017-12-04

介紹一個簡單的爬蟲框架,重點就是簡單,那就直接來試一下吧。

開始

Nodejs 爬蟲框架,支援佇列

[此處有圖片,載入有點慢]

我們來慢動作看一下都發生了什麼。

  ~ $ npm install crawl-pet -g複製程式碼

安裝 crawl-pet

  ~ $ cd /Volumes/M/download複製程式碼

進入到你想要新建專案的目錄

  download $ crawl-pet new複製程式碼

新建專案,根據提示填寫引數

  ctrl + c複製程式碼

如果爬取的規則需要自定義,先退出,篇輯專案下的 crawler.js 檔案

  module.exports = {
      /****************
       * Info part
       ****************/
      projectDir: __dirname,
      url : "https://imgur.com/r/funny",
      outdir : "/Volumes/M/download/imgur.com",
      saveMode : "group",
      keepName : true,
      limits : 5,
      timeout : 60000,
      limitWidth : 400,
      limitHeight : 400,
      proxy : "http://127.0.0.1:1087",
      userAgent : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
      cookies : null,
      fileTypes : "png|gif|jpg|jpeg|svg|xml|mp3|mp4|pdf|torrent|zip|rar",
      sleep : 1000,
      crawl_data : {},
  ​
      // crawl_js : "./parser.js",/****************
       * Crawler part
       *****************/
      // init(queen) {},
      prep(queen) {
          let url = queen.head.url;
          let m = url.match(/^(https?:\/\/)?(([\w\-]\.)?imgur.com)\/*/i);
          if (m) {
              url = (!m[1] ? 'https://' : '') + url.replace(/\/page(\/\d+(\/hit\.json)?)?$|\/+$/i, '');
              if (!/\/(new|top|hot)$/i.test(url)) {
                  url += '/new';
              }
              queen.head.url = url + '/page/0/hit.json';
              queen.save('api_url', url);
              queen.save('page_offset', 0);
          }
      },
      // start(queen) {},
      // filter(url) {},
      // filterDownload(url) {},
      // willLoad(request) {},
      loaded(body, links, files, crawler) {
          if (!/hit\.json/i.test(crawler.url)) {
              return;
          }
          try {
              let json = JSON.parse(body);
              let data = json.data;
              if (!data || data.length === 0) {
                  return;
              }
              let add_down = 0;
              for (let pic of data) {
                  if (crawler.appendDownload('https://i.imgur.com/' + pic.hash + pic.ext)) {
                      add_down += 1;
                  }
              }
              if (add_down) {
                  let api_url = crawler.read('api_url');
                  let offset = crawler.read('page_offset');
                  let add = 5;
                  while (add-- > 0) {
                      offset++;
                      crawler.appendPage(api_url + '/page/' + offset + '/hit.json');
                  }
                  crawler.save('page_offset', offset);
              }
          } catch (err) {
              // PASS
          }
      },
      // browser(crawler) {}
  }複製程式碼

說明一下,這裡重寫了兩個函式,prep(queen) / loaded(body, links, files, crawler) , 檢視更多點這裡

prep(queen) 是預處理,專案的第一次執行,與重置後第一次執行,會呼叫這個函式。這裡,根據 Imgur 的api,對啟始連結做了一些修改。

Imgur 的地址結構是:

  https://imgur.com/ 分類 / 排序方法 / page/ 頁數 /hit.json 
複製程式碼

loaded(body, links, files, crawler) 是每當頁面載入後會呼叫這個函式。

body 是頁面的文字,crawler 就是爬蟲了,可能通過 crawler.appendPage(url)crawler.appendDownload(url) 新增要爬取的址

這個例子中,因為請求的頁面都是json 的,所以需要先把文字解成 json, 然後用appendDownload 將圖片的 url 新增到下載佇列, 如果返回 false,說明圖片重複已下載過了,如果有新的圖片可以下載,就再生成 5 個新的頁面,appendPage 新增到佇列。

介紹一個實用命令

可以通過本地的檔名,查詢到下載的連結地址

  $ crawl-pet -f local "CstcePq.png"複製程式碼

更多命令請檢視幫助

  ~ $ crawl-pet -h複製程式碼

-------------------------------------------------------------------

GIthub 地址:github.com/wl879/crawl…

專案裡的 crawlers 資料夾中有一些示例,有福利啊。


相關文章