scrapy ip代理池如何在开发过程中搭建简单的假数据服务器

scrapy ip代理池本文是姚家艺同学的处女投稿,家艺同学目前在大B站,在一次开发过程中遇到后端木有及时提供接口的情况下,便诞生了此文。也欢迎大家来投稿~

在开发一块新功能的过程中,我们通常会涉及到与后端接口联调的问题。新的界面、新的后端接口,这时候在开发的时候往往前端就很尴尬,后端不依赖前端,但是前端十分依赖后端。

大部分应用都会有或多或少地依赖后端数据,有的界面只需要简单搞个假数据传入即可,但是我们还需要应对很多复杂情况,比如:

处理无数据、返回错误、各类非scrapy ip代理池正常的状态;

处理分页数据的情况;

模拟一个请求中、请求失败、请求结果返回的情景;

这时候如果能够写一个简单的服务器,你请求真实的接口url,只需要给手机设置一个代理,就返回你设置的假数据。这样你就可以完全抛开其他依赖的顾虑,可以像正常情况一样开发、校验结果,而不是依赖写死在代码里的各种假逻辑(这样做也会为后面的开发带来一些隐患)。

实际上服务器本身的逻辑是非常简单的,但是要真正得搭建成你所需要的环境,需要一些复杂功夫。本文以nodejs为例,具体描述一下如何scrapy ip代理池在本机上搭建测试服务器。

使用node搭建起简单的服务器脚本

1. 安装

Unix 用户可以使用命令行安装nodejs。

Windows 用户可以直接下载安装包。

安装成功后如果在命scrapy ip代理池令行下输入node -v能够打印出版本信息,说明安装成功了。

2. 简单服务器

Node 服务器可以运行在“IP:PORT”上,我们可以通过如下代码来在127.0.0.1:2333端口上搭建起一个简单的服务器:

server.js

const http = require(http); http.createServer( (req, res) => {  // 返回码200,返回头中标识内容为json  res.writeHead(200, {Content-Type: text/json});  let resp = {    code : 0,    time : ,    data : {      name : desmond,      gender : male    }  };  res.end(JSON.stringify(resp)); // 将resp转换为JSON字符串返回。}).listen(2333, 127.0.0.1, )

之后输入node server.js,然后我们到浏览器中访问localhost:2333就可以看见:

具体的信息可以参考Nodejs-http.

3. IDE配置

从IDE环境切换到脚本环境来写代码总会不顺手,推荐一个我认为比较容易scrapy ip代理池上手的配置吧:

编辑器 Sublime Text 3,没啥好说的,好用。

代码补全 TernJS, Tern-Sublime,是js下代码提示、补全的利器,极其推荐!

错误检查 ESLint, SublimeLinter-ESLint 是一款js的静态检查、错误提示的利器,Sublime的插件也非常好用,配置很简单。

配上这三个,你就会觉得用起来已经蛮舒服了。

Nginx反向代理

nginx 搭建服务器的强大处之一就是它的代理能力,配置也十分简洁。

如果要模拟最终的请求的话,我们应该是原封不动的保留请求url: ‘www.desmond.com/api/something’。首先我们需要 在手机上设置代理,将ip配置到自己电脑上,端口配为80 。但是你的电脑识别到这个请求后,怎么让它导流到你的node服务器,这是一个问题。scrapy ip代理池如果你代码写死的ip+端口来访问,未免有点太low了,我们既然折腾了这么多,那可以继续往下走一步:反向代理。

反向代理,简而言之,就是一个分发请求的代理。前向代理 是直接发给目标服务器,但是它会做一些额外的处理工作。反向代理不一样,它自己相当于是一个服务器,请求到它手里,它根据请求去不同服务器上拉取数据。

1. 安装Nginx

Linux用户可以使用命令行:

apt-get update apt-get install nginx

OSX用户可以用Homebrew:

brew install nginx

Windows用户可以下载安装包

2. 配置代理

我们希望针对’www.desmond.com/api/something’下的url交由node服务器(2333端口)处理,其他情况下继续发送,可以在nginx.conf里面这么配置(可以在命令行下输入nginx -t找到配置文件位置):

server {    listen       本机ip:80;    server_name  www.desmond.com;    #charset koi8-r;    access_log  /Users/desmond/Nginx/api.access.log;    error_log  /Users/desmond/Nginx/api.error.log;    location / { //默认情况原路继续        resolver 8.8.8.8;        proxy_pass ;        proxy_set_header Host $http_host;        proxy_connect_timeout 5;    }    location /api {      //检测到api路径下的,转发到端口2333        proxy_pass :2333;      }    #error_page  404  /404.html;    # redirect server error pages    # to the static page /50x.html    #    error_page   500 502 503 504  /50x.html;    location = /50x.html {        root   html;    } }

这里如果希望原路继续的那些url域名解析配合你的host(此处使用8.8.8.8来做DNS解析),你可以参考StackOverflow的一个提问。

这样一来,你所有手机上访问的www.desmond.com/api/something就导到你的nodejs服务器上啦,尽情配置假数据来测试吧~~

4. 配合Charles使用

如果使用Charles的话,手机上一般配的代理是”ip:8888”,那么此时需要做一件事:本地的host设置本机ip www.desmond.com,这样才能保证 www.desmond.com域名下的请求被导流到nginx服务器,从而导流到自己的nodejs服务器上。

最终搭建

直接使用node,还是有一些繁琐的。既然我们的目的是“简单”,scrapy ip代理池那么可以考虑一下使用express 。它封装了很多API,然呢使用起来非常方便。其中一项就是路由(Route)。它意思简单来说就是: www.desmond.com/api/a 由 a 的逻辑处理,www.desmond.com/api/b 由 b 的逻辑处理。

我相信一个新模块的服务器接口肯定不止一个,假如我们现在接口文档上写着:

1. 提交个人信息:www.desmond.com/api/personal 方法:POST 返回示例: {  code : 0,  time : } 2. 获取未来n天天气信息:www.desmond.com/api/weather 方法:GET 参数:day 未来天数 返回示例: {  code : 0,  time : ,  data : {    items : [      date : 2016-08-02,      state : sunny    ],    //...  } }

那么你可以使用来做一个简单的ROUTE+请求处理:

server.js

const express = require(express);const url = require(url);let app = express(); app.post(/api/personal,    function (req, res) { //针对/api/personal 的 post请求返回    res.writeHead(200,    {Content-Type:    text/json;charset=utf-8});    res.end(JSON.stringify({    code : 0,    time :  })); }); app.get(/api/weather,    function (req, res) { //针对/api/weather 的 get请求返回    res.writeHead(200,    {Content-Type:    text/json;charset=utf-8});  let count = url.parse(req.url, true).query.day; //解析传入的day参数  if(count) { //若有,根据day参数生成item    let tmpList = [];        let tmpDate = new Date();        for(let i = 0; i < count; i++ ) {      tmpDate.setDate(tmpDate.getDate() + 1);      tmpList.push({        date : `${tmpDate.getFullYear()}        -${tmpDate.getMonth() + 1}        -${tmpDate.getDate()}`,        state : `sunny - ${i}`      });    }    res.end(JSON.stringify({      code : 0,      time : ,      items : tmpList    }));  } else { //若无,则返回错误信息    res.end(JSON.stringify({      code : -1,      msg: you must send param \"day\",      time :    }));  } }); app.listen(2333, function(req, res) {    console.log(`You have run node host.`); });

注意:不要忘记安装express,(npm install express —save)即可。

编辑结束后运行一下node server.js,你可以看到输出:

You have run node host.

这时我们可以尝试请求一下 localhost:2333,可以看到返回:

大功告成~~

如果希望node server一直在后台跑(使用node server.js时shell会卡在当前运行中),可以使用ForeverJS。

更简单的办法

如果不想折腾太多,可以直接写一个json静态文件去返回:

data.json

{  "code" : 0,  "time" : }

*注意:手写json的话,里面的 key 必须以字符串形式(双冒号包围)存在。

server.js

const fs = require(fs);const express = require(express);let app = express(); app.get(/api/weather,  function (req, res) { //针对/api/weather 的 get请求返回  res.writeHead(200,    {Content-Type:     text/json;charset=utf-8});  fs.readFile(data.json, utf8, (err, data) => { //读取data.json    if(err) { //错误时返回异常      res.end(JSON.stringify({        code : -1,        msg : Read File error!      }));      return;    }    res.end(data);  }); }); app.listen(2333, function(req, res) {  console.log(`You have run node host.`); });

这样就非常简单,不过缺点就是无法动态地处理。