見出し画像

ツイッター漫画の画像を一括取得し、pdfにまとめる方法[100日後に退職する47歳編]

はじめに

ツイッターで毎日更新される短めの漫画を皆さんは見られたりしますか?
最近だと、きくちゆうきさん作の100日後に死ぬワニや@tome_uraさん作の100日後に退職する47歳を僕はリアルタイムで追っていました!
(他にも面白い漫画があればぜひとも教えてほしいです!!)

これらの漫画をツイッター上で読んでいて思ったのですが、一話目とかの昔の話を確認するとなるとだいぶ過去のツイートに遡る必要が出てきて、手間に感じませんか?

今回はそんな手間を解消すべく、
ツイッター漫画の画像を一括取得して、PDF形式の漫画を生成したいと思います!

こんなかんじのができますよ!↓↓↓

スクリーンショット 2021-10-31 20.41.41

※Togetterとかのまとめツイートみればいいじゃん?という風に思われる方もいると思いますが、それでOKだと思います笑。ただPython力を磨くためにもトレーニングの一環として今回はPythonを使って漫画を生成してみたいと思います。

概要

以下の手順になります。

1.ツイッター上の特定アカウントの画像を取得
2.収集した画像(jpg)を1つのpdfに変換

詳細

1.ツイッター上の特定アカウントの画像を取得

今回は100日後に退職する47歳の画像を一括取得するので、作者のtomu_ura様をuserIDに指定します。
中段あたりにある以下の条件文で特定タグのツイートのみ取得しています。
(本当はparamsのqでタグ反映させたかったがうまくいかず...)

if "#100日後に退職する47歳" in content["text"]: # ツイートに「#100日後に退職する47歳」という文章があれば次の処理に進む

また、以下の変数をご自身の設定に書き換える必要があります。

・TwitterAPIのKey4種を設定(CK, CS, AT, AS)
 →APIKeyの発行方法はググればいくらでも出でくるので割愛させて下さい...!

import json
import urllib.request
import os
from requests_oauthlib import OAuth1Session

CK = 'hogehoge'    # Consumer Key
CS = 'hogehoge'    # Consumer Secret
AT = 'hogehoge'    # Access Token
AS = 'hogehoge'    # Accesss Token Secert

url_media = "https://upload.twitter.com/1.1/media/upload.json"
url_text = "https://api.twitter.com/1.1/statuses/update.json"
TL = "https://api.twitter.com/1.1/statuses/user_timeline.json"

# OAuth認証 セッションを開始
twitter = OAuth1Session(CK, CS, AT, AS)

# userID = input("userID:")
userID = "tome_ura" # アカウント指定

GET_COUNT = 10
GET_AT_ONCE = 200

params = {
   "screen_name":userID,
   "count":GET_AT_ONCE,
   "include_entities":True,
   "exclude_replies":False,
   "include_rts":False,
   "q":"#100日後に退職する47歳" # 特定タグのツイートのみ取得(したかったがうまくいっていない)
}

def getTL():
   global req,timeline,content
   req = twitter.get(TL,params=params)
   timeline = json.loads(req.text)

def saveContents():
   """
   "#100日後に退職する47歳"の画像だけ取得するために、if文を追加
   """
   global count,li
   for content in timeline:      
       if "extended_entities" in content: 
           if "video_info" in content:    
               print("video\n")
           else:                      
               for photo in content["extended_entities"]["media"]:   
                   if "#100日後に退職する47歳" in content["text"]: # ツイートに「#100日後に退職する47歳」という文章があれば次の処理に進む
                       title = foldername+"/"+content["id_str"]+"_"+str(count)+".jpg"  #//画像のタイトルを決める。画像にはid(id_str)が割り振られているため,それを利用してみた。
                       image_url = photo["media_url"]      
                       try:                                
                           urllib.request.urlretrieve(image_url,title)    
                       except:
                           print("error")
                       count += 1
                       li.append(content)
                       print("Image is saved successfully")
       else:
           print("No entities")
       global num
       print(content)
       num = content["id"]       

count = 0
li = []

dev_flag = False

if dev_flag:
   foldername = "./account/"+userID+"/dev/images/"        #//保存するフォルダの名前
else:
   foldername = "./account/"+userID+"/images/"        #//保存するフォルダの名前

if not os.path.exists(foldername):      #//保存フォルダが存在していない場合作成
   os.makedirs(foldername)

for i in range(1,GET_COUNT):            #//GET_COUNTの分だけgetTL()を呼び出す
   if(i==1):
       params = params
   else:
       params.update({"max_id":num})   #//呼び出すツイートの最大idを指定。こうしないと常に最新のGET_AT_ONCE件しか取得できない。
   getTL()                         #//TLをGET_AT_ONCE件取得
   saveContents()                  #//画像があれば保存

2.収集した画像(jpg)を1つのpdfに変換

img2pdfを使います!(jpg2pdfでも良きかと)

import os
import img2pdf
from PIL import Image # img2pdfと一緒にインストールされたPillowを使います

pdf_PATH = "./account/"+userID+"/comic/"
fn = "100日後に退職する47歳.pdf"
pdf_FileName = pdf_PATH + fn # 出力するPDFの名前
png_Folder = "./account/"+userID+"/images/" # 画像フォルダ
extension  = ".jpg" # 拡張子が.jpgのものを対象

if not os.path.exists(pdf_PATH):      #//保存フォルダが存在していない場合作成
   os.makedirs(pdf_PATH)

with open(pdf_FileName,"wb") as f:
   li = [Image.open(png_Folder+j).filename for j in os.listdir(png_Folder) if j.endswith(extension)]
   li.sort() # 掲載日順にソート
   f.write(img2pdf.convert(li)) # 画像フォルダの中にあるPNGファイルを取得し配列に追加、バイナリ形式でファイルに書き込む

出力ファイル(PDF漫画)をチェック

序盤の2話分以外は取得できていました。
取得できなかった2話については、ツイート本文にタグが含まれていないことが原因でした。
(今回はアカウント名とタグ情報が合致するツイートの画像を一括で取得している)まぁ、けど思ったよりは網羅的に出力できたかと思います。超ざっくり自動化システムとしては上出来かな...?笑

100日後に死ぬワニの方もPDFマンガにした感想

100日後に死ぬワニの方もPDF漫画にしてみたのですが、
上のコードのままだとなにも画像を取得できませんでした。
アカウントをチェックしたところ、作者の本垢で掲載した漫画をリツイートするという方式だったため、以下3つの修正が必要でした。

・paramsのオプション"include_rts"をTrueにする
・userIDをcrocodile_dies、出力PDFファイル名を変更する
・sortをsort(reverse=True)にする (1日目から表示する場合)

修正を加えたら画像収集&PDFはできたのですが、なぜか最終話(100日目)の画像が重複する現象が起きました。("include_rts"をTrueにした影響?)
後処理をうまくやれば重複をなくせるかとは思います。

スクリーンショット 2021-10-31 21.09.06

終わりがないのが終わり...

2つのアカウントの画像を収集してわかったことは、
アカウント毎に画像のアップの仕方は様々なので、それぞれの方式に合わせて都度コードを修正する必要がある
ということですね。


最後に

今回はツイッター漫画をまとめて収集して1つのpdf漫画を生成してみました!
pdfでまとめて一気読みするのも意外といいですね笑
改めてさんの漫画のクオリティに脱帽です。
少し畑は違いますが情報系の仕事しているので、共感できるところもあって普通にめちゃくちゃ面白い笑
こういうの作れるのすごいなぁ

課題ですが、リプライ欄のコメントとかが面白かったりタメになったりするので、html形式にして各ツイートのコメントをページごとにいい感じに載せられるようにできたらなぁと思います。(どうすればできるのかは全然検討つかないですが...)

以上です!ではでは👋

参考記事

紹介されているコードとほぼ一緒です!笑
神記事です。

【Python3】twitterAPIを使って好きなアカウントの画像を一気に取得する方法

Pythonを使って複数画像をPDFに変換する



この記事が気に入ったらサポートをしてみませんか?