国庆的时候发现了一个小游戏,积分可以通过分享好友并点击链接获得,判定挺简单的样子。于是为了买到新皮肤,开始动手尝试。

screenshoot

代理

首先断开 WiFi,通过移动网络再次访问链接,积分增加。恩第一步就成功了,看来是通过 IP 判断的。

然后尝试修改请求 Header 的 X-Forwarded-For 并向目标发起请求,发现积分并没有增加。

$ curl http://xxx.me/ -H 'X-Forwarded-For: 1.1.1.1' -I
HTTP/1.1 200 OK
Server: Tengine
Content-Type: text/html
Content-Length: 7823
Connection: keep-alive
...

那对方可能是通过 remoteAddress 获取 IP 的,谷歌 “免费代理 IP” 终于找到一个有用的,再次发起请求,发现积分增加了,好开心呀

$ curl -x 122.96.59.104:81 http://xxx.me -I
HTTP/1.1 200 OK
Server: Tengine
Content-Type: text/html
Content-Length: 7823
Connection: keep-alive
...

就这样简单搞定啦。

然后简单提一下 X-Forwarded-For 和 remoteAddress。前者是一个 HTTP 扩展头部,请求从客户端到达目标服务器的过程中,中间经过的代理服务器(反向代理或者非高度匿名的正向代理)会把客户端的真实 IP 和代理 IP 记录在 X-Forwarded-For 中,类似 X-Forwarded-For: client, proxy0, proxy1,但由于头部可被自由修改所以不可信;后者无法伪造,否则无法在客户端和服务器之间建立连接。

而使用高度匿名的正向代理的话,代理服务器将我们的数据包原封不动的转发,在服务端看来就好像真的是一个普通客户端在访问,而记录的IP是代理服务器的IP。

proxy

然后每次手动寻找靠谱的代理 IP 然后发起请求效率太低啦,于是就继续看爬虫要怎么搞了。

爬虫

这里简单地爬取页面表格中的代理 IP,程序访问页面获得 HTML 文本然后过滤得到有效的信息,大概是这样的做法。每次爬取完成后直接使用而不入库,因为免费的 IP 质量太低啦而且我也不需要很大的量,类似的功能用 Node.js 配合 cherrio 就可以完成了(这个时候会想自己是个前端真是太好了)。

简单代码如下:

import request from 'request'
import cheerio from 'cheerio'
// request 配置
let option = {
url: 'http://free.ip',
timeout: 5e3,
headers: {
'User-Agent': 'Mozilla/5.0'
}
}
// 处理回调
let callback = function (process) {
return function (err, response, body) {
if (!error && response.statusCode === 200) {
process(body)
}
}
}
// 收集 IP
let process = function (body) {
let $ = cheerio.load(body)
$('#list .ip')
.map(
(index, el) => $(el).text()
)
.forEach(
ip => console.log(ip)
)
}
// 发起请求
request(option, callback(process))

然后这里模拟 UA 是因为如果 UA 不合理部分网站会直接拒绝请求。

类似的功能也封装成了 Faker,可以很方便地爬取数据和扩展。示例如下:

import faker from 'faker'
faker
.extend(require('faker/extend/xicidaili'))
.run()
.then(function (hosts) {
// hosts => ['http://100.10.10.10:80', ...]
// do something
})

大概内容就这些,皮肤也买到啦,玩的开心~