【Python】BeautifulSoupの文字化け

PythonでBeautifulSoupを使ってスクレイピングを実装している時、いつもではないけどたまに取得した値が全て文字化けしていることがあった。調査してみたところ、どうやら取得対象を「text」で指定しているのがよくないとのこと。

res = requests.get('https://www.yahoo.co.jp')
bs = BeautifulSoup(res.text, 'html.parser')


「text」の代わりに「content」を指定することで文字化けしないようになった。

res = requests.get('https://www.yahoo.co.jp')
bs = BeautifulSoup(res.content, 'html.parser')

【Javascript】APIで取得した値をHTMLにセットしたのに表示されない

JavacriptでAPIを呼び出して取得したレスポンスから値を取り出し、HTMLのDOMを指定して表示するように実装したけど、表示されない。

callSampleAPI(url, function(result) {
   console.log("RESULT : callSampleAPI:", result);
   $("#display-here").text(result.sample-text);
});


Javascriptのconsole.logで見る限りは値はちゃんと取れてるのになぜHTMLに表示されない。これはAPIからのレスポンスはjson形式になっているからで、これを「JSON.parse」でオブジェクトに変換して扱ってやる必要がある。以下のように修正して無事表示されるようになりました。めでたしめでたし。。

callSampleAPI(url, function(result) {
   console.log("RESULT : callSampleAPI:", result);
   let parsedResult = JSON.parse(result);
   $("#display-here").text(parsedResult .sample-text);
});

【AWS】API gateway コールエラー:Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

JavascriptAPI gatewayを呼び出そうとしたら、こんなエラーが出た。

Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.


メッセージの内容通りだが、これはAPI gateway側でCORS(別ドメインからのアクセス許可設定)がされていないことが原因。

API gatewayのCORSの設定は以下のようなステップになる。


(1) まずはAPI gatewayのコンソール画面で、対象のリソースを選択し、「アクション」ボタンから「CORSの有効化」を選択

f:id:daylambsbecomelions:20211123202550p:plain


(2) 「CORSを有効にして既存のCORSヘッダーを置換」を押下。CORSの有効化処理が実行され、プロセス項目の緑のチェックがつく。

f:id:daylambsbecomelions:20211123203106p:plain


(3) 次に左のメニューから「ゲートウェイのレスポンス」を選択。「アクセスが拒否されました」にチェックを入れ、「編集」ボタンを押下

f:id:daylambsbecomelions:20211123203439p:plain


(4) 赤枠の個所に以下の通り入力する
レスポンスヘッダー:Access-Control-Allow-Origin
値:'*'(シングルクオート、アスタリスク、シングルクオート)

f:id:daylambsbecomelions:20211123204203p:plain


(5) リソースのツリー階層から「/」をクリックし、「アクション」プルダウンから「APIのデプロイ」を選択。以降は通常のデプロイと同じ操作のため割愛。

f:id:daylambsbecomelions:20211123204730p:plain




これでフロントからJavascriptで呼び出せば正常にレスポンスが返ってくるようになります。

Have a nice coding life!

【AWS】EKSのチュートリアルでKubernetes Dashboardに「Http failure response for api/v1/token/refresh: 0 Unknown Error」が表示される場合の対処法

f:id:daylambsbecomelions:20210204070158p:plain

この画面の話。赤枠のコマンドでトークンを表示させて、画面で入力すればOK、と書いてあるのですが、実際にやってみるとDashboardの画面上で以下のようなエラーが表示される

Http failure response for api/v1/token/refresh: 0 Unknown Error

うーん、書いてある通りにやってるんだけどなー。。
調べてみるとstack overflowに以下のコマンドで発行したトークンならいけるとのこと。

kubectl describe secret $(kubectl get secret | grep cluster-admin | awk '{print $1}')

【AWS】API GatewayからStep Functionsを呼び出す際のエラーを解消

API gatewayからLambda関数を直接呼び出して動かす仕組みを作ったけど、処理が大きくなるとAPI gatewayの最大実行時間である29秒制限に引っかかってしまってどうにも立ち行かない。解決方法を調べてみるとStepFunctionsを利用して非同期処理にする方法が最もすっきりできそうだったので実装してみた。

細かい設定方法などについては別サイトにてまとめられている記事がたくさんあったのでそちらを参考に頂いた方が早いかと思います(↓)が、
dev.classmethod.jpdocs.aws.amazon.com

今回はAPI gatewayからStep Functionsを呼び出すテストをした際に直面したエラーの解決方法についてメモしておきたいと思います。

以下、API gatewayからStep Functionsをcallする際のRequest Bodyの基本パラメータなります。

{
   "input": "string",
   "name": "string",
   "stateMachineArn": "string",
   "traceHeader": "string"
}

・ExecutionAlreadyExists
 ⇒上記パラメータの内、「name」は毎度別の名前にする必要があるようで、過去にした値を指定するとこのエラーが出ます。「name」を適当に別の値に変えればOK
・InvalidExecutionInput
 ⇒「input」パラメータには、Lambda関数に渡す引数を入力しますが、jsonの中にjsonを入れる形になるので以下のようにダブルクオートをエスケープしてあげる必要があるようです。こちらの記述方法に修正すればOK

"input": "{\"first_name\" : \"test\"}"

自分は直面しませんでしたが、他のエラーに関してもあまり親切には書かれていませんが以下に説明があります。
docs.aws.amazon.com

ご参考に!

【Laravel】peginateでLimit句が使えない!ので代替案

Laravelのpaginateメソッドは、元々のクエリで取得した結果に、()の引数で指定した件数で"limit"と"offset"を自動的に設定し処理しています。

(公式のサンプルより)
f:id:daylambsbecomelions:20210829104452p:plain

例えばこの元々のクエリ部分(「DB::table('users')」)で取得する件数を指定したい場合、例えば以下のように記述すれば普通にいけるのかなと思いきや、peginate側で発行されるlimitに上書きされ、自分で書いたlimit句は無視されてしまう。

DB::table('users')->limit(1000)->paginate(15)

では、この元々のクエリにlimitをかけたい場合はどうすればいいのか。検索するとカスタムペジネーションを作るなどの方法が紹介されていたが、大変過ぎるので以下のようなやり方でやってみた。

$subquery = DB::table('users')
                      ->select([
                             row_number() over () as rownum,
                             id,
                             name,
                             email,
                             password,
                      ])
                      ->limit(1000);
$query = DB::table($subquery)->select('*')->where('rownum', '<=', '1000');
$query->paginate(15);

やり方としてはselectに「row_number() over () as rownum(rownum部分は何でもいい)」を追加し、取得した行に連番を振る。その連番を使って行番号を制限したい件数以下に指定して取得し、そのクエリにpeginateをかけるというもの。他にも方法があるかとは思いますが、一応うまくいった実績のある方法として参考に頂ければと思います。