某画像投稿サイトから、フォロワーの画像を一括ダウンロードする試み
先人たちのソースコードを参考にしています。
get_api.py
from pixivpy3 import * import json def get_api(): with open("client.json") as f: client_info = json.load(f) # pixivpyのログイン処理 api = PixivAPI() api.login(client_info["pixiv_id"], client_info["password"]) aapi = AppPixivAPI() aapi.login(client_info["pixiv_id"], client_info["password"]) return api, aapi
get_following_userID.py
from pixivpy3 import * import json from time import sleep import sys import io import re import os from robobrowser import RoboBrowser def get_following_userID(api, aapi): # フォローユーザーの総数を取得 self_info = aapi.user_detail(client_info["user_id"]) n_following_users = self_info.profile.total_follow_users # フォローユーザー一覧ページのページ数を取得 if(n_following_users % 48 != 0): pages = (n_following_users // 48) + 1 else: pages = n_following_users // 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) print("# of following users",n_following_users) print("# of obtained following users",len(following_users_id)) with open("following.json", "w") as f: json.dump(following_users_id, f, indent=1) return following_users_id
get_illustrations.py
from pixivpy3 import * import json from time import sleep import os def get_illustrations(api, aapi, illustrator_pixiv_id, DL_flag=False): # 最大作品数 max_works = 3000 # 入力された絵師IDから絵師情報を取得 json_result = api.users_works(illustrator_pixiv_id, per_page=max_works) # アカウントは停止ユーザー if "pagination" not in json_result: return total_works = json_result.pagination.total # 投稿数が0 if total_works == 0: return illust = json_result.response[0] # 絞り込み条件 # target_tag = "target_tag" if not os.path.exists("./pixiv_images"): # 保存用フォルダがない場合は生成 os.mkdir("./pixiv_images") saving_direcory_path = "./pixiv_images/" + str(illustrator_pixiv_id) + "/" if not os.path.exists(saving_direcory_path): os.mkdir(saving_direcory_path) # ダウンロード #print(f"Artist: {illust.user.name}") #print(f"Works: {total_works}") results = [] for n_work in range(0, total_works): if n_work >= max_works: break # DL画像を絞り込む場合 # if target_tag not in illust.tags: #タグによる絞り込み # continue illust = json_result.response[n_work] print(f"Works: {n_work + 1}/{total_works}, Download: {DL_flag}",end="\r") #print(f"Title: {illust.title}") #print(f"URL: {illust.image_urls['large']}") #print("Caption: %s" % illust.caption) #print(f"Tags: {illust.tags}") illust.caption = "" # 出力する際、冗長なので削除、コメントアウト可 results.append(illust) image_urls = [] 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] image_urls.append(page_info.image_urls) else: # イラストの場合 aapi.download(illust.image_urls.large, saving_direcory_path) image_urls.append(illust.image_urls) if DL_flag: for image_url in image_urls: exp_path = os.path.join(saving_direcory_path, image_url.large.split("/")[-1]) #ダウンロード済みを確認 if not os.path.exists(exp_path): aapi.download(image_url.large,saving_direcory_path) sleep(3) # ページを移動したら一時待機する(マナー) else: print(exp_path,"exists.") print() with open(f"./logs/{illustrator_pixiv_id}.json", "w",encoding="utf-8") as f: json.dump(results, f, indent=1, ensure_ascii=False)
main.py
import get_following_userID import get_illustrations import get_api from time import sleep api, aapi= get_api.get_api() ids = get_following_userID.get_following_userID() for i, id in enumerate( ids): print(f"Users: {i+1}/{len(ids)}, ID: {id}") get_illustrations.get_illustrations(api, aapi, int(id), False) sleep(1)
大量の画像をダウンロードすると、サーバーと回線に負荷を与える可能性があります。兵庫県警や神奈川県警等に恣意的な検挙を受けないためにも、負荷を与えないようにして使ってください。