果粉们忍够了!——App Store下载提速脚本

2012-04-03 21:41 by hackerzhou

首先申明一点,我不是果粉,虽然我用各种苹果产品,但是我最喜欢的手机牌子依旧是火腿肠(HTC),最喜欢的笔记本牌子依旧是ThinkPad。写本文的主要目的是方便国内使用苹果设备的同学们,想必大家都碰到过在国内下载App Store龟速的情况。价格不菲的苹果产品在天朝几Mb的带宽下竟然在以数十KB的速度下载,是相当不能忍的事情。其实原因很简单,苹果在大陆没有服务器,外国人做的软件貌似都不太了解中国国情,在这个互联网自由基本靠翻墙的神奇国度里,iTunes不增加动态检测可用的以及最快的服务器的功能真是弱爆了。不知道CEO 库克的来访是不是预示着苹果公司对中国市场越来越重视,不过国外公司无法在境内建造数据中心,必须有落地的本土企业才行,估计苹果服务器要落地内地比较难。

虽说iTunes自身不会那么智能的选择最快的接入点,但是我们可以帮它一把。网上之前也有过介绍类似PingInfoView之类批量Ping工具来找到相应最快的服务器的文章,大都hardcode了一些服务器IP,但哪些文章没有解决的就是如何得到哪些IP的,一旦苹果更改了服务器IP,那么一切都完了。所以,今天下午写了一个简单的Python脚本来动态的挑选最快的服务器。

不多说,先上代码(以下是我写的部分,没有包含我调用的Python Ping的代码,完整版请见:
https://github.com/hackerzhou/Scripts/blob/master/optimize_app_store_hosts.py
完整版脚本可以直接用(sudo) python optimize_app_store_hosts.py调用,运行完成后会在当前目录下生成两个文件,apple_ip.txt包含了App Store不同的IP地址以及各自的ping响应时间,hosts文件包含了一个自动选取ping响应最快的那个IP生成的hosts列表,大家贴到C:\Windows\system32\drivers\etc\hosts(Windows),/etc/hosts(Mac)文件中就可以了,同时也可以传到越狱了的苹果设备中去。

Note: Windows 用户执行命令python optimize_app_store_hosts.py,Mac用户执行sudo python optimize_app_store_hosts.py,因为Mac下只有root可以发出ICMP数据包。

#!/usr/bin/env python
import sys,socket

PING_TIMEOUT = 1000
def main():
  hosts = ['a%d.phobos.apple.com' % i for i in range(1, 200)]
  ips = get_ips(hosts)
  records = ping_ips(ips)
  output(records)

def get_ips(hosts):
  ips = []
  for host in hosts:
    ips.extend(get_ip(host))
  return {}.fromkeys(ips).keys()

def get_ip(host):
  print 'Getting IP for %s' % host
  ip_records = socket.getaddrinfo(host, None, socket.AF_INET)
  return [ip_record[4][0] for ip_record in ip_records]

def ping_ips(ips):
  ping_result = [(ip, my_ping(ip)) for ip in ips]
  ping_result.sort(cmp=lambda x, y: cmp(x[1], y[1]))
  return ping_result

def output(records):
  record_lines = ['IP: %s\tTime: %f ms\n' % (record[0], round(record[1])) for record in records]
  write_file('apple_ip.txt', record_lines)
  if len(records) > 0 and records[0][1] < PING_TIMEOUT:
    ip = records[0][0]
    hosts_lines = ['%s\ta%d.phobos.apple.com\n' % (ip, i) for i in range(1, 2000)]
    hosts_lines.insert(0, "#START APPLE STORE#\n")
    hosts_lines.append("#END APPLE STORE#\n")
    write_file('hosts', hosts_lines)

def write_file(filename, lines):
  with open(filename, 'w') as output_file:
    output_file.writelines(lines)
  output_file.close()

def my_ping(hostname):
  return Ping(hostname, PING_TIMEOUT, 8).run(4)

...
(Visit https://github.com/hackerzhou/Scripts/blob/master/optimize_app_store_hosts.py to see the rest part)

代码很简单,因为App Store的hostname都长成类似a1.phobos.apple.com这样,然后我们就从1到199遍历下(其实网上说可能会到2000,我实验下来大量的IP是相同的,真正不同的IP也就只有几十个。保险起见还是遍历了199个,没有验证过,如果大家有相关资料可以回复更正我。)把遍历得到的IP列表去除重复的,然后再挨个ping,最后按照ping的平均响应时间来排序,选择最快的那一个,产生一个hosts文件。本来想直接写入系统hosts文件的,因为Mac下必须用sudo才能写hosts而且随便改别人hosts文件毕竟不太好,容易引起杀毒软件报警,所以就直接写入到一个本地文件中。
Python写起来还是相当方便和简练的,特别是使用推导式构建列表以及lambda语法,用惯了Java再换用Python就会有一种耳目一新的感觉~

本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 hackerzhou 并包含 原文链接
发表评论

本文有 44 条评论

  1. 安云
    2015-01-13 11:19

    部分日本IP还是很快的

  2. shaneleeliar
    2013-05-08 10:32

    Traceback (most recent call last):
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 390, in
    main()
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 8, in main
    records = ping_ips(ips)
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 23, in ping_ips
    ping_result = [(ip, my_ping(ip)) for ip in ips]
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 43, in my_ping
    return Ping(hostname, PING_TIMEOUT, 8).run(4)
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 245, in run
    delay = self.do()
    File “C:\Users\Adonis\Desktop\optimize_app_store_hosts.py”, line 271, in do
    current_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname(“icmp”))
    File “C:\Python27\lib\socket.py”, line 187, in __init__
    _sock = _realsocket(family, type, proto)
    error: [Errno 10013]
    >>>
    请问这个是怎么回事 看不懂啊

  3. shaneleeliar
    2013-05-08 10:11

    有人吗?有没有人可以帮帮小白啊

  4. shaneleeliar
    2013-05-08 09:44

    我就是之前一直ping ip
    想找到能自己筛选ip的办法
    终于神奇的谷歌带我来这个页面
    可是,哥没学过计算机
    不懂啥是脚本啊

  5. linpython
    2012-12-01 22:02

    运行后错误,请问怎么解决呢谢谢!

    File “H:\Scripts-master\optimize_app_store_hosts.py”, line 38
    with open(filename,’w’) as output_file:
    ^
    SyntaxError: invalid syntax

    • hackerzhou
      2012-12-02 15:56

      貌似是因为没有写文件的权限,你检查下目录权限吧

  6. paying
    2012-05-18 22:57

    你SSH到服务器的时候会不会很慢,我租了个7刀的VPS,打个字起码1秒后才显示出来,不知道是不是网络的问题

  7. paying
    2012-05-05 17:33

    你的服务器是在https://www.lightwave.net 上租的?

  8. an9
    2012-05-04 13:50

    路过,来看一下技术博.

  9. 找太阳借火
    2012-05-04 09:34

    hackerzhou大神 我不懂编程…问个问题 我是win7x64的操作系统 安装的是python2.7.3 教育网 运行您的那个程序optimize_app_store_hosts.py 弹出的窗口把axxx.phobos.apple.com从1~199都遍历一遍 之后好像是在那个窗口里报错了 但是报错之后迅速消失 根本看不清报错的内容 运行之后当前文件夹下也没有apple_ip.txt和hosts文件 我设置了显示隐藏文件和系统文件 不知道怎么回事 大神能帮忙解释一下吗?

    • hackerzhou
      2012-05-04 16:52

      使用一个单独的cmd界面运行,开始-运行-cmd回车,然后cd到脚本存放的目录,然后用python optimize_app_store_hosts.py运行。

      • shaneleeliar
        2013-05-08 10:35

        我和他的问题 类似 而且我是按照博主说得那样 在新的cmd窗口运行的

        • hackerzhou
          2013-05-08 10:37

          现在已经不需要这么做了,苹果更新服务器在国内本身速度就不慢了。你肯定是开了uac,用管理员权限运行

发表评论