NodeJs从零构建代理ip池(二)项目框架介绍与搭建

《原文地址》

此小节项目源码:simple-proxy-pool

Eggjs 是阿里开源的一个企业级的 Nodejs web 基础框架。使用 Eggjs 再结合官网文档过一遍,就可以很容易上手了。

采用 Eggjs 搭建项目的框架, 《EggJs 官网文档》。

零、总结

  1. 初始化项目框架,并运行起来
  2. 实现一个简单的爬虫,抓取代理 IP

一、初始化项目

# 初始化项目
$ npx egg-init simple-proxy-pool --type=simple
$ cd simple-proxy-pool
$ npm i

# npm安装慢的话,可以使用cnpm
$ npm i -g cnpm
$ cnpm i

# 启动项目
$ npm run dev
$ open localhost:7001
image

二、目录结构

这里可以去看下《Eggjs 目录结构说明》, 这里有详细的解释。

项目开发中,会用到的目录有主要是以下这些

app/router.js 用于配置 URL 路由规则
app/controller/** 用于解析用户的输入,处理后返回相应的结果
app/service/** 用于编写业务逻辑层,可选,建议使用
config/config.{env}.js 用于编写配置文件
config/plugin.js 用于配置需要加载的插件 【数据库插件,模板渲染插件等】
app/schedule/** 用于定时任务 【定时抓取数据,定时清洗无用数据】

三、 写一个简单的爬虫

爬虫,简单的理解,就是发出一个 http 请求,拿到页面的 html 内容,然后解析 html 内容,得到自己想要的数据。

这里需要使用三个 npm 库

  1. request 用来发出 http 请求,
  2. request-promise promise 形式的 request 库, promise 化主要是为了方便 配置 async 和 await 使用
  3. iconv-lite html 页面的编码如果是 gbk 的时候,会乱码,因此需要用这个库解码一下。
# 安装需要的库
cnpm i --save request request-promise iconv-lite
# 重新启动项目
cnpm run dev
// simple-proxy-pool/app/controller/home.js
'use strict'

const Controller = require('egg').Controller
const iconv = require('iconv-lite')
const rp = require('request-promise')

class HomeController extends Controller {
  /**
   * 抓取代理IP
   * @param {number} [ipCount=100] 代理数量
   * @return {array} 抓取回来的代理列表
   */
  async get66ipData(ipCount = 100) {
    try {
      // 抓取的页面地址
      const apiURL = `http://www.66ip.cn/nmtq.php?getnum=${ipCount}&isp=0&anonymoustype=0&start=&ports=&export=&ipaddress=&area=0&proxytype=2&api=66ip`

      // 设置HTTP请求参数
      const options = {
        method: 'GET',
        url: apiURL,
        gzip: true,
        headers: {
          Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
          'Accept-Encoding': 'gzip, deflate',
          'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4',
          'User-Agent':
            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
          referer: 'http://www.66ip.cn/',
          Cookie:
            'yd_cookie=35c72298-25ad-4321acee5c54def5342d0a3b37ebf11f72c2; _ydclearance=9b6308ea1deb3b3b72c14f64-142a-4adf-9107-694c8922918b-1543373100; Hm_lvt_1761fabf3c988e7f04bec51acd4073f4=1541736200,1542009395,1542297692,1543365902; Hm_lpvt_1761fabf3c988e7f04bec51acd4073f4=1543365915',
          Host: 'www.66ip.cn'
        }
      }

      // 发出http请求
      let data = await rp(options)

      // 如果是 gbk ,则使用icnov 来转
      // node环境不支持 gbk,因此会乱码
      if (/meta.+charset=gbk/i.test(data)) {
        data = iconv.decode(data, 'gbk')
      }

      // 清洗出代理ip
      const proxyList = data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1,4}/g)

      // 把数据解析成约定的格式(数据库的格式)
      const newList = []
      proxyList.forEach(item => {
        newList.push({
          ip: item.split(':')[0],
          port: item.split(':')[1],
          anonymous: '高匿',
          source: 'http://www.66ip.cn/'
        })
      })

      return newList
    } catch (error) {
      console.warn('get proxy list error ...')
      return error
    }
  }

  async index() {
    // 因为获取代理ip是异步的,因此配合promise化的request, 可以直接使用 await来处理异步
    // 不用像早起写成功回调
    this.ctx.body = await this.get66ipData()
  }
}

module.exports = HomeController

注意点:抓取数据的时候,可能因此没有代理 ip 网站的有反爬虫机制,因此需要做一些特殊的处理。 比如这个网站 需要携带 cookie ,否则会报 521 错误。

运行结果


image

此小节项目源码:simple-proxy-pool

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,799评论 25 707
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,699评论 2 59
  • 在上网的时候,看到一句话,觉得还是很有道理的,为什么我们会觉得网友是贴心的,因为他们从来不麻烦你。 不知道你有没有...
    碎忆录阅读 1,031评论 0 0
  • 引用一个学长的一段话: “在途中与友人聊天,感叹资源的各种不公平的分配。资源往往都是被占有,而不是被利用。那些被占...
    小漆江西阅读 312评论 0 1