Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

danbooruの画像ファイルを全て持ってくる

皆様、明けましておめでとうございます。
全然関係ないけどなんかSKYPEdanbooruの話が少し出たので書いてみました。

根性がないのでBeautifulSoupを使っています。
lxmlは使っておりません。
もちろんtwsited厨なのでtwistedです。

from twisted.web import client
from twisted.internet import reactor,defer
from BeautifulSoup import *

REQUEST_URL = 'http://danbooru.donmai.us/post/show/%s/'
ids = []
retry = []
deferredList = []
dl = None

def stop(res):
    print 'stop'
    if reactor.running:
        reactor.stop()

def download(list):
    if len(list):
        id = list.pop(0)
        downloadPic (list, id, '/Users/xxx/danbooru/%s.%s')
    else:
        dl = defer.DeferredList(deferredList)
        dl.addCallback(stop)

def downloadPic(list, id, file):
    
    def finish(data):
        print 'finish %s' % id
        download(list)

    def get_data(data):
        exists = False
        html = BeautifulSoup(data)
        images = html.findAll('img', id='image')
        for image in images:
            src = image['src']
            if src:
                image_url = str(src)
                print 'download image %s' % image_url
                exists = True
                image_file = file % (str(id).zfill(8), image_url[image_url.rindex('.')+1:])
                defer = client.downloadPage(image_url, image_file, supportPartial=1).addCallback(finish).addErrback(err);
                if len(list) < 20:
                    deferredList.append(defer)
                    print len(deferredList)

        if not exists:
            download(list)     
    
    def err(e):
        download(list)

    url = REQUEST_URL % id
    print 'access %s' % url
    client.getPage(url).addCallback(get_data).addErrback(err);

def start():
    ids = range(1,200000)
    for x in xrange(50):
        download(ids)

if __name__ == '__main__':
    start()
    reactor.run()
 

Partialを使っていますがRangeでContentLengthが適当な値を返してくるので
レジュームはできないようです。
danbooruには相当量の画像ファイルがあるので時間かかります。
(20万近くアップされてるかな)
DeferredListのところはテストしてません。適当極まりないです。
Leopardでやってみようと思ったひとはtwsitedの呪いに合います。
Leopardはデフォルトでtwistedの一部がインスコされています。
でもwebモジュールはありません。使いもんにならんです。
適当にtwistedを新規にインスコしてもExtrasに入っている方を先に見ちゃうのでExtrasの
twistedのdirの名前を変えないといけません。

また関係ないけどTwsited X-ishについてはあとで書く予定。

というわけで現実逃避のエントリでした。