LoginSignup
2
3

More than 5 years have passed since last update.

pixiv小説をクロールしてみる

Last updated at Posted at 2018-02-20

こんにちは。
先日ふと、pixiv小説をデータセットに使いたいと思いクローラーを作れないかなと思って作ってみました。

apiはtwo/pixiv.pyを利用します。
リポジトリをクローンしたのち作業はpixiv/で行います。

プログラムは指定したidから順番に1つづつ減らしていって取得しています。

  • id
  • 本文
  • タグ

をsqliteに突っ込んでます。
errorが帰ってきたらerror文をみてapi制限エラーだったらsleepするようにしてます。

以下コードです。

crawl.py
# -*- coding: utf-8 -*-
from pixiv.auth import OAuthHandler
from pixiv.api import PixivAPI, AppPixivAPI
from pixiv.cursor import Cursor, AppCursor
from pixiv.utils import PixivDownload

import sys
import sqlite3
import time

import json

auth = OAuthHandler()
auth.login('id', 'pass')

aapi = AppPixivAPI(auth)
con = sqlite3.connect("novel.db")
cur = con.cursor()
cur.execute("""CREATE TABLE IF NOT EXISTS Novel(id int PRIMARY KEY,tag varchar(10000), text varchar(10000));""")

cnt=200000
while(True):
    try:
        novel=aapi.novel_text(novel_id=cnt)
        tagstr=''
        try:
            series_prev=novel.series_prev.id
            sprev=aapi.novel_text(novel_id=int(series_prev))
            for tag in sprev.series_next.tags:
                tagstr+=tag['name']+','
        except:
            pass

        try:
            series_next=novel.series_next.id
            snext=aapi.novel_text(novel_id=int(series_next))
            for tag in snext.series_prev.tags:
                tagstr+=tag['name']+',' 
        except:
            pass
        if(tagstr==''):
            cnt-=1
            continue
        con.execute("insert or replace INTO Novel VALUES(?,?,?)", (cnt,tagstr,novel.novel_text))
        sys.stdout.write("\r%d Download." % cnt)
        sys.stdout.flush()
        con.commit()
        cnt-=1
    except  Exception as e:
        try:
            if('該当作品は削除されたか、存在しない作品IDです。'==str(e.args[0]['error']['user_message']) or '該当作品の公開レベルにより閲覧できません。'==str(e.args[0]['error']['user_message'])or '公開制限エラーです。'==str(e.args[0]['error']['user_message'])):
                sys.stdout.write("\r%d Download." % cnt)
                sys.stdout.flush()
                cnt-=1
                continue
            elif('閲覧制限エラーです。'==str(e.args[0]['error']['user_message'])):
                novel=aapi.search_novel(word=str(cnt))[0]
                id=str(novel.id)
                tagstr=''
                for tag in novel.tags:
                    tagstr+=tag['name']+','
                con.execute("insert or replace INTO Novel VALUES(?,?,?)", (cnt,tagstr,aapi.novel_text(novel_id=id).novel_text))
                sys.stdout.write("\r%d Download." % cnt)
                sys.stdout.flush()
                con.commit()
                cnt-=1
                continue
            elif('Rate Limit'==str(e.args[0]['error']['message'])):
                print('sleep600')
                time.sleep(600)

        except Exception as e2:
            print(e2.args)
        print(e.args)
        cnt-=1
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3