xkcd arşivi, python, threading
Yıllardır XKCD arşivine tam olarak göz atamadım, bugün aşağıdaki diyaloğu -tekrardan- görünce artık vaktinin geldiğini anladım. [buraya random gülüş gelecek]
tüm arşivi indirmeye karar verince, yapmam gereken işlemin basit olduğunu gördüm, ama 700 küsür resmi tek thread/tek process çalışan bir python scriptiyle indirmek uzun sürecekti. bunun üstüne python’da thread pool mevzusunu hem öğrenmek hem de etinden suyundan faydalanmak için araştırdım ve çok kısa bir sürede hallettim. (akabinde python’a yine aşık oldum, tekrardan. literally.)
aşağıdaki betik threading kütüphanesi yardımıyla -biraz daha hızlıca- XKCD arşivini download ediyor. çalışması için sadece ilgili makinede python kurulu olması yeterli.
#!/usr/bin/env python import Queue import threading import urllib import re, os """ XKCD dumper - http://www.xkcd.com emre yilmaz - www.darkbrown.org """ class Fetcher(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue self.__control_download_path() def run(self): while True: comic_id = self.queue.get() try: url = "http://www.xkcd.com/%s/" % comic_id source = urllib.urlopen(url).read() image = self.retrieve_image_url(source) self.download_image(image, comic_id) print "downloading image: %s" % comic_id except Exception, error: print "image cannot be retrived for this id: %s" % comic_id # birinci belli, ikinci kim? self.queue.task_done() def retrieve_image_url(self, source): try: reply = re.findall("(http://imgs.xkcd.com/.*)</h3>", source)[0] except: print error reply = "" return reply def __get_extension(self, image_url): return re.findall("\.[a-z]{3,4}$", image_url)[0] def __control_download_path(self): if not os.path.isdir(XKCD.DOWNLOAD_DIR): os.mkdir(XKCD.DOWNLOAD_DIR) def download_image(self, comic_url, comic_id): extension = self.__get_extension(comic_url) image_content = urllib.urlopen(comic_url).read() fp = open("%s/%s%s" % (XKCD.DOWNLOAD_DIR, comic_id, extension), 'wb') fp.write(image_content) fp.close() queue = Queue.Queue() class XKCD(object): THREAD_COUNT = 10 COMIC_RANGE = 732 DOWNLOAD_DIR = 'images' @staticmethod def fetch(): # thread'leri olustur, ve siraya diz for i in range(XKCD.THREAD_COUNT): new_thread = Fetcher(queue) new_thread.setDaemon(1) new_thread.start() # siradaki islere veriyi daya for item in range(1, XKCD.COMIC_RANGE): queue.put(item) queue.join() XKCD.fetch()

tşk ederim böyle ögretici kod paylaştıgınız için.