16万タイトルの AV の ID を dmm から集めた | ぱろすけのメモ帳

皆様こんにちは!

今日は、「大規模AVサンプル画像認識」プロジェクトの第1回として、その下準備としての素材集めの話について書きます。これはもちろん何か悪事を働くためのプロジェクトではなく、コンピュータの活用によるユートピアの実現へ向けての第一歩と捉えていただければ幸いです。


さて僕は、画像処理や画像認識に関して、少しだけ知識があります。画像処理とは主に画像を処理して別の画像を吐き出すことで、たとえばフィルタをかけて色を変えたりぼやけさせたり、そういうようなことをしています。画像認識とは人工知能に比較的近い分野で、もう少し高度なことをします。たとえば、画像から顔を検出したり、写っているものが何であるか判定したりします。

画像認識では、近年、ネット上の大規模データを活用して何か賢いものを作ろうという話が多くあります。そのようなアプローチはアカデミックな世界では多くあるのですが、たとえば画像処理や認識と聞いて思いつくであろう桃色画像に関する研究については、アカデミックでは滅多にないわけです。じゃあ趣味でやって、学んだことを社会に還元すれば良いではないか。

近年の動画サイトの隆盛により、ネット上には多くのデータがあります。たとえば xvideos であるとか、まあいろいろありますよね。今回、ここでは dmm.co.jp に着目します。なぜならば、AV がタイトル別で配信されており、タイトルやジャンルなどの情報がまとめて手に入るからです。また、1タイトルあたり平均して10枚程度のサンプル画像が提供されています。動画から画像を切りださなくともこれを拾えば良い。手軽ですね。また、配信されているタイトル数がべらぼうに多く、現在16万タイトル以上あります。

これはデータをかき集める他ないじゃないですか。これは社会貢献であり、知的好奇心によるものでもあります。


まずは下準備として、動画の ID を集めます。後に、これを元に画像をたくさん集めます。

ID の集め方はいろいろあるのですが、今回は適当に、「dmm に提供しているメーカーの一覧を開く」→「メーカー別にタイトル一覧を抜き出す」という形を取ります。

適当に書いたスクリプトが以下。

#!/usr/bin/env python# -*- coding: utf-8 -*- import urllib2import chardetimport BeautifulSoupimport sqlite3import osimport Imageimport leargistimport pickleimport cStringIOimport sysimport urllibimport shutilimport threadingimport timeimport globimport cv2import numpy as nimport mathdef getCID():    class MakerThread(threading.Thread):        def __init__(self, url):            self.url = url            threading.Thread.__init__(self)        def run(self):            print self.url            self.cids = []            for self.i in range(1,1000):                self.open_url = "%slimit=120/page=%d/" % (self.url, self.i)                print self.open_url                 self.opened_url = urllib2.urlopen(self.open_url)                if self.opened_url.url != self.open_url:                    break                self.lines = self.opened_url.read()                self.lines = unicode(self.lines, chardet.detect(self.lines)['encoding'])                self.soup = BeautifulSoup.BeautifulSoup(self.lines)                for self.s in self.soup(attrs={'class': 'tmb'}):                    self.vurl = "%s%s" % (base_url, self.s('a')[0]['href'])                    self.pos1 = self.vurl.index("cid=") + 4                    self.pos2 = self.vurl.index("/", self.pos1)                    self.cids.append((self.vurl[self.pos1:self.pos2],))                        while True:                try:                    self.con = sqlite3.connect(db_name)                    self.con.executemany('insert into cid values (?)', self.cids)                    self.con.commit()                    self.con.close()                    break                except:                    time.sleep(10)            print "done"    class CharThread(threading.Thread):        def __init__(self, consonant, vowel):            self.url = "http://www.dmm.co.jp/digital/videoa/-/maker/=/keyword=%s%s/" % (consonant, vowel)            threading.Thread.__init__(self)        def run(self):            self.lines = urllib2.urlopen(self.url).read()            self.lines = unicode(self.lines, chardet.detect(self.lines)['encoding'])            self.soup = BeautifulSoup.BeautifulSoup(self.lines)            self.r = self.soup(attrs={'class': 'd-boxpicdata d-smalltmb'})            self.maker = []            for self.r1 in self.r:                    while True:                    time.sleep(10)                    if threading.activeCount() <= max_threads:                        break                self.t = MakerThread("%s%s" % (base_url, self.r1('a')[0]['href']))                self.t.setDaemon = True                self.t.start()        # make table    con = sqlite3.connect(db_name)    cur = con.execute("SELECT * FROM sqlite_master WHERE type='table' AND name='cid';")    if cur.fetchone() != None:        con.execute("drop table cid;")    con.execute("create table cid (cid);")    con.commit()    con.close()    for consonant in ['', 'k', 's', 't', 'n', 'h', 'm', 'y', 'r', 'w']:        for vowel in ['a', 'i', 'u', 'e', 'o']:            t = CharThread(consonant, vowel)            t.setDaemon = True            t.start()            time.sleep(1)

データは sqlite に保存するのでまず開いてテーブルを作ります。次に、メーカー一覧のページを「あ」「い」「う」…と順番に開きます。これは全てスレッドを分けていて、すなわち50本くらいのスレッドが立ちます。ここでは「あ」を例に取りましょう。「あ」から始まるメーカー一覧を取得し、今度はメーカーごとにスレッドを立てます。そして、そのスレッドが各々 ID を抽出します。

素直に回すとスレッドが立ちまくって Python が死ぬので、最大数を制限しています。その他いろいろと小細工があります。

まあでもこれで ID 一覧が取れます。


マルチスレッドで並行してすごい勢いでアクセスしますが、それでも終わるのに数時間はかかります。

そしてできたデータベースの様子がこちら。

タイトル数が出てますね。全164533タイトル!

明日以降はこのデータをもとにもっといろいろ進めます。宜しくお願いします。

なお今、手元では顔検出スクリプトと類似画像検索用特徴抽出スクリプトがくるくる回っています。乞御期待。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中