5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ガルパのスクレイピングをはじめよう~『Python編』

Last updated at Posted at 2019-03-02

ガルパの画像をなるべく集めていきたい...

ソーシャルゲームとかで画像を集めていく場合、インターネット上でPCのブラウザで右クリックで保存したり、ゲームの画像をスクショで保存したり、SNSで公開されている画像を保存したりと、自分で探して画像を保存する必要があります。しかし、それだと自分が見逃した場合、新しいキャラクターの画像や新衣装の画像を取り逃してしまったり、取り逃してしまった画像も集めようとした場合、時間がかかってしまうこともあります...
そのため、自動化していきたいです...('ω')

そうだ、スクレイピングをしよう(´・ω・)

せっかくプログラミングに触れているので活用するしかないということで、Pythonで 『バンドリ! ガールズバンドパーティ!』のキャラクターの画像を自動で保存するプログラムを作成していこうと思います。ガルパの画像をスクレイピングしていく上で、対象のサイトして以下のサイトでまとめられているので利用させていただきます(/・ω・)/

動作環境

  • Windows10 Pro
  • Docker on Ubuntu1604 LTS on VirtualBox(Vagrant)
  • Python 3
  • Jupyter Notebook

URLの情報を取得する

まず、URLの情報を取得します。今回、BeautifulSoupというライブラリを使って必要なURLの文字列を選択して取得していくようにしています。何も考えずに適当に要素を選択すると以下のように書けます。

import os
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen

url = 'http://bangdream.gamedbs.jp/'
pre_r = requests.get(url)

pre_soup = BeautifulSoup(pre_r.text,'lxml')
urls = pre_soup.find_all('a')

print(urls)

出力結果

127.0.0.1_8888_notebooks_test.ipynb.png

取得した情報から欲しい情報を抽出していく

次に取得した情報から必要な部分を抽出します。今回取得したいのは画像ファイルのリンクの文字列ですが、例としてキャラクターの名前の要素を取得してみました。

import os
import time
import requests
import re
import uuid
from bs4 import BeautifulSoup
from urllib.request import urlopen

url = 'http://bangdream.gamedbs.jp/'
pre_r = requests.get(url)

pre_soup = BeautifulSoup(pre_r.text,'lxml')
urls = pre_soup.find_all('a', href=re.compile('^http://bangdream.gamedbs.jp/chara/show'))

for url in urls:
    print(url['title'])

出力結果

127.0.0.1_8888_notebooks_test.ipynb (1).png

キャラクターごとにURLを管理する

今回の対象となるサイトはキャラクターごとにリンクで画像がまとめられていたので、名前とURLを対応するように辞書でURLを管理しました(*‘ω‘ *) いつかはデータベースで管理するように改良していきたいですね~(>_<)


characters = {
    "kasumi_toyama":     "http://bangdream.gamedbs.jp/chara/show/11/",
    "tae_hanazono":      "http://bangdream.gamedbs.jp/chara/show/10/",
    "rimi_ushigome":     "http://bangdream.gamedbs.jp/chara/show/25/",
    "saaya_yamabuki":    "http://bangdream.gamedbs.jp/chara/show/24/",
    "arisa_ichigaya":    "http://bangdream.gamedbs.jp/chara/show/23/",
    "ran_mitake":        "http://bangdream.gamedbs.jp/chara/show/22/",
    "moka_aoba":         "http://bangdream.gamedbs.jp/chara/show/9/",
    "himari_uehara":     "http://bangdream.gamedbs.jp/chara/show/21/",
    "tomoe_udagawa":     "http://bangdream.gamedbs.jp/chara/show/8/",
    "tsugumi_hazawa":    "http://bangdream.gamedbs.jp/chara/show/20/",
    "kokoro_tsurumaki":  "http://bangdream.gamedbs.jp/chara/show/7/",
    "seta_kaoru":        "http://bangdream.gamedbs.jp/chara/show/19/",
    "hagumi_kitazawa":   "http://bangdream.gamedbs.jp/chara/show/6/",
    "kanon_matsubara":   "http://bangdream.gamedbs.jp/chara/show/18/",
    "misaki_okuzawa":    "http://bangdream.gamedbs.jp/chara/show/12/",
    "aya_maruyama":      "http://bangdream.gamedbs.jp/chara/show/5/",
    "hina_hikawa":       "http://bangdream.gamedbs.jp/chara/show/17/",
    "chisato_shirasagi": "http://bangdream.gamedbs.jp/chara/show/4/",
    "maya_yamato":       "http://bangdream.gamedbs.jp/chara/show/16/",
    "eve_wakamiya":      "http://bangdream.gamedbs.jp/chara/show/3/",
    "yukina_minato":     "http://bangdream.gamedbs.jp/chara/show/15/",
    "sayo_hikawa":       "http://bangdream.gamedbs.jp/chara/show/2/",
    "risa_imai":         "http://bangdream.gamedbs.jp/chara/show/14/",
    "ako_udagawa":       "http://bangdream.gamedbs.jp/chara/show/1/",
    "rinko_shirogane":   "http://bangdream.gamedbs.jp/chara/show/13/"
}

最終版

自分がやりたいように記述したら以下のようになりました...サイトや取得したい対象によって指定の仕方が変わっていくので、まずはライブラリを実際に使ってみるのがいいかもしれません(/・ω・)/

import os
import time
import requests
import re
import uuid
from bs4 import BeautifulSoup
from urllib.request import urlopen

characters = {
    "kasumi_toyama":     "http://bangdream.gamedbs.jp/chara/show/11/",
    "tae_hanazono":      "http://bangdream.gamedbs.jp/chara/show/10/",
    "rimi_ushigome":     "http://bangdream.gamedbs.jp/chara/show/25/",
    "saaya_yamabuki":    "http://bangdream.gamedbs.jp/chara/show/24/",
    "arisa_ichigaya":    "http://bangdream.gamedbs.jp/chara/show/23/",
    "ran_mitake":        "http://bangdream.gamedbs.jp/chara/show/22/",
    "moka_aoba":         "http://bangdream.gamedbs.jp/chara/show/9/",
    "himari_uehara":     "http://bangdream.gamedbs.jp/chara/show/21/",
    "tomoe_udagawa":     "http://bangdream.gamedbs.jp/chara/show/8/",
    "tsugumi_hazawa":    "http://bangdream.gamedbs.jp/chara/show/20/",
    "kokoro_tsurumaki":  "http://bangdream.gamedbs.jp/chara/show/7/",
    "seta_kaoru":        "http://bangdream.gamedbs.jp/chara/show/19/",
    "hagumi_kitazawa":   "http://bangdream.gamedbs.jp/chara/show/6/",
    "kanon_matsubara":   "http://bangdream.gamedbs.jp/chara/show/18/",
    "misaki_okuzawa":    "http://bangdream.gamedbs.jp/chara/show/12/",
    "aya_maruyama":      "http://bangdream.gamedbs.jp/chara/show/5/",
    "hina_hikawa":       "http://bangdream.gamedbs.jp/chara/show/17/",
    "chisato_shirasagi": "http://bangdream.gamedbs.jp/chara/show/4/",
    "maya_yamato":       "http://bangdream.gamedbs.jp/chara/show/16/",
    "eve_wakamiya":      "http://bangdream.gamedbs.jp/chara/show/3/",
    "yukina_minato":     "http://bangdream.gamedbs.jp/chara/show/15/",
    "sayo_hikawa":       "http://bangdream.gamedbs.jp/chara/show/2/",
    "risa_imai":         "http://bangdream.gamedbs.jp/chara/show/14/",
    "ako_udagawa":       "http://bangdream.gamedbs.jp/chara/show/1/",
    "rinko_shirogane":   "http://bangdream.gamedbs.jp/chara/show/13/"
}

def my_makedirs(path):
    if not os.path.isdir(path):
        os.makedirs(path)

def main():
    for k, v in characters.items():
        
        url = str(v)

        dirs_card = './workspace/bangdream/' + str(k) + '/card'
        my_makedirs(str(dirs_card))
        dirs_sd = './workspace/bangdream/' + str(k) + '/sd'
        my_makedirs(str(dirs_sd))
        dirs_live2d = './workspace/bangdream/' + str(k) + '/live2d'
        my_makedirs(str(dirs_live2d))
        
        pre_r = requests.get(url)
        if pre_r.status_code == 404:
            continue
        else:
            pre_soup = BeautifulSoup(pre_r.text,'lxml')
            urls = pre_soup.find_all('a', href=re.compile('^http://bangdream.gamedbs.jp/chara/show/'))
        
        for url in urls:
            r = requests.get(url['href'])
            if r.status_code == 404:
                continue
            else:
                soup = BeautifulSoup(r.text,'lxml')
                imgs1 = soup.find_all('a', href=re.compile('^http://bangdream.gamedbs.jp/images/chara/card'))
                imgs2 = soup.find_all('a', href=re.compile('^http://bangdream.gamedbs.jp/images/chara/livesd'))
                imgs3 = soup.find_all('span', class_ ='swimg sbtn radius animated')
              
                for img in imgs1:
                    print(img['href'])
                    r = requests.get(img['href'])
                    tmp = img['href'].split('/')
                    with open(dirs_card + '/' + tmp[-1],'wb') as file:
                        file.write(r.content)

                for img in imgs2:
                    r = requests.get(img['href'])
                    tmp = img['href'].split('/')
                    with open(dirs_sd + '/' + tmp[-1],'wb') as file:
                        file.write(r.content)

                for img in imgs3:
                    r = requests.get(img['data-img-url'])
                    tmp = img['data-img-url'].split('/')
                    with open(dirs_live2d + '/' + tmp[-1],'wb') as file:
                        file.write(r.content)
                
if __name__ == '__main__':
	main()

実行結果

Jupyter Notebookで実行しているので、以下のように実行結果が表示されていきます...やったね!('ω')!

111111.JPG
11111111.JPG

以上となります。スクレイピングについて禁止されているサイトなどもあります。そのあたりは自己責任となりますので、ご注意ください('ω')
また、取得した情報(画像や数値など色々)について私用の範囲で利用してください(/・ω・)/

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?