【Python Advent Calender 1日目】scrapyを使ってpixivのランキングから評価の高い画像だけをクローリングする
Python Advent Calender
※本記事は、【Python Advent Calender 2017 1日目】の記事になります。
もともとはOMEGA014さんが埋めていたカレンダーでしたが、もともと書きたいとは思いながらも埋まっているわ何か書こうかとか考えているうちに埋まってしまうわで散々でしたが、なんとなんと1日目に穴が空いているではありませんか!
私の誕生日が12月1日ということもありこれはもしかすると運命かもしれないと思い投稿することに。
というわけで飛び入り遅刻勢で滑り込んでいこうというスタンスです←
お前さん誰だ
- 某南の島にて情報工学を学ぶ大学生です
- 普段はJupyter + Python でデータ分析や画像処理(OpenCV)、自然言語処理など幅広く勉強しています。
- そろそろ進路を決めなきゃいけない学年でございます
んで本題
なんでも書いてよい感じだったのでつい最近やったことを晒そうかと。
大学の講義実験にて、「pixivの人気イラストの特徴が何か分析してみよう」という題のもとプロジェクトがスタートするにあたり、分析する画像が必要となりこれを数百枚以上用意する必要が出てきたのでそのときに書いたプログラムなどを晒しながら個人的なポイントとかを紹介して行こうと思います。
scrapy とは
2年前のPython Advent Calender にてすっごく分かりやすい説明をしていただいた記事があったのでそちらを参考にしていただけると。
ベースとなったプログラム
基本的には上記のリポジトリに変更を加えるような形でプログラムを作りました。先人の知恵でログインのところやparseのところをかいてくれていたお陰でだいぶ楽にクローリングすることができました。この場をお借りして感謝申し上げたいと思います。謝謝。
変更点
主に変更したのは画像をダウンロードする部分(parse_detail)で、
def parse_detail(self, response): item = response.meta['item'] item['url'] = response.url img_url = response.css('._illust_modal img').css('::attr("data-src")').extract() rated_count = response.xpath("//div[@class='user-reaction']/section[@class='score']/dl/dd[@class='rated-count']//text()").extract_first() # 画像が存在し、なおかついいね数が5000以上のみ収集 print("=====================================") print("This illust rated_count is {}" .format(rated_count)) if (len(img_url) > 0) and int(rated_count) > 5000: item['img_urls'] = img_url yield item
rated_countが新しく加えた部分です。ポイントはxpathを使用して必要なデータを細かく指定しているところですね。わりと当たり前な方法といえば当たり前ではあるのですが、scrapyが初心者である私にはxpathやcssの指定でクローリングしたデータから抽出できることに感動していました。
実際に抽出する場所はブラウザの検証などをつかってソースを眺める作業に費やしていたので目がとても痛かった・・・
結果
今回はいいね数が5000以上の画像のみを取得するようにして・・・
いい感じにクローリングできました。
scrapyの使用が初めてだったのでソースの理解やxpathの理解に時間を費やしてしまったのですが、おかげさまでクローリングのちょっとした理解ができました。データ収集はこれからも必要な技術ではあるので面白い方向にscrapyをどんどん使用していきたいと思います!
(もちろん!悪意のあるクローリングは相手先サーバに負荷をかけてしまうので気をつけてくださいね!sleepを適度に挟む必要が有ることを初めて知った )