LoginSignup
7
9

More than 5 years have passed since last update.

Tornado+Tornado-JSONでとりあえずGetできるようにする

Last updated at Posted at 2016-03-22

何がやりたかったか?

お付き合いのあるとある公共施設のブログというかWeb日記というかをスクレイピングしてきたものを、RESTでロボットから呼び出してお話させてみたく、とりあえずJSONでスクレイピングしてきた内容を返すだけの簡易サービスを作って置きたかった。

RSSやらAtomやらのフィードがあれば、それを使えばよいのだろうけど、いかんせんそれがなかったので、なんとかしようとしたというのが前提になっている。

簡単にJSONを返すだけのサービスをTornadoで作る

ということで、Tornadoを使ってスクレイピング結果をGetで、かつ、JSONで返せるようにしようと考えた。作成に使った環境は以下の通り。

  • OS:Ubuntu15.10
  • Python:3.5.1
  • Tornado:4.3
  • Tornado-JSON:1.2.2

Tornadoを使った簡易なWeb API作成で、JSONを返すための方法はいくつかあると思うが、今回はTornado-JSONを利用した。Tornado-JSONのsampleやtutorialを参考にすれば、そんなに迷わないはず。

まずはTornadoでのWebアプリケーション作成と同様

以下のような感じで、WebアプリケーションとしてURLで呼び出せるようにするための部分を書く。

diary_talker.py
import tornado.ioloop
from tornado_json.routes import get_routes
from tornado_json.application import Application

def main():
    import diarytalker
    routes = get_routes(diarytalker)
    application = Application(routes=routes, settings={})
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == '__main__':
    main()

tornado_json.routesにより、この後記述するAPIのエンドポイント部分のパッケージ名、RequestHandlerから、自動でルートを特定してくれるので、自分でルートの記述を行う必要はない。インポートしているdiarytalkerがRequestHandlerが含まれるAPIの本体。

RequestHandlerを含んだAPI本体のパッケージ

以下のようなディレクトリ構成で作っていく。

ディレクトリ構成
ーdiary_talker.py
|
|
ーdiarytalker/
      |
      |ー__init__.py
      |ーapi.py
      |ーdiary.py

インポートされるdiarytalker下で、API本体の実装はapi.pyに記載している。diary.pyはスクレイピングの実装だた、今回の本題とは外れるので、割愛。とにかくWebアクセスしてBeautifulSoup4などを駆使して日記をスクレイピングし、日付、タイトル、本文をdictionary化して返すメソッドが定義されている。

from tornado_json.requesthandlers import APIHandler
from tornado_json import schema
import diary

class DiaryTalkerHandler(APIHandler):
    @schema.validate(
        output_schema={
            "type": "object",
            "properties": {
                "date": {"type": "string"},
                "title": {"type": "string"},
                "body": {"type": "string"}
            }
        }
    )
    def get(self):
        td = diary.Diary()
        diary = td.get_newest_diary()
        return {
            "date": "{}".format(diary["date"]),
            "title": "{}".format(diary["title"]),
            "body": "{}".format(diary["body"])
        }

api.pyのgetメソッドでは、スクレイピングを行っているDiaryのget_newest_diaryメソッドを呼び出し、結果の入ったdictionaryから、schemaにより定義したJSONを返す実装になっている。日記の本体(日付、タイトル、本文)はschema定義のPropertiesでそれぞれ型とともに指定している。

実際に呼び出すときは

http://〜/api/diarytalkerで呼び出せる。結果は

結果
{"data":{
  "date":"20160323",
  "title":"hoge",
  "body":"〜"
 },
 "status": "success"
}

のような感じに返ってくる。

7
9
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
7
9