d_tail's blog

備忘や記録

【Tumblr API】Tumblrのブログやスキ(like)したポストの写真と動画をダウンロードする【Python】

はじめに

最近,Tumblrがアダルトコンテンツを禁止したり,その判定がガバガバ(キツキツ?)なせいで話題になっていました.

そんなことから,以前API関連を試していた時に,TumblrAPIをいじりかけてそのまま放置していたことを思い出したので,指定したブログや自分がlikeしたポストの写真と動画をダウンロードするコードを試しに書いてみました.

github.com

使用したライブラリ

コードを書くにあたって以下のライブラリを使用しました.

  • pytumblr
  • requests
  • beautifulsoup4
  • tqdm

pytumblrは公式(多分)で提供されている,Tumblr APIを呼び出すためのクライアントを作成できるライブラリです.

使い方

使い方の説明はリポジトリREADMEに書いてありますが,APIキーの取得関連についてだけ参考サイトなどを少し記載しておこうと思います.

このコードを使用するにはAPIキーが必要になります.
まずはアプリケーション登録を行ってコンシューマーキーとシークレットキーを取得します. 以下のサイトなどを参考にすると良さそうです.

また,上のサイトにも記載されているOAuth認証のためのトークンとシークレットトークンも必要になります.
プログラムで認証を行って取得する方法もありますが,以下のサイトから取得するのが簡単そうです.

参考:https://github.com/tumblr/pytumblr

感想

今回使用したライブラリの一つであるBeautifulsoup4ですが,スクレイピング関連で使うということで前から耳にしていたものの,使用するのは今回が初めてでした (大したことには使っていませんが).
スクレイピングもいつかやってみたいと思います.

参考・関連記事

【参加記録】AtCoder Beginner Contest 114

はじめに

AtCoder Beginner Contest 114に参加した記録です.

beta.atcoder.jp

A - 753

入力が7か5か3だったら'YES'を出力,そうでなければ'NO'を出力する.

N = int(input())

if N == 7 or N == 5 or N == 3:
    print('YES')
else:
    print('NO')

B - 754

文字列の先頭から順番に3つずつ取り出し,753との差の絶対値を比べていけば良い.
Pythonだと簡単.

S = list(input())

res = 753

for i in range(len(S)-2):
    X = ''
    for i in S[i:i+3]:
        X += i 
    X = int(X)
    tmp = abs(753-X)
    if tmp < res:
        res = tmp

print(res)

解説では2行で実装していました.

S = input()
print(min(abs(int(S[i:i+3]) - 753) for i in range(len(S) - 2)))

https://img.atcoder.jp/abc114/editorial.pdf

C - 755

(7,5,3)の3桁以上入力の桁数以下の直積集合(?)によって,解説における準七五三数を列挙して条件に合うものの数をカウント.
itertoolsが非常に便利でした.暇があったら使い方のまとめみたいなものを作りたい.
解説によると再帰関数で実装するのが素直な方法らしいです.

import itertools
import collections

N = input()

if int(N) < 100:
    print(0)
    exit()

product_list = []
for i in range(3,len(N)+1):
    product_list += list(itertools.product('753', repeat=i))

res = 0

for i in product_list:
    num = "".join(list(i))
    if int(N) < int(num):
        continue
    if num.count('5') > 0 and num.count('7') > 0 and num.count('3') > 0:
        res += 1

print(res)

D - 756

ググったら解けそうな気がしたけど,時間不足&結局方針も間違えていました.

コメント

ここ最近は競プロにあまり触れていなかったので,C問題が解けるか不安でしたが無事解くことができました.
そして今回のコンテストでレートが緑に到達しました.

f:id:d_tail:20181202235618p:plain

まだまだC問題も安定して解ける訳ではないので,できる限り陥落しないように精進したいです.

【参加記録】AtCoder Beginner Contest 113

はじめに

AtCoder Beginner Contest 113に参加した記録です.

beta.atcoder.jp

A - Discount Fare

X + Y/2を出力すれば良い.
A問題でしたが,制約をちゃんと見ていなかったのは気をつけたいです.

X,Y = map(int,input().split())
print(X + int(Y/2))

B - Palace

T−H[i]*0.006を計算してAとの差の絶対値が最小になるiを求めれば良い.
計算結果をintでキャストしたものを提出してしまったため1WA.
焦りすぎたせいで提出までに少し時間がかかってしまったのも反省点.

N = int(input())
T,A = map(int,input().split())
H = [int(i) for i in input().split()]
 
res = - 1
res_val = 100000
for i in range(N):
    av_temp = T - H[i] * 0.006
    if res_val > abs(av_temp - A):
        res = i
        res_val = abs(av_temp - A)
 
print(res+1)

C - ID

入力のPとYの組み合わせに市の番号を追加したものをソートしたり,県ごとに何回市が存在したかをカウントしていくリストを作成したりして解きました.
解法はそこそこで思いつけましたが,Pythonはリスト関係の処理が遅いらしいため,どのように書くか迷って時間を潰してしまいました.(そもそもappendを多用してるのが悪そう)

N,M = map(int,input().split())
PY = []
tmp = []
cheker = []
res = []
for i in range(M):
    tmp = list(map(int,input().split()))
    tmp.append(i)
    PY.append(list(tmp))
    res.append('')
 
sorted_py = sorted(PY, key=lambda x: x[1])
checker = [0 for i in range(N)]
 
for i in range(M):
    index = sorted_py[i][0]-1
    checker[index] += 1
    res[sorted_py[i][2]] = str(sorted_py[i][0]).zfill(6) + str(checker[sorted_py[i][0]-1]).zfill(6)
 
for i in range(M):
    print(res[i])

D - Number of Amidakuji

手付かず.

コメント

C問題がなんとか解けて良かったです.
次回もC問題が解ければレートが緑になる可能性があるので頑張りたいところです.

【精進記録】AtCoder Beginner Contest 066 C - pushpush

問題

beta.atcoder.jp

解法

TLEしか出せなかったので解説を見てAC.

最初に追加した要素ほど数列の中央側になっていくので,要素のindexの偶奇に気をつけて数列の前と後ろに交互に要素を追加していけば良い.

解法自体は思いついたが単純にPythonのリストに対してappend()で後ろに追加,insert()で先頭に追加,という方法をしていたのがよくなかった.
特にinsertは計算量がO(n)なので遅いらしい.
参考:

qiita.com

解説を見たところ,C++の場合はdequeというライブラリを使うと簡単にできると記されていたので,Pythonにも存在するか調べたところ,collectionモジュールにdequeが含まれていたのでこれを利用しました.

insert()の代わりにdequeのappendleft()を使えば計算量がO(1)になるようです.

コード

from collections import deque
 
N = int(input())
A = [int(i) for i in input().split()]
 
B = deque(maxlen=2*10**5)
 
if N % 2 == 0:
    for i in range(N):
        if i % 2 == 0:
            B.append(A[i])
        else:
            B.appendleft(A[i])
else:
    for i in range(N):
        if i % 2 == 0:
            B.appendleft(A[i])
        else:
            B.append(A[i])
 
print(*B)

Submission #3525231 - AtCoder Beginner Contest 066

コメント

dequeの存在を知れたのが良かった.
標準ライブラリに含まれているデータ構造などは調べておいたほうが良さそう.
加えて,問題を解いて練習するのと同時にそろそろアルゴリズムとデータ構造についても少しづつ練習していく必要がありそう.