我如何使用ProxyScrape 代理服务器赢得 ipinfo.io 商品

Jan-19-20245 分钟阅读

嘿,我是 Benji,一个ProxyScrape 用户,我喜欢捣鼓系统,研究程序在后台是如何工作的。我还做一些服务器管理的工作,偶尔也写写代码 (https://benji.link)。ProxyScrape 让我写一点关于我使用他们的代理服务器的事情,所以我们开始吧:2023 年万圣节,ipinfo.io 举行了

嘿,我是 Benji,一个ProxyScrape 用户,我喜欢捣鼓系统,研究程序在后台是如何工作的。我还做一些服务器管理的工作,偶尔也写写代码(https://benji.link)。ProxyScrape 让我写一点我使用他们的代理服务器的情况,所以就写到这里了:

在 2023 年万圣节,ipinfo.io 举办了"万圣节狩猎 "竞赛,要求用户使用 IPinfo 应用程序提交 IP 和 GPS 数据。我猜他们是想改进他们的 IP 数据,而我们则有机会赢得一些商品。

在连续两周的时间里,他们每天都会从提交的作品中挑选一位用户赢得当天的商品。这样就不是完全的数字游戏,而是有一定的运气成分。

我开始了我的旅程,这可能是它的初衷,只是有些自动化。我在手机上设置了一个缓慢的自动点击功能,用于打开/关闭飞行模式,以强制从 ISP 获取新的移动 IP。这个方法很有效,但速度很慢,每分钟只能给我提供大约 2-3 个 IP。

在我开始考虑更快的方法之前,我用手机用这种方法总共获得了大约 400-500 个 IP。

那天一回到家,我就开始逆向设计这个应用程序,看看有没有什么办法可以让我轻松绕过系统,在不使用手机的情况下使用代理服务器。

在检查了应用程序的网络流量后,我注意到向 json 端点("https://ipinfo.io/json")发送的所有请求中只有一个请求包含您的设备 ID。


HTTP 工具包监控通过 IPinfo 应用程序的流量截图。(设备 ID 高亮显示)

我首先尝试复制其中一个请求并使用代理,但请求没有被接受。经过反复试验,我发现这与请求中发送的额外信息有关。

设备 ID 和端点 URL 是该请求中唯一重要的信息。

在删除所有其他细节,使请求中只有设备 ID 而无其他信息后,它开始工作了。

url = "https://ipinfo.io/json?token=app_test"


headers = {
  'Host': 'ipinfo.io',
  'User-Agent': 'IPinfo/Android-Lib/3.0.6/IPinfo',
  'x-conn-details': 'device_id=d813353d28df2ad3'
}

设备 ID 可以从任何安装了该程序的手机上复制,我也许可以做一些东西,让它在没有程序的情况下为我生成 ID,但这不值得这么麻烦。

现在唯一要做的就是使用代理服务器,这是最简单的部分。

我决定使用ProxyScrape 住宅代理服务器,因为我从一次促销活动中获得了一些免费数据,它们让我获得了数千个唯一 IP。

我一开始只用了一个非常简单的脚本,像这样发送了 100 个请求:


这样做效果很好,速度从每分钟约 2-3 个 IP 提高到每分钟约 30 个 IP(每个请求耗时 0.5-2 秒)。

为了进一步提高速度,因为这对我来说还不够快,我想实现一些简单的线程来并发发送请求。

import requests
import concurrent.futures
import time
import random


# open the proxies.txt file and read the proxies
proxies = open("proxies.txt", "r").read().split("\n")


url = "https://ipinfo.io/json?token=app_test"


device_ids = {
  "3d8e0d7245a92152",
  "a9c7b2b233dd06b8",
  "661035895999a7fe",
  "d813353d28df2ad3",
  "982078c380f4fe38"
}


success_count = 0


def send_request(i):
  global success_count
  try:
    # pick a random number between 1 and 1000
    rand = random.randint(1, 10000)
    proxy = {"https": proxies[rand]}
    device_id = random.choice(list(device_ids))


    payload = {}
    headers = {
        'Host': 'ipinfo.io',
        'User-Agent': 'IPinfo/Android-Lib/3.0.6/IPinfo',
        'x-conn-details': 'device_id={}'.format(device_id)
    }


    response = requests.request("GET", url, headers=headers, data=payload, proxies=proxy, timeout=20)
    print("Request #{}: \n{} \nTime taken: {}\n".format(i, response.text, response.elapsed.total_seconds()))
    success_count += 1
  except Exception as e:
    print("Request #{}: Error - {}".format(i, str(e)))


with concurrent.futures.ThreadPoolExecutor() as executor:
  futures = []
  for i in range(500):
    time.sleep(0.02)  # wait for 100ms before starting each thread
    futures.append(executor.submit(send_request, i))


  try:
    for future in concurrent.futures.as_completed(futures):
      future.result()
  except KeyboardInterrupt:
    print("Program interrupted by user.")
    for future in futures:
      future.cancel()
  except Exception as e:
    print("An error occurred:", str(e))


print("Success count:", success_count)

为了以防万一,我添加了几个不同的设备 ID,并从 ProxyScrap 中获得了 10 000 个 1 分钟轮换一次的代理列表,将其粘贴到 proxies.txt 中。我还确保在启动每个线程之间添加较短的休眠时间,这样就不会在完全相同的时间内同时启动所有线程。(这似乎会造成问题)。

现在,我只需更改 "range(500) "中的数字,就能计算出数千个 IP。

所有这些变化让我每分钟都能获得几百个 IP。然后,在为期两周的狩猎中,我继续每天发送几千个 IP。

根据活动组织者提供的数据,我成功获得了 14.9 万个独立 IP,不过我怀疑我发送了更多的 IP。这让我获得了全球第六名的好成绩,并得到了一些精美的商品。
您可以在这里查看比赛结果: https://community.ipinfo.io/t/the-great-ip-hunt-is-over/3906

我给自己买了一个贴纸包、一件 "我是狩猎马拉松优胜者 T 恤"、一张印有互联网地图的记事卡和一些 IPinfo 袜子。

这些都是在 3 周后到达的:

作为免责声明,IPinfo 团队原本以为该应用程序会被反向工程化,但实际上他们非常高兴地了解到人们是如何找到创造性的解决方案来解决这些问题的。

最后,这是一段有趣的时光,我们结识了新朋友,学习了一些关于代理和安卓逆向工程的知识,当然还得到了一些免费的商品。

本吉