LoginSignup
0
3

More than 3 years have passed since last update.

スクレイピングで画像を集める。さらに動画作成!

Last updated at Posted at 2021-01-15

概要

皆さんはタレントの画像やキャラクターのイラストなどをスマホやパソコンに保存したりすることはありますか?
集めたい画像のタイトルを書くだけで画像とその画像を見るためのムービーが自動で生成するコードを公開します。ぜひ利用してみてください。
画像はプリ画像というサイトから1000枚弱ダウンロードする。

Screen Shot 2021-01-16 at 0.03.10.png

また、スクレイピングを学習したい人に向けてコードの解説も入れていきます。

コード

まず利用したいだけの人向けにコードを載せます。

main.py

import requests
from bs4 import BeautifulSoup
import time
import re
import sys
import os
import cv2
import glob
import numpy as np
frame_rate = 0.7  #FPS
width = 1920
height = 1080
def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            f.write(r.content)
def timelaps(images,path):
    fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
    video = cv2.VideoWriter(path+'.mp4', fourcc, frame_rate, (width, height))
    print("動画変換中...")
    for image in images:
        print(image)
        img = cv2.imread(image)
        dst_img = np.zeros((height, width, 3), dtype = np.uint8)
        top = 0
        left = 0
        h, w, c = img.shape
        if(height/h<width/w):
            img=cv2.resize(img,(height*w//h,height))
        else:
            img=cv2.resize(img,(width,h*width//w))
        print(img.shape)
        h, w, c = img.shape
        dst_img[0:h, 0:w] = img
        video.write(dst_img)
    video.release()
    print("動画変換完了")
def main():
    argv = sys.argv
    if(len(argv)<2):
        print("python3 main.py $名前$\n と入力してね")
        return
    name = sys.argv[1]
    path = './pic/'+name
    if(True):
        if not os.path.isdir(path):
            os.makedirs(path)
        c = 0
        for i in range(100):
            urlName = "https://prcm.jp/list/"+name+"?page={}".format(i+1)
            url = requests.get(urlName)
            soup = BeautifulSoup(url.content, "html.parser")
#img_list = soup.select('div.entry > ul > li > a > div > img')
            img_list = soup.select('div>ul>li>a>div>img')
            for img in img_list:
                img_url = (img.attrs['src'])
                img_url = re.sub('_.*jpeg','.jpeg',img_url)
                img_url = re.sub('_.*png','.png',img_url)
                print(img_url)
                download_img(img_url,path+'/img{}.png'.format(c))
                c+=1
# making movie
    if(True):
        movie_path = './video/'
        if not os.path.isdir(movie_path):
            os.makedirs(movie_path)
        images = sorted(glob.glob(path+"/*.png"))
        timelaps(images,movie_path+name)

if __name__ == '__main__':
    main()

実行方法

python3 main.py (欲しい画像の名前)

例えば「橋本環奈」の画像を集めたい場合は

python3 main.py 橋本環奈

実行するとScreen Shot 2021-01-16 at 0.30.44.pngこの状態から
Screen Shot 2021-01-16 at 0.35.12.png
この状態になり、Screen Shot 2021-01-16 at 0.36.18.pngこのように画像が保存されている。

環境

Python3.9.1
必要なライブラリはpip3やanacondaでinstallしてください

コードの解説

別のサイトでの利用やコードのを学びたい方向けにコードを解説していきます。

import requests
from bs4 import BeautifulSoup
import time
import re
import sys
import os
import cv2
import glob
import numpy as np
frame_rate = 0.7  #FPS
width = 1920
height = 1080

まず必要なライブラリをimport。
集める画像と作る動画の情報としてFPSと画像幅(width)、画像の高さ(height)をここで入力

def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            f.write(r.content)

画像をダウンロードするための関数。URLとファイルの名前を入力としてurlにある画像をfileに保存します。

def timelaps(images,path):
    fourcc = cv2.VideoWriter_fourcc('m','p','4','v')
    video = cv2.VideoWriter(path+'.mp4', fourcc, frame_rate, (width, height))
    print("動画変換中...")
    for image in images:
        print(image)
        img = cv2.imread(image)
        dst_img = np.zeros((height, width, 3), dtype = np.uint8)
        top = 0
        left = 0
        h, w, c = img.shape
        if(height/h<width/w):
            img=cv2.resize(img,(height*w//h,height))
        else:
            img=cv2.resize(img,(width,h*width//w))
        print(img.shape)
        h, w, c = img.shape
        dst_img[0:h, 0:w] = img
        video.write(dst_img)
    video.release()
    print("動画変換完了")

集めた画像から動画を生成する関数。
保存した画像のパスの配列と動画の保存先ファイル名を入力として動画を作成する。
保存された画像の形が自分の作りたい動画の形と一致していないと思われるのでここでreshapeを行っている。
しかし、単純にcv2.reshapeを使うとアスペクト比がメチャクチャになるため、アスペクト比を保ちながら限界まで拡大したのちに残りを黒で埋めるという処理を行っている。

def main():
    argv = sys.argv
    if(len(argv)<2):
        print("python3 main.py $名前$\n と入力してね")
        return
    name = sys.argv[1]
    path = './pic/'+name
    if(True):
        if not os.path.isdir(path):
            os.makedirs(path)
        c = 0
        for i in range(100):
            urlName = "https://prcm.jp/list/"+name+"?page={}".format(i+1)
            url = requests.get(urlName)
            soup = BeautifulSoup(url.content, "html.parser")
#img_list = soup.select('div.entry > ul > li > a > div > img')
            img_list = soup.select('div>ul>li>a>div>img')
            for img in img_list:
                img_url = (img.attrs['src'])
                img_url = re.sub('_.*jpeg','.jpeg',img_url)
                img_url = re.sub('_.*png','.png',img_url)
                print(img_url)
                download_img(img_url,path+'/img{}.png'.format(c))
                c+=1
# making movie
    if(True):
        movie_path = './video/'
        if not os.path.isdir(movie_path):
            os.makedirs(movie_path)
        images = sorted(glob.glob(path+"/*.png"))
        timelaps(images,movie_path+name)

if __name__ == '__main__':
    main()

実行部である。sys.argv[1]にある名前をnameに格納。
スクレイピング部に関して、このプリ画像というサイトは'https://prcm.jp/list/{名前}/page={数字}' のリンク上に画像リンクが9つ程度書いてあるので、それをsoup.selectで選択してそれぞれをダウンロードしている。
htmlの情報はChromeのViewタブからDeveloper、Developer Toolと選択すれば解析しやすい。
他のサイトで利用したい場合はこの部分をうまく書き換える必要がある。
画像のリンクがどこに埋まっているかをよく調べてsoup.selectで上手に選択してimg_listに追加しよう。

0
3
1

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
0
3