【Python入門】Pyscriptで楽天APIを使ったアプリを作ってみた!

この記事は約12分で読めます。


PyscriptとはPythonがhtmlファイルで使えるものです。
HTML、CSS、JavaScriptの基本的な知識は必要です。
まだできたばかりで本番では使用しない方がいいようです。
htmlファイル一つ作ればいいだけなので開発環境はエディターだけで済みます。
実行環境はウェブプラウザ。
パソコンにPythonがインストールされてる必要はありません。
今回アーティスト名を入力したら
楽天APIでCD検索して結果を表示するプログラムを作りました。
 
完成品 1番最後に機能アップ版もあります!

Pyscriptとは

こちらのYoutubeが分かりやすいです。
【話題のPyScript!】HTMLファイルにPythonが書ける?!Webブラウザで動くPythonを解説!〜プログラム初心者用〜
基本的なHTMLコードに以下があれば動きます。

headタグの中に以下2行追加で使える。

<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>

コードを書く場所、bodyタグ内。

 <py-script>
    print('テスト') 
</py-script>

開発環境

開発環境はhtmlファイル一つだけで動くのでWindowsのメモ帳でも作れます。
メモ帳使うときは、保存するときにテキストファイルで保存しないように注意が必要です。
保存するときにファイルの種類をすべてに選択し
ファイル名は必ず*.htmlというファイル名で保存しましょう。

しかしメモ帳ではさすがにプログラミングには不便です。特にインテンド。
一般的にはパソコンにVSCodeなどのエディターをインストールして
プログラミングします。
Jsfidleというオンラインエディタだとパソコンに何もインストールする必要がありません。

実行は作ったhtmlファイルをウェブプラウザで開くだけです。

Pythonの実行環境を用意する必要がありません。
逆にJupiterNotebookでRunしても動かせません。

コード

requestsに関して

こちらを参考にさせていただきました。PyScriptを試してみました
requestsではrequests.get(request_url,params)のようにして
urlパラメータを連結できました。
open_urlは多分できないようなので
以下のようにurlのあとに?’キー’=’value’&’キー’=’value’という形でurlを作ります。

import urllib.parse
from pyodide.http import open_url
import json 

省略

    request_url='https://app.rakuten.co.jp/services/api/BooksCD/Search/20170404'
    APP_ID='個人別コード'
    params={'artistName':keyword,
                'sort':'-releaseDate',
               'applicationId':APP_ID}

    url=request_url+'?'+'artistName='+urllib.parse.quote(keyword)+r'&sort='+'-releaseDate'+r'&applicationId='+APP_ID
    
    res = json.loads(open_url(url).read())


日本語になる可能性のある部分はurllib.parse.quoteにより%エンコードします。
%エンコードについては以下の記事を参考にしてください。

ソースコード

楽天APIのコード部分はAPP_ID=’個人別コード’としてありますので
このままコピペしても動きません。
楽天APIの使い方は、Pythonで楽天トラベルAPIを使用した宿泊先リスト作成方法をわかりやすく解説!が分かりやすいです。

イチゲをOFUSEで応援する

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Pyscript練習</title>
  <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>

</py-env>
<style type="text/css">
.cgap {
  display: grid;
  gap: 20px 20px;
}
h1{
  font-size:200%;
  color: #ff0000;
  background-color: #ffffff;
}
a {color: skyblue; text-decoration: underline;}
.btn--orange,
a.btn--orange {
  color: #fff;
  background-color: #eb6100;
}
.btn--orange:hover,
a.btn--orange:hover {
  color: #fff;
  background: #f56500;
}
table {
  border-collapse: collapse;
  text-align: center;
}
th, td {
  padding: 5px;
  border: 1px solid #333;
}
th {
  background-color: #2c88d9;
  color: #FFF;
}
</style>
</head>

<body>
<div style="display:flex; flex-flow: column; justify-content:center; margin: 6px 4px;">
<div class="cgap">


<h1>
楽天ブックスCD検索APIを利用したアプリ
</h1>
<div>
    <input id="input_test" class="border">
    <button id="btn" class="btn btn--orange" pys-onClick="searchCD">  検索  </button>
    <p>入力例:babymetal</p>
</div>
<p>表示はするけど反応するまでに数十秒かかります。反応するようになってからは速いです。</p>
<p>このサイトの詳細は<a href="https://kikuichige.com">イチゲブログ</a></p>
<label id='mes'></label>
<table>
  <tr><!-- 行1(見出し)-->
    <th>タイトル</th> <th>楽天ブックスCDリンク</th>
  </tr>
  <tr>
    <td><label id='0'></label></td> <td><label id='10'></label></td>
  </tr>
  <tr>
    <td><label id='1'></label></td> <td><label id='11'></label></td>
  </tr>
  <tr>
    <td><label id='2'></label></td> <td><label id='12'></label></td>
  </tr>
  <tr>
  <td><label id='3'></label></td> <td><label id='13'></label></td>
  </tr>
  <tr>
    <td><label id='4'></label></td> <td><label id='14'></label></td>
  </tr>

</table>
</div></div>
<py-script>
import urllib.parse
from pyodide.http import open_url
import json
def searchCD(*ags, **kws):
    input_test_element = Element("input_test")
    input_word = input_test_element.element.value
    
    input_test_element.clear() #処理後に入力フォームを空にする

    keyword=input_word
     
    test_text=''
    request_url='https://app.rakuten.co.jp/services/api/BooksCD/Search/20170404'
    APP_ID='個人別コード'
    params={'artistName':keyword,
                'sort':'-releaseDate',
               'applicationId':APP_ID}
               
    
    url=request_url+'?'+'artistName='+urllib.parse.quote(keyword)+r'&sort='+'-releaseDate'+r'&applicationId='+APP_ID
    
    res = json.loads(open_url(url).read())
    
     
     
    result=res
    dic=[]
    if 'error' in result:
      test_text='失敗です!'
    else:
      if result['last'] !='':
        suu=result['last']
      else:
        suu=0 

      for i in range(suu):

        if (result['Items'][i]['Item']['smallImageUrl']!='' and result['Items'][i]['Item']['title']!='' and result['Items'][i]['Item']['itemUrl'] !=''):
          dic.append(result['Items'][i]['Item']['title'])
          dic.append(result['Items'][i]['Item']['itemUrl'])

      if dic == []:
        test_text='該当するアーティストがいません'
      else:
        dic1=dic[0::2]
        dic2=dic[1::2]
        for i in range(5):
          pyscript.write(i,dic1[i])
          pyscript.write(i+10,dic2[i])
    pyscript.write("mes",test_text)

    return  

</py-script>

</body>
</html>

CORS

参考にさせていただいたPyScriptを試してみましたでCORSに関して触れています。
CORSとはCORSエラーで検索すると出てきます。
これは結構やっかいでパソコンにPyscript demoのサンプルをコピーして実行しようとするときも
このエラーに悩まされます。(pathsを使ってるサンプルの場合)
パソコンの場合、原因は多分ここで紹介されてる内容だと思います。
 【Ajax】ローカルファイルを読み込もうとしたらCORSエラーが発生したので解決した
簡単な対策としてはファイルを分けないで
*.pyを<scriput></script>内に全部書いて読み込みに行かないようにするとうまくいきます。

エラーの確認方法はプラウザの検証ツールを使ってコンソールのところをクリックすると見れます。
クロームの場合は以下

今回使用した楽天APIは下のようにレスポンスが返ってきてます。
(ネットワーク→対象の通信を右クリック→コピー→レスポンスヘッダをコピーで見れます。)
どこのオリジンからの通信もOK(Access-Control-Allow-Origin: *)と設定されているようです。
なので何もしなくてもうまくいきます。

HTTP/1.1 200 200
Date: Fri, 13 May 2022 04:53:16 GMT
Server: Apache
Access-Control-Allow-Origin: *

公開

できたものを公開するにはサーバーに***.htmlをアップロードすればできます。
やり方はこちらの記事を参考にしてください。

感想

いいと思う部分

  • htmlファイル一つで済む。

使いにくい部分や疑問

  • 動き出すまでに時間がかかる。
  • タグがPythonで変更できないのか?<a href=や<img src=がPythonで変更できたら便利。
    できました。↓↓

aタグやimgを動的に変更した完成品

イチゲをOFUSEで応援する

MENTAやってます(ichige)

コメント

タイトルとURLをコピーしました