选择最快的appstore ip地址之Python版

今天才用上正统的Appstore软件下载方法:从iTunes端下载,然后PC端与iOS设备同步。然后俺就发现,下载速度那个慢啊。。。
从网上得到如下消息:

苹果为 App Store 准备了 a1.phobos.apple.com 到 a2000.phobos.apple.com 这么一群服务器,美国、欧洲、日韩、港澳……就是没有中国。。。

不管真假,让咱们用Python挨个ping出哪个地址最快,然后加到hosts里面吧:)
以下代码为Windows中文版,如果其它版,请把speed_ptn行的字符串改成对应的:

Nov/4/2014更新:
multiprocessing.dummy处理I/O负荷的并发,multiprocessing处理CPU负荷的并发。多少个url都无所谓啦~
注意:只写了Mac OS X版本的

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
Only works in Mac OS X, I tested in Yosemite
"""
from __future__ import unicode_literals
from subprocess import check_output, CalledProcessError
from re import compile as re_compile
from sys import getfilesystemencoding
from os import devnull
from multiprocessing.dummy import Pool 

URLS = ['a{}.phobos.apple.com'.format(i) for i in range(1,2001)]
IP_PTN = re_compile('\d+\.\d+\.\d+\.\d+')
AVG_PTN = re_compile('min/avg/max/stddev = \d+\.\d+/(\d+\.\d+)/')

def ping_test(url):
    try:
        with open(devnull, 'w') as null:
            output = check_output(['ping','-c','3', url], stderr=null).decode(getfilesystemencoding())
            ip = IP_PTN.search(output).group()
            avg = float(AVG_PTN.search(output).group(1))
    except CalledProcessError:
        ip = ""
        avg = ""
    print 'Server {}\t||\t Average Speed: {}ms'.format(url,avg)
    return {ip: avg}

if __name__ == '__main__':
    pool = Pool(25) #25 is process count, try increase or decrease it to find the best performance
    results = pool.map(ping_test, URLS)
    pool.close()
    pool.join()
    best = min(results,key=lambda x: x.values()[0])
    best_svr = results.index(best)
    print '***** Best server is a{}.phobos.apple.com, ip={}, avg speed={}ms *****'.format(best_svr, best.keys()[0],best.values()[0])

Aug/20/2012更新:写了使用多线程并加入了对timeout情况的处理,发现虽然速度快了,但是结果却是每次都是最大那个数的服务器ping值最快。不知道为啥。另外并发数不能太大,URLS里面直接用2000会提示打开文件太多。改成500没发现问题。

新版代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
"""
from __future__ import unicode_literals
import subprocess
import re
import sys
import threading

URLS=map(lambda x: 'a{}.phobos.apple.com'.format(x), range(1,501))
NUM=0
BEST=[2**16,'',''] # a big number normally larger than average
IP_PTN=re.compile('\[(.*)\]')
SPEED_PTN=re.compile('平均 = (\d+)ms')

class Ping(threading.Thread):
    def __init__(self, url, lock):
        threading.Thread.__init__(self)
        self.url=url
        self.lock=lock

    def run(self):
        try:
            output=subprocess.check_output(['ping',self.url]).decode(sys.getfilesystemencoding())
        except subprocess.CalledProcessError as cpe:
            print cpe.output
            output=cpe.output.decode(sys.getfilesystemencoding())
            avg='timed out'
        else:
            avg="{}ms".format((SPEED_PTN.search(output).group(1)))
        ip= IP_PTN.search(output).group(1)
        self.lock.acquire()
        print 'Server {}\t||\t Average Speed: {}'.format(self.url,avg)
        if avg =='timed out':
            pass
        elif BEST[0] > int(avg[:-2]):
            BEST[0] = int(avg[:-2])
            BEST[1] = ip
            BEST[2] = url
        global NUM
        NUM+=1
        if NUM==len(URLS):
            print 'Fastest server: {2} ( {1} ) fastest average speed: {0}ms'.format(*BEST)
        self.lock.release()

if __name__ == '__main__':
    lock=threading.Lock()
    try:
        for url in URLS:
            ping_thread=Ping(url,lock)
            ping_thread.start()
    except KeyboardInterrupt:
        pass

原版:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Sina weibo @SeganW
"""
from __future__ import unicode_literals
import subprocess
import re
import sys

urls=map(lambda x: 'a{}.phobos.apple.com'.format(x), range(1,2001))
best=[2**16,'',''] # a big number normally larger than average
ip_ptn=re.compile(r'\[(.*)\]')
speed_ptn=re.compile(r'平均 = (\d+)ms')
try:
    for url in urls:
        output=subprocess.check_output('ping {}'.format(url),shell=True).decode(sys.getfilesystemencoding())
        output=[i for i in output.split('\r\n') if i]
        ip= ip_ptn.search(output[0]).group(1)
        avg=int(speed_ptn.search(output[-1]).group(1))
        print 'Server {}\t||\t Average Speed: {}ms'.format(url,avg)
        if best[0] > avg:
            best[0] = avg
            best[1] = ip
            best[2] = url
except KeyboardInterrupt:
    print '\n'
print 'Fastest ip address:\n{1} {2}\nfastest speed: {0}ms'.format(*best)

找到最快的以后就可以改hosts文件了,这个不懂的自己google吧。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s