歩いたら休め

If the implementation is easy to explain, it may be a good idea.

【Python】【pixiv】pixivAPIから、アニメキャライラストのタグデータをcsvで出力する

pixivは(基本的に)APIを公開しておらず、ログインした状態で全てのページを情報を参照する方法が無いか長らく悩んでいました。以前、よくわからないpixivAPIを使って、ログインしていない状態で取得できる限られたデータからアニメの人間関係ネットワークを作ったことがありましたが、これ以上のことはできそうにないなと思ってました。

【集計】pixiv小説タグでアイカツの人間関係ネットワークを描いてみた│今私は小さな魚だけれど

よく調べてみると、APIに「&PHPSESSID=」という引数があり、これを使えば全てのデータが取得できると下の記事に書いていました。

PixivAPIを使った検索とソートソフトの配布:ブロマガのタイトル * - ブロマガ

 

※12/17日追記
上の方法ではPHPSESSIDが取得できなくなっていました。ブラウザのクッキーから自分のIDを参照して使いましょう。

WindowsのFirefoxの場合、pixivにログイン→メニューのオプション→プライバシー→Cookieを表示→pixivで検索→PHPSESSIDのある項目から取得できます。これ以降のやり方は今まで通りでOKのようです。

 

python2系で書いたんですが、文字コード変換がややこしくて「.encode("utf-8")」が非常に多いです。python3系だと統一されてるみたいなんですが。

pixivAPIの中身はこの記事を参考にしました。またR-18かどうかを判別するカラムも見つけたのでそれも出力データに残してあります。

# -*- coding: utf-8 -*-
import pandas as pd
from dateutil.parser import parse
from datetime import datetime

word = "アイカツ"
#SSID取得元:http://spapi.pixiv.net/iphone/login.php?mode=login&pixiv_id=
SSID = "(取得したPHPSSID)"
preurl = "http://spapi.pixiv.net/iphone/search.php?s_mode=s_tag&word=" + word + "&PHPSESSID=" + SSID

#空のデータフレームを取得
frame = pd.DataFrame()

for pagenum in range(1,200):
    url = preurl + "&p=" + str(pagenum)
    df = pd.read_csv(url, header=None, encoding='utf-8')
    if len(df[0]) == 50: #pandasのバージョンによってカラムの指定方法が違う?
        frame = frame.append(df)
        print pagenum ,
    else:
        frame = frame.append(df)
        print pagenum
        break


frame2 = frame[[0,1,12,13,15,16,17,26]]
frame2.columns=["picID","userID","datetime","tags","num_of_rating","rating","visits","R-18"]


#datetimeを日付と時間のカラムに分ける
datelist = list()
timelist = list()
for date in frame2.datetime:
    datelist.append(parse(date).date())
    timelist.append(parse(date).time())

frame2["date"] = datelist
frame2["time"] = timelist

#キャラクターのタグが含まれているか2値のカラムを作る
clist = [u"星宮いちご",u"霧矢あおい",u"紫吹蘭",u"有栖川おとめ",u"藤堂ユリカ",u"北大路さくら",u"一ノ瀬かえで",u"神崎美月",u"三ノ輪ヒカリ",
         u"神谷しおん",u"光石織姫",u"ジョニー別府",u"涼川直人",u"星宮りんご",u"星宮らいち",u"音城セイラ",u"冴草きい",u"風沢そら"]

for chara in clist:
    templist = []
    for tags in frame2.tags:
        if chara.encode('utf-8') in tags.encode('utf-8').split():
            templist.append(1)
        else:
            templist.append(0)
    frame2[chara.encode("utf-8")] = templist
        

#不要なカラムを削除(tagsは文字コードの都合でto_csvで出力できない?)
del frame2["tags"]
del frame2["datetime"]

frame2.to_csv("ai_test.csv",index=False,encoding='utf-8')

 

これを実行すると、 以下の様なcsvファイル(ai_test.csv)が保存されます。

 

picID userID num_of_rating rating visits R-18 date time 星宮いちご 霧矢あおい
XXXXX XXXXX 1 10 64 0 2013/12/17 X:XX:XX 0 0 0
XXXXX XXXXX 6 57 173 1 2013/12/17 X:XX:XX 1 0 0
XXXXX XXXXX 2 20 24 0 2013/12/17 X:XX:XX 0 0 0
XXXXX XXXXX 6 60 165 0 2013/12/17 X:XX:XX 0 0 0