python スクレイピング その3
はじめに
今回はYahoo画像検索で猫の画像をかき集めて保存するプログラムを書いてみた。
準備
- imageDownload.py
import requests, os, json, traceback from bs4 import BeautifulSoup path = './img-cat/' maxPage = 2 searchText = '猫' def imageDownload(searchWord, index): url = 'https://search.yahoo.co.jp/image/search?p={searchWord}&ei=UTF-8&b={index}' resp = requests.get(url.format(searchWord=searchWord, index=index)) soup = BeautifulSoup(resp.content, 'html.parser') #分析 script = soup.find("script", attrs={"id": "__NEXT_DATA__"}) # タグの内容を取り出してJSON変換 # <script>なので中身はstringで取るみたい。 scriptJson = json.loads(script.string) imageUrlList = [] for algos in scriptJson['props']['initialProps']['pageProps']['algos']: imageUrlList.append(algos['main']['url']) #画像取得 imageObjectList = [] for imageUrl in imageUrlList: resp = requests.get(imageUrl) imageObjectList.append(resp.content) #画像リスト返却 return imageObjectList def imageWrite(imageList): for i, image in enumerate(imageList): fileName = path + 'img' + '{:04}'.format(i+1) + '.jpg' with open(fileName, 'wb') as saveImage: saveImage.write(image) return if __name__ == '__main__': try: if os.path.exists(path) != True: os.mkdir(path) imageList = [] # Page * 20ループで画像取得 for i in range(int(maxPage)): #画像収集 index = (i * 20) + 1 imageList.extend(imageDownload(searchText, index)) #画像書き込み imageWrite(imageList) except Exception as e: print(e) print(traceback.format_exc())
- 実行方法と結果
$ python imageDownload.py
$ ls img-cat/
img0001.jpg img0003.jpg img0005.jpg img0007.jpg img0009.jpg img0011.jpg img0013.jpg
:
- 簡単な解説
Yahoo画像検索が1ページに付き20枚画像が取れる。
それを前提に以下で20ずつindexを勧めて画像を取得してリストに追加している。
リストにリストを追加する処理はextend(appendでやって1敗)
# Page * 20ループで画像取得 for i in range(int(maxPage)): #画像収集 index = (i * 20) + 1 imageList.extend(imageDownload(searchText, index))
ここでリストを全部渡して、カレントの下のディレクトリにファイルに出力している。
#画像書き込み
imageWrite(imageList)
- 関数の解説
以下の処理でリクエストを投げて、結果を受け取っている。
特筆すべきはscriptにJSONでURLなどを保持しているところ。
def imageDownload(searchWord, index): url = 'https://search.yahoo.co.jp/image/search?p={searchWord}&ei=UTF-8&b={index}' resp = requests.get(url.format(searchWord=searchWord, index=index)) soup = BeautifulSoup(resp.content, 'html.parser') #分析 script = soup.find("script", attrs={"id": "__NEXT_DATA__"})
あとは、JSONを分析+URLのリストを作って画像をダウンロードしてimageObjectListに保存している。
scriptJson = json.loads(script.string) imageUrlList = [] for algos in scriptJson['props']['initialProps']['pageProps']['algos']: imageUrlList.append(algos['main']['url']) #画像取得 imageObjectList = [] for imageUrl in imageUrlList: resp = requests.get(imageUrl) imageObjectList.append(resp.content) #画像リスト返却 return imageObjectList
imageWriteはリストを吐き出しているだけなので省略
まとめ
スクレイピングをやっていると、どんどんこれやっていいのかってなってくるので方向性がぶれてくる。
だけど、やりたいことはできたので良しとする。