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

#概要
皆さんはタレントの画像やキャラクターのイラストなどをスマホやパソコンに保存したりすることはありますか？
集めたい画像のタイトルを書くだけで画像とその画像を見るためのムービーが自動で生成するコードを公開します。ぜひ利用してみてください。
画像は[プリ画像](https://prcm.jp/)というサイトから1000枚弱ダウンロードする。
#![Screen Shot 2021-01-16 at 0.03.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625181/f7db5c56-0847-fb1c-9145-1fa9476130ca.png)

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

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

```python: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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625181/b68d08f1-ef81-07fb-dd4d-33e95aea2a24.png)この状態から
![Screen Shot 2021-01-16 at 0.35.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625181/767da665-4391-966e-0108-b745d5f760f6.png)
この状態になり、![Screen Shot 2021-01-16 at 0.36.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625181/784498ae-797c-222e-b238-27ab0fefa237.png)このように画像が保存されている。

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

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


```python
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)をここで入力

```python
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に保存します。

```python
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を使うとアスペクト比がメチャクチャになるため、アスペクト比を保ちながら限界まで拡大したのちに残りを黒で埋めるという処理を行っている。

```python
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/)というサイトは'https://prcm.jp/list/{名前}/page={数字}' のリンク上に画像リンクが9つ程度書いてあるので、それをsoup.selectで選択してそれぞれをダウンロードしている。
htmlの情報はChromeのViewタブからDeveloper、Developer Toolと選択すれば解析しやすい。
他のサイトで利用したい場合はこの部分をうまく書き換える必要がある。
画像のリンクがどこに埋まっているかをよく調べてsoup.selectで上手に選択してimg_listに追加しよう。