ポートフォリオサイト公開中

【pythonコードを読む】AV女優10000人webスクレイピング

こんにちは、ともろう(@tomorrowSLog)です。

今回FANZA動画サイト(旧DMM.R18)よりAV女優約1万人分の名前と画像をpythonを使ってスクレイピングしたのでその流れを書いていき、実際に動かしたコードを読んでいきたいと思います。

目次
  1. はじめに
    ・AV女優をwebスクレイピングしたきっかけ
    ・この記事でできるようになること
    ・開発環境
  2. AV女優をスクレイピング
    ・ロードマップ
    ・コード全文
    ・コード解説
    ・結果
  3. まとめ





【ChromeDriver】python3でgoogle検索を自動化する

はじめに

AV女優をwebスクレイピングしたきっかけ

きっかけはスケベサイエンティストで有名なDAIさん(@never_be_a_pm)のこのツイート。

ともろう

そういやこれやってみようと思ってた

以前見かけて面白そうだと思っていてその時は手をつけられなかったDAIさんの記事がtwitterで流れてきました。

ちょうど最近webスクレイピングの勉強をはじめたばかりで実践にちょうどいいと思い挑戦してみました。

ちなみにDAIさんはpythonやwebスクレイピング、APIをうまく使って初心者にもわかりやすいロードマップをたくさん公開されています。

ともろう

こんなものが作れるんだ

といった学びがたくさんあって、技術を学んだ後の実践にとても役に立ちます。そしてその記事がとても丁寧でわかりやすいです。

参考 Pythonによるスクレイピング①入門編 ブログの記事をCSVにエクスポートするnote.mu

この記事でできるようになること

pythonを使ってweb上の大量のデータを自動でスクレイピングできるようになります。

この記事の発展としてスクレイピングしたデータをもとにデータサイエンティスト的な情報分析をしたり、取得した画像を機械学習のデータにしたり、webアプリを作るのに利用したりすることができます。

開発環境

macOS Sierra10.12.6
Python 3.7.1

Macでのpython3環境構築はこちらの記事をどうぞ。anacondaやpyenvを使わずmacにpython環境を構築しています。

【ChromeDriver】python3でgoogle検索を自動化する 今回扱うseleniumの簡単な使い方を書いています。



AV女優をスクレイピング

DAIさんの記事を丸写して動かすのも悪くはないと思いますが、今回は実践ということで流れだけ見ながら自分でコードを組んでいきます。

ロードマップ

FANZA動画AV女優一覧からAV女優の情報をスクレイピングします。

  1. 名前が「あ」から始まるAV女優の人数を取得
  2. 人数からページ数を計算
  3. 名前が「あ」から始まるAV女優の1ページ目からAV女優の画像リンクと名前を取得
  4. データフレームに格納
  5. 1~4を「あ」から「わ」まで繰り返す
  6. 取得データをcsvに出力

コード全文

あまり綺麗なコードではないですが、動かすことを重視しました。結果抜け漏れなくデータを取得できたのでよかったのかなと思います。

コード全文
from selenium import webdriver
import pandas as pd

data = {"name": [],
        "image":[]}
df = pd.DataFrame(data)

url = 'http://www.dmm.co.jp/digital/videoa/-/actress/='
driver = webdriver.Chrome()
next_key = '#main-ds > div.d-area.area-actbox > div:nth-child(3) > p'

boins=['a', 'i', 'u', 'e', 'o']
siins=['', 'k', 's', 't', 'n', 'h', 'm', 'y', 'r', 'w']

def function(df):
    driver.get(url + '/keyword=' + siin + boin)
    ninzu = driver.find_element_by_css_selector(next_key).text
    num = -(-int(list(map(str,ninzu.split("\u3000")))[0][0:-2])//100)

    for i in range(num):
        driver.get(url + '/keyword=' + siin + boin + '/page=' + str(i+1))
        elements = driver.find_element_by_css_selector("#main-ds > div.d-area.area-actbox > div.d-sect.act-box").find_elements_by_tag_name("img")

        for element in elements:
            src = element.get_attribute("src")
            alt = element.get_attribute("alt")

            se = pd.Series([alt,src],["name", "image"])
            df = df.append(se, ignore_index=True)
    return df


for siin in siins:
    if siin == 'y':
        for boin in boins[::2]:
            df=function(df)
    elif siin == 'w':
        for boin in boins[0]:
            df=function(df)
    else:
        for boin in boins:
            df=function(df)

df.to_csv("output.csv")
driver.quit()



コード解説

Line1-7
from selenium import webdriver
import pandas as pd

data = {"name": [],
        "image":[]}
df = pd.DataFrame(data)

必要なモジュールをimportして、取得データを入れる箱を作っています。

Line8-14
url = 'http://www.dmm.co.jp/digital/videoa/-/actress/='
driver = webdriver.Chrome()
next_key = '#main-ds > div.d-area.area-actbox > div:nth-child(3) > p'

boins=['a', 'i', 'u', 'e', 'o']
siins=['', 'k', 's', 't', 'n', 'h', 'm', 'y', 'r', 'w']

urlとwebdriverの準備です。next_keyはAV女優の人数を取得する際に使うcssセレクタになっています。

ともろう

最初は次へボタンをクリックしてページ遷移をするつもりだったのですが断念した名残でnext_keyです笑

boinsとsiinsのリストの組み合わせで50音を作ります。

Line15-19
def function(df):
    driver.get(url + '/keyword=' + siin + boin)
    ninzu = driver.find_element_by_css_selector(next_key).text
    num = -(-int(list(map(str,ninzu.split("\u3000")))[0][0:-2])//100)

chromeドライバを開いてデータを取得して格納するというところを関数化したfunction関数を作りました。関数化の理由は後ほど書きます。

ninzuで取得した値は「1074人中 1~100人 全11ページ中 1ページ目を表示」このような形の文字列になるので欲しい値(1074人中の1074の部分)にうまく整形します。

ロードマップ1の部分の変数num。取得したい値を整形して数字を取り出し、1ページに表示される100人で割って切り上げ。

ともろう

書いてて思ったけど「全11ページ中」の部分を取得したらよかったですね
num = int(list(map(str,ninzu.split(“\u3000”)))[2][1:-len(ninzu.split(“\u3000”)))[2])+3])みたいな感じ。

どちらにせよ長いコードになるのでもっとわかりやすく書けよと言いたいです。

Line20-31
for i in range(num):
        driver.get(url + '/keyword=' + siin + boin + '/page=' + str(i+1))
        elements = driver.find_element_by_css_selector("#main-ds > div.d-area.area-actbox > div.d-sect.act-box").find_elements_by_tag_name("img")

        for element in elements:
            src = element.get_attribute("src")
            alt = element.get_attribute("alt")

            se = pd.Series([alt,src],["name", "image"])
            df = df.append(se, ignore_index=True)
    return df

Chromeを開いて欲しいimgタグをリスト化します。

そして画像と名前を取得し、データフレームに格納。

【ChromeDriver】python3でgoogle検索を自動化する セレクター操作とかはこの記事で軽く扱っています。

Line32-45
for siin in siins:
    if siin == 'y':
        for boin in boins[::2]:
            df=function(df)
    elif siin == 'w':
        for boin in boins[0]:
            df=function(df)
    else:
        for boin in boins:
            df=function(df)

df.to_csv("output.csv")
driver.quit()

母音と子音を組み合わせて50音を作っていましたがこれでは”yi”や”wu”などの使わない値が出てきます。そしてこの値でurlを検索すると名前が「あ」から始まるAV女優が出てきてしまい、データ重複を起こしてしまいます。

それに対策するため子音で’y’と’w’が出た時は例外操作をします。これをするにあたってfunction関数を作りました。

最後にcsvを”output.csv”という名前で出力してChromeを閉じます。



結果

AV女優スクレイピング結果

AV女優9763人分の名前と画像がスクレイピングできました。

まとめ

  • スクレイピングの実践としてちょうどいい難度だった
  • ブログにまとめる中で自分のコードを振り返れてよかった
  • もっと可動性の高いコードを書きたい
  • AV女優10,000人もいることに驚き

これからの流れとして今回得られたデータをうまく使ってAVライフをエンジョイGASでのデータ編集やAPIを使ったデータ取得、機械学習の勉強へ活かしていけたらと思います。

ではでは



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です