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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

selenium

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

font

近年は、コンピュータ上、紙面上で利用できる書体データのことをfontといいます。数える時の単位は「書体」で、データとしてのフォントは、デジタルフォントと呼ばれる場合があります。 HTML/CSSでは要素を指定し、フォント情報を調整することができます。

Q&A

解決済

2回答

1712閲覧

サーバーサイドSeleniumでスクショ時に豆腐化

YukiMoriNRT

総合スコア11

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

selenium

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

font

近年は、コンピュータ上、紙面上で利用できる書体データのことをfontといいます。数える時の単位は「書体」で、データとしてのフォントは、デジタルフォントと呼ばれる場合があります。 HTML/CSSでは要素を指定し、フォント情報を調整することができます。

0グッド

0クリップ

投稿2022/08/25 07:22

編集2022/08/25 07:56

発生している問題

データ収集の案件のためVPSを契約し、Seleniumスクレイピングをしています。
最初はどうせHeadlessだし、フォントをインストールせずにChromeだけインストールしてSeleniumしていました。URL等のテキストデータを抽出したり、ページの文章を抽出したテキストファイルをPCに落として閲覧するだけならこれで問題ありませんでした。

しかしながら、ある時ページの文章をテキストデータではなくスクショで保存しなければならない案件があり、日本語フォントが入っていないせいで豆腐化してしまう問題が発生しました。
ググったらtexlive-lang-cjkというライブラリ(この中に日本語フォントが入っている)を入れると直ると書いてあったので試してみましたが、1回目と同じように豆腐化。
ただ、texlive-lang-cjkを入れてからはコンソール画面が文字化けしなくなったため、Chrome以外はちゃんとフォントが更新されているようです。

なぜChromeだけダメなのか不思議ですが、おそらく日本語フォントをインストールする前にChromeをインストールしたせいで、フォント情報無しでChromeが初期化されてしまった可能性が考えられます。
このような場合、Chromeの設定ファイルを自分で書き換える必要があると思いますが、Linux初心者なのでどのファイルをいじればいいのか見当がつきません。
ご教授いただければ幸いです。
豆腐化

該当のソースコード

Python

1from selenium.webdriver import なんちゃらの数行は省略 2 3BASEURL = "https://b.hatena.ne.jp/" 4FILENAME = "screen_selenium.png" 5 6options = ChromeOptions() 7ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36' 8for arg in ['--headless', '--no-sandbox', '--window-size=800,600', '--user-agent=' + ua]: 9 options.add_argument(arg) 10service = ChromeService(executable_path=r'/usr/bin/chromedriver') 11 12with Chrome(service=service, options=options) as driver: 13 driver.get(BASEURL) 14 WebDriverWait(driver=driver, timeout=10).until(EC.presence_of_all_elements_located) 15 driver.save_screenshot(FILENAME)

補足情報(FW/ツールのバージョンなど)

WebArena Indigo
2 CPU 2 GB
Ubuntu 20.04
Python 3.8.10
selenium 4.4.3
Google Chrome 104.0.5112.101
ChromeDriver 104.0.5112.101

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

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

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

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

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

maisumakun

2022/08/25 07:57

> おそらく日本語フォントをインストールする前にChromeをインストールしたせいで、フォント情報無しでChromeが初期化されてしまった可能性が考えられます。 Chromeを再インストールしてみる、というのはどうでしょうか。
YukiMoriNRT

2022/08/25 09:16

Chromeとchromedriver両方をpurgeで完全アンインストールしてから再度installしてみましたが、結果は変わらず豆腐でした。 Chromeのconfigファイルの場所を教えて頂けますでしょうか? Linux初心者なので、さっぱりわからないのです。 WinPCだったら日本語フォントは標準装備で当然ですからね。
ikadzuchi

2022/08/28 16:27

> ブラウザによる文字コード判定が機能していない(日本語サイトも全部ASCII扱いになる)ことが原因とみて間違いなさそうです。 いいえ、そんなことはありません。 文字コードが正しく判定できたかどうかは文字数を見ればほとんど分かります。 今回の場合、UTF-8で書かれたサイトが正しい文字数で表示されています。これは正しくUTF-8として判定していなければあり得ない状況です。
guest

回答2

0

自己解決

遅くなってすみません。
その後、新しいインスタンスを立てた時はseleniumをインストールする前にtexlive-lang-cjkをインストールしたため豆腐化せずうまくいきました。
どうやらseleniumのインストール時点で存在するフォントのリストがseleniumにインポートされる仕様で、後からフォントを追加してもseleniumからは見えないようです。
その後、また別件のインスタンスを立てた時は、texlive-lang-cjkを使用せずPCからVPSにmeiryo.ttcをコピーしただけでもうまくいきました(もちろんseleniumインストール前です)

投稿2022/12/11 15:11

YukiMoriNRT

総合スコア11

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

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

0

こちらのサイトを参考に、次のコードへと修正しましたが、

Python

1JS_REPLACE_TEXT = """ 2function handleFont(node, fontFamily) 3{ 4 node.style.fontFamily = fontFamily; 5} 6 7function walk(node, fontFamily) 8{ 9var child, next; 10 11 switch (node.nodeType) 12 { 13 case 1: // Element 14 handleFont(node, fontFamily); 15 case 9: // Document 16 case 11: // Document fragment 17 child = node.firstChild; 18 while (child) 19 { 20 next = child.nextSibling; 21 walk(child, fontFamily); 22 child = next; 23 } 24 break; 25 26 case 3: // Text node 27 break; 28 } 29} 30 31var style = document.createElement('style'); 32style.textContent = `@import url('//fonts.googleapis.com/css?family=Source+Code+Pro');@importurl('//fonts.googleapis.com/earlyaccess/notosansjp.css');`; 33document.head.appendChild(style); 34document.body.style.fontFamily = "'Noto Sans JP', sans-serif"; 35walk(document.body, "'Source Code Pro', 'Noto Sans JP', monospace"); 36""" 37driver.execute_script(JS_REPLACE_TEXT)

英字部分のフォントデザインが若干変化しただけで、日本語部分の豆腐化は相変わらずです。
CSSのフォント指定がASCII文字には効いているが、マルチバイト文字には効いていないということは、フォントの問題ではなく、ブラウザによる文字コード判定が機能していない(日本語サイトも全部ASCII扱いになる)ことが原因とみて間違いなさそうです。
豆腐化2
ここでの文字コード判定をChrome自体が行っているのか、それともPythonで文字コードを判定してからChromeに渡しているのかは、最初はよくわかりませんでした。
しかし、今回の実行時はコンソールに変なメッセージが出て、そのうちの1つが文字コード判定ライブラリのchardetからの警告だったので、どうやらこれが怪しそうです。
実は数日前も、別案件の1MB超のテキストデータ処理で、高速化のためにSeleniumの代わりにrequestsを使ったら文字化けでハマってしまい、ググったらこちらのブログに辿り着いて、

公式のベンチマークによると、chardetが0.35(call/s)に対して、cchardetは1467.77(call/s)となります。

と書かれていたのでcChardetをインストールしてしまったんですよね。
そのせいで既存のchardetと競合してしまい、chardetへの依存関係にある他のライブラリ(その中には当然、seleniumも含まれます)が全部おかしくなってしまった線が濃厚っぽいです。

Console

1/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.12) or chardet (3.0.4) doesn't match a supported version!

というわけで、1MB超のテキストデータを扱うことは当面なさそうなので、pip uninstall cchardetしてから再度チャレンジ…やっぱりダメでした。
コンソールの警告は出なくなりましたが、肝心のスクショは豆腐のままです。
イメージ説明
一体どうすればいいのでしょう?
色々なライブラリをいじり過ぎて依存関係がカオスになっているので、いっそのこと新しいインスタンスを立ち上げてリセマラしたほうがいいですかね?(こういう時はVPSって便利ですよね)

投稿2022/08/25 11:23

YukiMoriNRT

総合スコア11

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

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

ikadzuchi

2022/08/28 16:23

ここは解答欄です。質問に追記してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問