前回のおさらい
QiitaもしくはQiita:Teamからmdをダウンロードするコード
Qiita:Teamからデータを移行するかもしれないので、データのダウンロードのみ行ったよって状態でした。
実際の中身はjsonのbodyにmarkdownが入ってるので、それを引っ張ってくれば良いだけでした。
なんだそりゃって感じです。
urlに.mdをつけてダウンロードしようとしたのですが、ログイン画面のダウンロードになり、思惑失敗という形です。
ブラウザ開発者の方はログインさえできてしまえば、URLに.mdとつければ良いのでお手軽だと思います。
コードを書いた結果
今回は、お昼前に1時間、お昼後に3時間pythonと格闘してました。
すると、pythonのラッパー作ってる人がいて絶句しましたけどね…。
主に苦戦したのはglobal変数の使い方ですけど、なぜ値が入ってこないんだ!と思ってたら、global宣言した時のみ最後の値が反映される、という仕様であることに気づき、なるほどなぁ、となってました。
#!/usr/bin/env python
# coding: utf-8
import os
import sys
import json
import urllib.request
import urllib.parse
url = ''
apiKey = ''
teamName = ''
api = '/api/v2/items?per_page=100'
pageApi = '&page='
pageCount = 0
maxCount = 0
def argmentscheck():
global url
global apiKey
global teamName
global api
url = ''
apiKey = ''
teamName = ''
api = '/api/v2/items?per_page=100'
if len(sys.argv) == 2:
apiKey = sys.argv[1]
url = 'https://qiita.com'
print('Qiitaからデータを抜き出します')
elif len(sys.argv) == 3:
apiKey = sys.argv[1]
teamName = sys.argv[2]
url = 'https://' + teamName + '.qiita.com'
print('Qiita:Teamの' + teamName + 'からデータを抜き出します')
else :
print('引数の数が何かおかしいです')
def createDirectory(createDay, markdownUrl):
directoryArray = createDay.split('-')
createPath = "./" + directoryArray[0] + "/" + directoryArray[1]
if not(os.path.exists(createPath)):
os.makedirs(createPath)
def getPerPageJsonDownload():
global pageApi
global pageCount
global maxCount
headers = {"Authorization" : "Bearer " + apiKey}
requestUrl = url + api
if pageCount:
requestUrl = url + api + pageApi + str(pageCount)
request = urllib.request.Request(requestUrl, None, headers)
response = urllib.request.urlopen(request)
responseHeader = str(response.info())
if maxCount == 0:
headerList = []
headerDict = {}
for headerOneline in responseHeader.split('\n'):
for oneWord in headerOneline.split(': '):
if len(oneWord):
headerList.append(oneWord)
headerDict = dict(zip(headerList[0::2], headerList[1::2]))
maxCount = headerDict['Total-Count']
jsonRaw = response.read().decode('utf-8')
json.dumps(jsonRaw, ensure_ascii=False)
return jsonRaw
def fileWriting(createDay, markdown, title):
markdownTitle = title.replace('/', ' ') + '.md'
directoryArray = createDay.split('-')
createPath = "./" + directoryArray[0] + "/" + directoryArray[1] + "/" + markdownTitle
writeFile = open(createPath, 'w')
writeFile.write(markdown)
writeFile.close()
def main():
global pageCount
jsonRaw = getPerPageJsonDownload()
jsons = json.loads(jsonRaw)
for count in range(round(int(maxCount)/len(jsons))):
pageCount += 1
for oneWrote in jsons:
createDirectory(oneWrote['created_at'], oneWrote['url'])
fileWriting(oneWrote['created_at'], oneWrote['body'], oneWrote['title'] )
jsonRaw = getPerPageJsonDownload()
jsons = json.loads(jsonRaw)
if __name__ == '__main__':
argmentscheck()
main()
あ、前回の記事で一個誤りがありました。
pageの考え方がないものだと思っていたら、Qiitaにもpageの考え方がありました。
その内容が盛り込まれています。
Qiita APIからpageを取得する場合、headerにTotal-Count
が存在しますので、うまく取り出すようにします。
取り出し方としては、以下のようになります。
if maxCount == 0:
headerList = []
headerDict = {}
for headerOneline in responseHeader.split('\n'):
for oneWord in headerOneline.split(': '):
if len(oneWord):
headerList.append(oneWord)
headerDict = dict(zip(headerList[0::2], headerList[1::2]))
maxCount = headerDict['Total-Count']
最初だけQiitaの記事数の最大値がわからないので、処理が無駄にならないよう、最初のみ実行させています。
responseHeaderは、改行区切り
になってますので、splitで分割し、さらに:{space}
で改めて分割し直してます。
headerがこの仕様じゃなかったらわなわなと震えてるところでした。
これ、Qiita:Team仕様にしてますので、Qiitaで流した場合、トークンの上限に達するまで延々取得し続けますのでご注意ください(ぉぃ
タイトルをファイル名にしてますが、詰めが甘く、/
が含まれる場合は、{space}
に置き換えてます。
先頭に.
がある場合は考慮されていません。
考慮したい場合は、以下にコーディングを足していただければと思います。
markdownTitle = title.replace('/', ' ').replace('.', {.に変わる何か}) + '.md'
これからやること
残タスクはざっとこんな感じです。
- Qiita:Teamからイメージを取得する処理
- Qiita:Team内の画像パスを相対パスに書き換える対応
できたらまた記事投稿します。お元気で。