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 nginxOSX用户可以用Homebrew:
brew install nginxWindows用户可以下载安装包
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.`); });这样就非常简单,不过缺点就是无法动态地处理。