質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

1回答

4504閲覧

AWS lambda selenium webdriverによるスクリーンショットで文字化け

miyazy

総合スコア8

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

1クリップ

投稿2021/05/01 14:48

編集2021/05/01 15:17

AWS lambda selenium webdriverでスクリーンショット取得するようにしていますが、文字化けがなかなか解消しません

以下のサイトを参考にしてフォントを設置しております。
https://masakimisawa.com/selenium_headless-chrome_python_on_lambda/

実行時にフォントがうまく置かれているか出力確認するようにして
問題なく設置できていると思っております。

別途こちらのサイトも参考にやってみましたが、
フォントキャッシュの生成というのがうまくできませんでした。
https://qiita.com/komeda-shinji/items/e049edd1389579059c53

その他簡単な方法がありましたら教えていただければと思います。
(公開されているフォントのlambdaレイヤーのARNとかありますか?)

python

1import os 2import glob 3 4from selenium import webdriver 5from ftplib import FTP_TLS 6 7 8localpath = "/tmp/" 9ftppath = "####/test/" 10 11 12# webdriber.chrome option 設定 13options = webdriver.ChromeOptions() 14options.add_argument("--headless") 15options.add_argument("--disable-gpu") 16options.add_argument("--window-size=1704x1078") 17options.add_argument("--disable-application-cache") 18options.add_argument("--disable-infobars") 19options.add_argument("--no-sandbox") 20options.add_argument("--hide-scrollbars") 21options.add_argument("--enable-logging") 22options.add_argument("--log-level=0") 23options.add_argument("--v=99") 24options.add_argument("--single-process") 25options.add_argument("--ignore-certificate-errors") 26options.add_argument("--homedir=/tmp") 27options.binary_location = "/opt/bin/headless-chromium" 28 29 30 31#FTPS でファイルを 1 件アップロード 32def push(local_path: str,remote_path: str) -> None: 33 hostname = "##########" 34 username = "##########" 35 password = "##########" 36 37 with FTP_TLS(host=hostname, user=username, passwd=password) as ftp: 38 print("UPLOAD--- " + hostname + " " + local_path + " ---> " + remote_path) 39 ftp.storbinary('STOR {}'.format(remote_path), open(local_path, 'rb')) 40 41 42 43def lambda_handler(event, contxt): 44 45 print("--------------------------------") 46 print("環境変数",os.environ['HOME']) 47 48 print("----- /opt/.font") 49 files = os.listdir("/opt/.font") 50 for file in files: 51 print(file) 52 53 print("----- os.environ['HOME']") 54 files = os.listdir(os.environ['HOME']) 55 for file in files: 56 print(file) 57 58 print("--------------------------------") 59 60 url = "https://www.yahoo.co.jp/" 61 62 driver = webdriver.Chrome("/opt/bin/chromedriver", chrome_options=options) 63 64 print("接続--> "+url) 65 66 driver.set_window_size(1200, 1200) 67 driver.get(url) 68 time.sleep(3) 69 70 imgname = localpath + "screenshot.png" 71 72 # スクリーンショット 73 driver.get_screenshot_as_file(imgname) 74 print("画像保存 "+imgname) 75 76 driver.close() 77 78 79 files = glob.glob(localpath+"*.png") 80 for file in files: 81 if os.path.isfile(file): 82 filename = os.path.basename(file) 83 ftpfile = ftppath + str(filename) 84 localfile = localpath+str(filename) 85 #print(localfile," --> ",ftpfile) 86 push(local_path=localfile,remote_path=ftpfile) 87 88 #ファイル削除 89 #os.remove(localfile) 90 91 print() 92 93 return "ok" 94

実行結果

-------------------------------- 環境変数 /opt/ ----- /opt/.font NotoSansCJKjp-Regular.otf NotoSansMonoCJKjp-Regular.otf ipaexg.ttf ipaexm.ttf ----- os.environ['HOME'] .font bin python -------------------------------- 接続--> https://www.yahoo.co.jp/ 画像保存 /tmp/screenshot.png UPLOAD--- ######### /tmp/screenshot..png ---> #####/test/screenshot..png

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

初めまして。2つほどやり方がありそうです。

1つ目
selenium実行中にスクリーンショットしたいページへ遷移し、javascriptを埋め込んでstyle属性の変更を行う方法。ただし、iframeの対応はできない。
Lambda上のSeleniumでスクリーンショットを撮った際に文字化けする問題の解消

2つ目
fontファイルを設置して読み込む方法。

上記の実装を鑑みてfontファイルを読み込む上で2点怪しいなと思っている部分がありまして、
・fontファイルパスの権限に問題はないか?(読み込み、実行は可能?)
・fontキャッシュの更新を行っているのか?(こちら参照)

ご確認のほどよろしくお願いいたします。

参考
【 fc-cache 】コマンド――フォントキャッシュを更新する

投稿2021/05/01 22:09

編集2021/05/01 22:27
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyazy

2021/05/02 02:12

ご回答いただきありがとうございます。 1つ目について  コードを追加してみましたがうまくいきませんでした。(コードの内容が理解できてないです。) 2つ目について  fontファイルのパスについて確認したところ、読み込みも実行も不可となっていました。  変更を試みたのですがうまくいきません。(圧縮前に権限をつけて圧縮しています。)  権限の変更方法がありました、お教え願います。 fontキャッシュの更新について  お教えいただいたサイトを参考に調査中ですが、まだ内容を理解しきれておりません。
退会済みユーザー

退会済みユーザー

2021/05/02 02:37

> 1つ目について // execute_script内のjavascriptコードを読み込み、実行する。 execute_script // styleタグを生成する。 var style = document.createElement('style'); // styleタグに対して、fontに関するcssを埋め込む。 style.textContent = `@import url('//fonts.googleapis.com/css?family=Source+Code+Pro');@importurl('//fonts.googleapis.com/earlyaccess/notosansjp.css');`; // headタグ内にstyleタグを埋め込む。 document.head.appendChild(style); // bodyタグ内のstyleのfontFamilyの変更 document.body.style.fontFamily = "'Noto Sans JP', sans-serif"; // preタグの子要素を持つcodeタグの部分に対してfontの変更を行う。 document.querySelectorAll('pre > code').forEach((el, idx) =>{ el.style.fontFamily = "'Source Code Pro', 'Noto Sans JP', monospace"; });
退会済みユーザー

退会済みユーザー

2021/05/02 02:40

> 2つ目について 権限に関すること ファイル実行するfontファイルに関して権限変更しないといけないと思うので、lambda実行時に変更する必要がありそうです。 こちらのコードが役に立ちそうですので、ご確認ください。 https://github.com/kuroroblog/check_price/blob/master/automate.py#L14
退会済みユーザー

退会済みユーザー

2021/05/02 02:41

> fontキャッシュの更新について 何か困ったことがありましたら、ご連絡ください〜
miyazy

2021/05/02 04:14

ありがとうございます。 def addExecutePermission(path,target): mode_map = { "u": stat.S_IXUSR, "g": stat.S_IXGRP, "o": stat.S_IXOTH, "a": stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH, } print(path) mode = path.stat().st_mode for t in target: mode |= mode_map[t] path.chmod(mode) addExecutePermission("/opt/.font/NotoSansCJKjp-Regular.otf","ug") 教えていただいたコードを参考に以上のコードを追加してみましたが、エラーが出てしまします。 File "/var/task/lambda_function.py", line 59, in addExecutePermission mode = path.stat().st_mode AttributeError: 'str' object has no attribute 'stat'
退会済みユーザー

退会済みユーザー

2021/05/02 06:01

from pathlib import Path をimportして addExecutePermission(Path("/opt/.font/NotoSansCJKjp-Regular.otf"), "ug") に変更するとどのようになりますか?
miyazy

2021/05/02 06:53

次のようなエラーが出ました。 { "errorMessage": "[Errno 30] Read-only file system: '/opt/.font/NotoSansCJKjp-Regular.otf'", "errorType": "OSError", "stackTrace": [ [ "/var/task/lambda_function.py", 76, "lambda_handler", "addExecutePermission(Path(\"/opt/.font/NotoSansCJKjp-Regular.otf\"),\"ug\")" ], [ "/var/task/lambda_function.py", 61, "addExecutePermission", "path.chmod(mode)" ], [ "/opt/python/pathlib.py", 1117, "chmod", "self._accessor.chmod(self, mode)" ], [ "/opt/python/pathlib.py", 346, "wrapped", "return strfunc(str(pathobj), *args)" ] ] }
退会済みユーザー

退会済みユーザー

2021/05/02 08:23

なるほど、自分の方で少し動かしてみます。 明日のお昼頃には何かしら返事いたします。????‍♂️
miyazy

2021/05/02 08:32

ご親切にありがとうございます。 よろしくお願いします。
退会済みユーザー

退会済みユーザー

2021/05/03 03:48

すみません。とりあえず、スクリーンショットとる機構までは再現できました。 ただ、文字化け問題はまだ解消できていない状態です。 意外と難しいですね笑
退会済みユーザー

退会済みユーザー

2021/05/03 05:24 編集

うまくいきました。 今日明日中にまとめますのでお待ちください。
miyazy

2021/05/03 05:32

ありがとうございます。よろしくお願いします。
退会済みユーザー

退会済みユーザー

2021/05/04 04:05

お待たせしました。 こちらの記事にまとめましたので、ご一読いただけますと理解が深まると思います。 https://kuroro.blog/python/0Sd4HERaGbzIpSsyEVoz/ またこちらgithubのコードになります。 https://github.com/kuroroblog 実際動かしてみて、わからない部分が出てきましたら、ご連絡いただけますと幸いです。????‍♂️
miyazy

2021/05/04 05:37

上手くいきました、ありがとうございます。 短時間にこんなに丁寧にまとめていただいて、感謝とともに尊敬いたします。 記事をみてフォントについてやり方は問題ないのではと思ったのですが、 ダウンロードした内容をみてうまくいかなかった原因がわかりました。 「.fonts」ではなく「.font」としておりました。 結局はそこを訂正したらうまくいきました。 大変ご迷惑おかけしました。
退会済みユーザー

退会済みユーザー

2021/05/04 05:52

お〜、フォルダ名だったんですね。(笑) エンジニアやっていると、ついやってしまいますよね〜!! なりより、うまく行ってよかった!! 問題文のコード読んでみて、いい感じに書けていて、いいエンジニアが育ってる感じでして素直に嬉しいです。 Enjoy!!!
miyazy

2021/05/04 06:05

記事についてひとつ要望なのですが、 コードとフォントをdeploy.zipとしてアップロードしておりますが、 lambdaのコードソースに直接記入する方法も紹介していただきたいです。 こちらの方法ですとコードの修正が簡単にできるので便利だと思います。 その際、フォントは別途レイヤーにアップし環境変数を/opt/とすることになります。 このようなやり方を紹介しているサイトは私の探した限りは見受けられなかったので、 参考になる人が多いのではないでしょうか。
退会済みユーザー

退会済みユーザー

2021/05/04 07:39 編集

そうですね。 > lambdaのコードソースに直接記入する方法も紹介して 動くことを確認しましたので、しばらくお待ちください。修正します。 ご指摘ありがとうございます。????‍♂️
退会済みユーザー

退会済みユーザー

2021/05/04 07:47 編集

.fontsをLayerにして記事修正を行いました。 コード直書き方法の追記の件ですが、 ・直書きしてバグが発生する < zipファイルで固めてアップしたのちに、後でコード確認して理解を深める方が離脱なく問題解決に繋がりそう。 ・複数解を記事内で提示して、問題解決できなくなる。 ・.fontsをLayerにしたことで、コードの編集はできるようになった。 ので、今回は記入しないことにしました。 後々の機能開発にて、コメント機能を追加する予定で別解という形でコード直書きできる旨を伝える或いは、関連記事として作成するなどを考慮いたします。 ご指摘ありがとうございます。????‍♂️
miyazy

2021/05/04 09:04

記事確認しました。素早いご対応関心するばかりです。 >・.fontsをLayerにしたことで、コードの編集はできるようになった。 容量が少なければZIPでアップロードしても編集できましたね。 これならすぐ修正ができていいです。 この記事にもっと早く出会いたかったです。 サーバーレスを使う方法、dockerを使う方法などはありましたが、いまいち理解できずに苦労しておりました。ZIPを何度もアップロードし直して苦労していた次第です。
退会済みユーザー

退会済みユーザー

2021/05/04 09:08

そうだったんですね。 僕もLambda触ったの1年ぶりで、色々変わっててとてもワクワクしました!笑 多くの方に記事が見られて、幸せな人生が歩めますように〜!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問