読者です 読者をやめる 読者になる 読者になる

MATHGRAM

主に数学とプログラミング、時々趣味について。

pixivからイラストを無限に集めてみる[python]

python スクレイピング

一個前の記事で書いたように,

初心者がchainerで線画着色してみた。わりとできた。 - Qiita

を実装する際に溜まった知識のまとめ第二弾です.
今回は画像のスクレイピングについてです.

以下のサイトのコードをめちゃくちゃ参考にしています. ありがとうございました. kennn.hatenablog.com

pixivpy

なんと, pixivから画像を収集するためのapiがあるみたいで今回はそれを利用させていただきます.

あ、公式ではないですよ.

GitHub - upbit/pixivpy: Pixiv API for Python

こちらがそのapigithubです. インストールはpipでオッケー.

$ pip install pixivpy

これを使えば大体の情報はとってこれるのでほとんど問題ないと思います.
ただし, pixivはよく内部の環境が変わるようでこのapiもいつまで使えるかわからないとのこと. その辺注意してください.

以下に貼るのは, scoreが500以上の絵師さんの画像をmax300枚ずつ集めるスクリプトです. このコードと同じディレクトリに自分のアカウント情報を書いたjsonファイルを作ってください.

具体的にはこんな感じです.

{"pixiv_id":"ここにメールアドレス", "password":"ここにパスワード"}

特に問題がなければコードの中に直接アカウント情報を書いてもいいと思います.

# coding: utf-8

from pixivpy3 import *
import json
from time import sleep
import os

# ログイン処理
api = PixivAPI()
f = open('client.json', 'r')
client_info = json.load(f)
f.close()
# ここに直接アカウント情報を書いても大丈夫です.
api.login(client_info['pixiv_id'], client_info['password'])

# ここでIDを指定します.
STARTID = 0
ENDID = 100000

for ID in range(STARTID, ENDID):
    # アーティスト検索から情報取得
    try:
        artist_pixiv_id = ID

        # ここのper_pageの値を変えることで一人の絵師さんから持ってくる最大数を定義できます.
        json_result = api.users_works(artist_pixiv_id, per_page=300)
        info = json_result.response[0]
        score = info.stats.score

        # 僕はscoreが500以上の人を収集対象にしました.
        # よりクオリティの高い画像のみを集めたい場合はこの閾値を変更してください.
        if score < 500:
            continue

        total_works = json_result.pagination.total
        illust = json_result.response[0]

        # 画像の保存先を定義しています.
        # 特に指定先に希望がない場合はこのままでokです.
        # このまま走らせると, このスクリプトがあるディレクトリの直下に
        # "pixiv_images"フォルダが作成され画像が DLされます.
        if not os.path.exists("./pixiv_images"):
            os.mkdir("./pixiv_images")
        saving_direcory_path = './pixiv_images'

        aapi = AppPixivAPI()
        separator = '------------------------------------------------------------'

        # ダウンロード
        print('Artist: %s' % illust.user.name)
        print('Works: %d' % total_works)
        print(separator)

        # 絵師さんごとにディレクトリを分けたい場合は以下の2行を
        # アンコメントアウトしてください.
        # 一つのディレクトリにまとめたい場合はそのままでokです.

        #if not os.path.exists(saving_direcory_path):
        #    os.mkdir(saving_direcory_path)

        for work_no in range(0, total_works):
            illust = json_result.response[work_no]
            print('Procedure: %d/%d:%d' % (work_no + 1, total_works, ID))
            print('Title: %s' % illust.title)
            print(separator)
            aapi.download(illust.image_urls.large, saving_direcory_path)
            sleep(1)

        print('\nThat\'s all.')
    except:
        continue

以上です.