果粉们忍够了!——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就会有一种耳目一新的感觉~
2012-05-02 16:15
你好博主,我也做过个人博客的,用的都是美国的主机提供商,不过国内访问速度实在是不敢恭维,请问你的博客用的是什么服务器?我觉得访问速度很稳定,而且貌似还是V4 V6双栈的,能给我提供一点信息吗?谢啦~~
2012-05-03 21:52
我用的是lightwave.net,其实我个人觉得速度跟自己的配置和优化很有关系
2012-05-06 22:09
谢谢,那你用的是什么价位的?VPS吗?
2012-05-06 22:12
14刀每月的vps
2012-04-23 02:22
hackerzhou:
hi~
看了你的这个网站http://love.hackerzhou.me/
瞬间45度角了
特地跑来真诚想求教一下网站建设的事情
(不是为了女朋友)
我是清华的一名八年制临床医学生,目前7年级,将毕业
现在希望建一个关于临床医学指南的中文网站,类似wikipedia那种,专业、权威的(绝非百度百科、医学百科那类)
这个想法诞生至今,足足1年半
受了一群北大医学生开医疗科普网站的启发:http://www.bazhua.org
(对于这个网站的更多评价:http://whb.news365.com.cn/jkw/201104/t20110421_3015754.htm;http://finance.ifeng.com/roll/20110421/3912655.shtml)
关于网站内容、模式、受众等等我都想得比较清楚
我也调研过,这个方面,市场上是空白
关键现在对于网站建设,没有任何思路
之所以跑来向你真诚求教,
纯粹是热血沸腾想着创业的时候,看到校内上有人转了你的链接
而且目前我自己人在协和(八年制就这样,2年半在清华学基础,然后5年半回协和学临床),毕竟是医学院,圈子比较小
如果你方便且有时间,
真诚希望能够给我一些建议!
如果你需要更多信息,我可以通过邮件将自己网站构建的想法发给你。
拜谢了!!!
不胜感激!临书涕零!!!
2012-04-23 16:34
你说的那个网站,一看就知道用的是wordpress模板,作者这个也是。那种网站,建设起来不难的,你可以看看我的网站http://www.liaoshixiong.com
2012-04-23 22:16
没有主题是完全适合的,修改是必须的。比如我这个站点的主题就修改过后开源在https://github.com/hackerzhou/MyMinyxLITE 上。
一个好的网站更加重要的是内容,而不是外观。
ps:你的网站似乎是建立在免费的虚拟主机上?wordpress的配置貌似没配好,点击链接之后的域名不一致。
2012-04-23 22:05
如果想做成类似wikipedia的,推荐你使用开源的wiki作为网站的基础,我曾经也搭过一个wiki:http://wiki.hackerzhou.me ,使用的是开源的MediaWiki。
wiki的好处是可以慢慢的添加内容,直到最后变成一个专业性很强的站点。
2012-04-23 00:34
博主你好,在校内上看到别人转载你的love story,因为我没搞过Web不懂怎么做,能否把源码给我看看?我想在GF生日的时候给她个惊喜。。
2012-04-23 22:02
源代码在https://github.com/hackerzhou/Love 上,可以下载
2012-04-24 14:50
没想到Hackerzhou大牛还能贡献代码~嘿嘿~我拿去参考啦!!!
话说人人网能加你吗?
2012-04-24 17:51
人人网上一般不加不熟悉的人,你可以在微博上follow我。
我写过一篇关于SNS的文章,你可以看看 https://www.hackerzhou.me/2011/02/the-myth-of-sns.html
2012-04-22 23:16
要是ios设备上也能运行个脚本就好了~不过大前提是越狱,然而越狱后就没有必要到水果商店去下软件了。。。囧
2012-04-21 21:28
可以默默地仰望一下么……
2012-04-22 10:32
额,其实只是善于动手实践而已
2012-04-09 13:21
至于覆盖 hosts 文件吗?执行完后本地的记录全没了。
2012-04-09 20:09
本脚本不会覆盖hosts文件
2012-04-08 16:48
运行不能,文件也没有生成,报错如下:
Getting IP for a199.phobos.apple.com
PYTHON-PING 203.78.36.40 (203.78.36.40): 8 data bytes
Traceback (most recent call last):
File “optimize_app_store_hosts.py”, line 390, in
main()
File “optimize_app_store_hosts.py”, line 8, in main
records = ping_ips(ips)
File “optimize_app_store_hosts.py”, line 23, in ping_ips
ping_result = [(ip, my_ping(ip)) for ip in ips]
File “optimize_app_store_hosts.py”, line 43, in my_ping
return Ping(hostname, PING_TIMEOUT, 8).run(4)
File “optimize_app_store_hosts.py”, line 245, in run
delay = self.do()
File “optimize_app_store_hosts.py”, line 271, in do
current_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname(“icmp”))
File “/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/socket.py”, line 182, in __init__
socket.error: [Errno 1] Operation not permitted – Note that ICMP messages can only be send from processes running as root.
2012-04-08 21:23
请用sudo来执行该脚本Operation not permitted – Note that ICMP messages can only be send from processes running as root.
2012-04-08 01:05
貌似有问题
PYTHON-PING *.*.*.* (*.*.*.*): 8 data bytes
Traceback (most recent call last):
File “/Users/T******/Desktop/itunes.hosts.py”, line 390, in
main()
File “/Users/T******/Desktop/itunes.hosts.py”, line 8, in main
records = ping_ips(ips)
File “/Users/T******/Desktop/itunes.hosts.py”, line 23, in ping_ips
ping_result = [(ip, my_ping(ip)) for ip in ips]
File “/Users/T******/Desktop/itunes.hosts.py”, line 43, in my_ping
return Ping(hostname, PING_TIMEOUT, 8).run(4)
File “/Users/T******/Desktop/itunes.hosts.py”, line 245, in run
delay = self.do()
File “/Users/T******/Desktop/itunes.hosts.py”, line 271, in do
current_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname(“icmp”))
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py”, line 187, in __init__
socket.error: [Errno 1] Operation not permitted – Note that ICMP messages can only be send from processes running as root.
2012-04-08 21:24
请用sudo来执行该脚本
2012-04-07 16:27
弱弱的问下,这个文件是怎么使用的?
2012-04-04 12:53
我也曾经写了一个这样的脚本,后来发现不对劲,找到的ip几乎全是日本的。事实上,你在做dns查询的时候,本身dns服务器就会根据你的ip分配给你一个比较近的ip。类似a1.phobos.apple.com只是做负载均衡用的,像从a1-a2000查出来的都是些日本的ip。只有把自己的dns服务器换成香港或台湾的,才能查到香港或台服的服务器地址。因此,你的脚本估计只能查处在日本的服务器中速度比较快的。
2012-04-04 14:48
不完全是,目前我用的最快的是美帝的IP,而我查到的IP里面也很少有日本的IP。