Python
pixiv
pixivpy

pixivのフォローユーザーの漫画・イラストを一括DL


やりたかったこと

pixivでフォローしている全ての絵師さんの漫画・イラストをまとめてダウンロードしたかったんです。

1枚1枚手動で保存するのは面倒ですよね。

できれば自動で保存したい。

そんな時に見つけたのが、pixivpyライブラリ

非公式のpixiv APIみたいで、これで今回やりたかったことに近いスクリプトを書いてらっしゃる方もいました。

ただ、上記のスクリプトだと、漫画が1ページ目しか取れなかったので、少しスクリプトの改造が必要でした。

また、pixivpyには自分のフォローユーザーの情報を取得するメソッドがなかったので、そのスクリプトも別で用意する必要がありました。


やったこと

以下の3つのスクリプトを書きました。



  1. 自分のフォローユーザーの絵師IDを取得する

  2. 絵師IDから全ての漫画・イラストをDLする


  3. 自分のフォローユーザー全ての漫画・イラストをDLする


実行環境


  • OS: macOS High Sierra

  • python: 3.6.3

  • pixivpy: 3.3.3


事前準備①: 外部ライブラリのインストール

必要なライブラリをインストールします。


Terminal

$ pip install pixivpy

$ pip install beautifulsoup4
$ pip install robobrowser
$ pip install lxml


事前準備②: 認証情報をまとめる

コードに直書きしてもいいのですが、外部ファイルにまとめておくと管理しやすいです。


client.json

{

"pixiv_id": "自分のpixiv ID",
"password": "自分のpixiv パスワード",
"user_id": "自分のユーザID"
}


ファイル構造

作業ディレクトリ

├── client.json
├── get_following_userID.py
├── get_illustrations.py
├── get_all_illustrations.py
└── pixiv_images


ソースコード


1. 自分のフォローユーザーの絵師IDを取得する

フォローユーザー一覧ページより、絵師さんのユーザIDを抽出するスクリプトです。


▷ ソースコード本体


get_following_userID.py

#!/usr/bin/env PYTHONIOENCODING=UTF-8 python3

# -*- coding: utf-8 -*-

from pixivpy3 import *
import json
from time import sleep
import sys, io, re, os
from robobrowser import RoboBrowser
from bs4 import BeautifulSoup

f = open("client.json", "r")
client_info = json.load(f)
f.close()

# pixivpyのログイン処理
api = PixivAPI()
api.login(client_info["pixiv_id"], client_info["password"])
aapi = AppPixivAPI()

# フォローユーザーの総数を取得
self_info = aapi.user_detail(client_info["user_id"])
following_users_num = self_info.profile.total_follow_users

# フォローユーザー一覧ページのページ数を取得
if(following_users_num%48 != 0):
pages = (following_users_num//48)+1
else:
pages = following_users_num//48

#タグ除去用
p = re.compile(r"<[^>]*?>")
# [jump:1]形式除去用
jump = re.compile(r"\[jump:.+\]")
#ファイルエンコード設定用
character_encoding = 'utf_8'

# Webスクレイパーのログイン処理
pixiv_url = 'https://www.pixiv.net'
browser = RoboBrowser(parser='lxml', history=True)
browser.open('https://accounts.pixiv.net/login')
form = browser.get_forms('form', class_='')[0]
form['pixiv_id'] = client_info["pixiv_id"]
form['password'] = client_info["password"]
browser.submit_form(form)

# フォローユーザー一覧ページのURLを設定
target_url = 'https://www.pixiv.net/bookmark.php?type=user&rest=show&p='

# 全てのフォローユーザーのユーザIDを取得
following_users_id = []
for i in range(1, pages+1):
print(target_url + str(i))
browser.open(target_url + str(i))
following_users = browser.find(class_='members')
for user in following_users.find_all("input"):
following_users_id.append(user.get("value"))
sleep(3) # ページを移動したら一時待機する(マナー)

print(following_users_id)



▷ 実行例


Terminal

$ python get_following_userID.py

https://www.pixiv.net/bookmark.php?type=user&rest=show&p=1
https://www.pixiv.net/bookmark.php?type=user&rest=show&p=2
https://www.pixiv.net/bookmark.php?type=user&rest=show&p=3
['2246509', '1203800', '220531', ... , '11']


2. 絵師IDから全ての漫画・イラストをDLする

絵師さんのユーザIDより全ての漫画・イラストをダウンロードするスクリプトです。


▷ ソースコード本体


get_illustrations.py


# -*- coding: utf-8 -*-

from pixivpy3 import *
import json
from time import sleep
import os

# ログイン処理
api = PixivAPI()
f = open("client.json", "r")
client_info = json.load(f)
f.close()
api.login(client_info["pixiv_id"], client_info["password"])

# 入力された絵師IDから絵師情報を取得
illustrator_pixiv_id = int(input("Type illustrator pixiv id number:\n>>>"))
json_result = api.users_works(illustrator_pixiv_id, per_page=300) # とりあえずmax300作品と定義
total_works = json_result.pagination.total
illust = json_result.response[0]

# # 絞り込み条件
# target_tag = "target_tag"
# lower_score = 0

if not os.path.exists("./pixiv_images"): # 保存用フォルダがない場合は生成
os.mkdir("./pixiv_images")
saving_direcory_path = "./pixiv_images/" + illust.user.name + "/"
aapi = AppPixivAPI()
separator = "------------------------------------------------------------"

# ダウンロード
print("Artist: %s" % illust.user.name)
print("Works: %d" % total_works)
print(separator)
if not os.path.exists(saving_direcory_path):
os.mkdir(saving_direcory_path)
for work_no in range(0, total_works):
# # DL画像を絞り込む場合
# if target_tag not in illust.tags: #タグによる絞り込み
# continue
# if illust.stats.score < lower_score:#スコアによる絞り込み
# continue

illust = json_result.response[work_no]
print("Procedure: %d/%d" % (work_no + 1, total_works))
print("Title: %s" % illust.title)
print("URL: %s" % illust.image_urls["large"])
print("Caption: %s" % illust.caption)
# 漫画の場合
if illust.is_manga:
work_info = api.works(illust.id)
for page_no in range(0, work_info.response[0].page_count):
page_info = work_info.response[0].metadata.pages[page_no]
aapi.download(page_info.image_urls.large, saving_direcory_path)
sleep(3)
# イラストの場合
else:
aapi.download(illust.image_urls.large, saving_direcory_path)
sleep(3)
print(separator)

print("\nThat\'s all.")



▷ 実行例


Terminal

$ python get_illustrations.py

Type illustrator pixiv id number:
>>>2246509
Artist: カナヘイ
Works: 234
------------------------------------------------------------
Procedure: 1/234
Title: つねー
URL: https://i.pximg.net/img-original/img/2018/02/01/15/19/01/67061760_ugoira0.jpg
Caption: ねーねーねこの動くスタンプ出ましたー!
1と2の中から人気のものを動かしたグレードアップ版です✨動くねーねー達をぜひ見てみてください☺
https://t.co/PX4UFAf72k
------------------------------------------------------------
Procedure: 2/234
Title: ただ単に勢い余ったうさぎ
URL: https://i.pximg.net/img-original/img/2018/02/01/15/17/31/67061749_p0.jpg
Caption: ただ単に勢い余ったうさぎ。
...
..
.
That's all.


3. 自分のフォローユーザー全ての漫画・イラストをDLする

1と2の機能を統合したスクリプトです。


▷ ソースコード本体


get_all_illustrations.py


#!/usr/bin/env PYTHONIOENCODING=UTF-8 python3
# -*- coding: utf-8 -*-

from pixivpy3 import *
import json
from time import sleep
import sys, io, re, os

from robobrowser import RoboBrowser
from bs4 import BeautifulSoup

f = open("client.json", "r")
client_info = json.load(f)
f.close()

##### 全てのフォローユーザーのユーザIDを取得 #####

# pixivpyのログイン処理
api = PixivAPI()
api.login(client_info["pixiv_id"], client_info["password"])
aapi = AppPixivAPI()

# フォローユーザーの総数を取得
self_info = aapi.user_detail(client_info["user_id"])
following_users_num = self_info.profile.total_follow_users

# フォローユーザー一覧ページのページ数を取得
if(following_users_num%48 != 0):
pages = (following_users_num//48)+1
else:
pages = following_users_num//48

#タグ除去用
p = re.compile(r"<[^>]*?>")
# [jump:1]形式除去用
jump = re.compile(r"\[jump:.+\]")
#ファイルエンコード設定用
character_encoding = 'utf_8'

# Webスクレイパーのログイン処理
pixiv_url = 'https://www.pixiv.net'
browser = RoboBrowser(parser='lxml', history=True)
browser.open('https://accounts.pixiv.net/login')
form = browser.get_forms('form', class_='')[0]
form['pixiv_id'] = client_info["pixiv_id"]
form['password'] = client_info["password"]
browser.submit_form(form)

# フォローユーザー一覧ページのURLを設定
target_url = 'https://www.pixiv.net/bookmark.php?type=user&rest=show&p='

# 全てのフォローユーザーのユーザIDを取得
following_users_id = []
for i in range(1, pages+1):
print(target_url + str(i))
browser.open(target_url + str(i))
following_users = browser.find(class_='members')
for user in following_users.find_all("input"):
following_users_id.append(user.get("value"))
sleep(3) # ページを移動したら一時待機する(マナー)

print("\n▽▽▽\n")

##### ダウンロード処理 #####

# 絵師IDから絵師情報を取得
for user_id in following_users_id:

json_result = api.users_works(int(user_id), per_page=300) # とりあえず1ユーザにつきmax300作品ダウンロードする
total_works = json_result.pagination.total
illust = json_result.response[0]

# # 絞り込み条件
# target_tag = "target tag"
# lower_score = 0

if not os.path.exists("./pixiv_images"): # 保存用フォルダがない場合は生成
os.mkdir("./pixiv_images")
saving_direcory_path = "./pixiv_images/" + illust.user.name + "/"
separator = "------------------------------------------------------------"

# ダウンロード
print("Artist: %s" % illust.user.name)
print("Works: %d" % total_works)
print(separator)
if not os.path.exists(saving_direcory_path):
os.mkdir(saving_direcory_path)
for work_no in range(0, total_works):
# # DLする画像を絞り込む場合
# if target_tag not in illust.tags: #タグによる絞り込み
# continue
# if illust.stats.score < lower_score:#スコアによる絞り込み
# continue

illust = json_result.response[work_no]
print("Procedure: %d/%d" % (work_no + 1, total_works))
print("Title: %s" % illust.title)
print("URL: %s" % illust.image_urls["large"])
print("Caption: %s" % illust.caption)
# 漫画の場合
if illust.is_manga:
work_info = api.works(illust.id)
for page_no in range(0, work_info.response[0].page_count):
page_info = work_info.response[0].metadata.pages[page_no]
aapi.download(page_info.image_urls.large, saving_direcory_path)
sleep(3)
# イラストの場合
else:
aapi.download(illust.image_urls.large, saving_direcory_path)
sleep(3)
print(separator)

print("\nThat\'s all.")



▷ 実行例


Terminal

$ python get_all_illustrations.py

https://www.pixiv.net/bookmark.php?type=user&rest=show&p=1
https://www.pixiv.net/bookmark.php?type=user&rest=show&p=2
https://www.pixiv.net/bookmark.php?type=user&rest=show&p=3

▽▽▽

Artist: カナヘイ
Works: 234
------------------------------------------------------------
Procedure: 1/234
Title: つねー
URL: https://i.pximg.net/img-original/img/2018/02/01/15/19/01/67061760_ugoira0.jpg
Caption: ねーねーねこの動くスタンプ出ましたー!
1と2の中から人気のものを動かしたグレードアップ版です✨動くねーねー達をぜひ見てみてください☺
https://t.co/PX4UFAf72k
------------------------------------------------------------
Procedure: 2/234
Title: ただ単に勢い余ったうさぎ
URL: https://i.pximg.net/img-original/img/2018/02/01/15/17/31/67061749_p0.jpg
Caption: ただ単に勢い余ったうさぎ。
...
..
.
That's all.


(※ソースコードを載せましたが、無茶な利用をするとBANされるのでご注意ください)


今後の展望

このスクリプトで好きなイラストを集めて、自分の好みのイラスト判別器でも作ろうかと。

判別器を使って、Tumblrで自動リブログとかしたいです。

でも、まずはシンプルに、似たキャラクターの分類器から始めようと思います。

積んであったゼロ本を読み始める機会がやってきたぞ...。


参考にしたサイト


余談

プログラミングが面倒な人のために、こんな便利ツールもあるみたいです。

pixivダウンローダ