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

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

新規登録して質問してみよう
ただいま回答率
85.46%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

Q&A

解決済

1回答

2231閲覧

Python requests-htmlでスマホ用サイトのスクリーンショットを撮りたい

lis

総合スコア15

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

0グッド

0クリップ

投稿2021/11/17 10:27

編集2021/11/19 06:50

やりたいこと

User-Agentによってスマホ用とPC用のページが切り替わるWebページで、スマホ用ページのスクリーンショットを撮りたいです。

どのようにすればスマホで表示している画面と同様の画面がスクリーンショットできるか教えて頂きたいです。

状況

screenshot()で、ターゲットWebページのスクリーンショットを画像ファイルとして保存することはできました。

しかし保存された画像は、実際にスマホで表示した画面とは異なるものでした。

表示が異なる箇所の例

  • 本来設定されている背景色が設定がない(白背景)
  • トップ画像などすべての画像が表示されていない
  • ハンバーガーメニューに畳まれるはずのメニューが<ul><li>をそのままリスト表示した状態で表示されている

これらのことから恐らくそもそもCSSが適用されていない状態と思われます。

実施したスマホ用ページはブラウザサイズをどれだけ大きくしても、表示横幅が広がっていくだけでコンテンツの表示に変更はないページです。
そのためサイズによる表示の違いは関係ありません。

またPCのChromeからUser-Agent偽装してアクセスし、正常に表示されることを確認したUser-Agentを用いて実施しても、同様の状況となっております。

試したこと

arender()のkeep_page, reloadパラメータに応じた保存画像の状況

r.html.arender()keep_page, reloadの値を変更することで状況が変わった。

  • keep_page=False: r.html.page=Noneとなりr.html.page.screenshot()でエラー(このためTrueに固定)
  • reload=True: r.html.arender()が実行された後、PC用サイトが読み込まれるため、PC用ページが保存される
  • reload=False: r.html.arender()が実行された後、スマホ用サイトが読み込まれるが、スマホ用ページだが画像やスタイルなど適用されていないようなものが保存される(表示画面とは異なる状態)

→例えば背景が黒なのに白い、ハンバーガーメニューで畳まれているメニューがリスト表示されている等

arender()のwait, sleepパラメータを設定

arender()にwait, sleepパラメータを設定(長めにしてみた)。

結果は変わらず期待した画像の取得はできなかった。

python

1await r.html.arender(wait=60, sleep=60, keep_page=True, reload=False)

r.html.page.screenshot.__doc__を確認

print(r.html.page.screenshot.doc)を出力してみたが、画像ファイル形式に関するものしかなかったため、今回の期待値へのアプローチとは関係ない模様。

# print(r.html.page.screenshot.__doc__) Take a screen shot. The following options are available: * ``path`` (str): The file path to save the image to. The screenshot type will be inferred from the file extension. * ``type`` (str): Specify screenshot type, can be either ``jpeg`` or ``png``. Defaults to ``png``. * ``quality`` (int): The quality of the image, between 0-100. Not applicable to ``png`` image. * ``fullPage`` (bool): When true, take a screenshot of the full scrollable page. Defaults to ``False``. * ``clip`` (dict): An object which specifies clipping region of the page. This option should have the following fields: * ``x`` (int): x-coordinate of top-left corner of clip area. * ``y`` (int): y-coordinate of top-left corner of clip area. * ``width`` (int): width of clipping area. * ``height`` (int): height of clipping area. * ``omitBackground`` (bool): Hide default white background and allow capturing screenshot with transparency. * ``encoding`` (str): The encoding of the image, can be either ``'base64'`` or ``'binary'``. Defaults to ``'binary'``.

ソース

参考ページを元にスクリーンショット用のメソッドを作成しました。

python

1import requests_html 2from requests_html import AsyncHTMLSession 3 4def screenshot(asession, url, headers, is_full_page): 5 async def process(): 6 asession.headers = headers 7 print(f'- url: {url}\n- headers: {headers}\n') 8 r = await asession.get(url, headers=headers, verify=False) 9 await r.html.arender(keep_page=True, reload=False) 10 await r.html.page.screenshot({'path': 'screenshot.png', 'fullPage': is_full_page}) 11 return r 12 r = asession.run(process)[0] 13 14 15assesion = AsyncHTMLSession() 16url = 'https://exsample.com/' 17headers = { 18 "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) > > AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1", 19} 20is_full_page = True 21screenshot(assesion, url, headers, is_full_page)

参考ページ

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

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

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

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

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

ppaul

2021/11/17 12:24

HTMLなのですから、スマホによって表示される画面はそれぞれに違います。 同じスマホであっても、使用するブラウザの種類やバージョンが違えば画面は違います。
lis

2021/11/18 02:21

表示サイズ等の問題ではなく、表示コンテンツそのものが欠落したような状態です。 例えばPCブラウザからUser-Agentを偽装してそのページにアクセスしたとします。 この状況でどれだけブラウザサイズを大きくしても、トップ画像が表示され、メニューはハンバーガーメニューで折りたたまれているようなコンテンツです。 しかしスクリーンショット結果は、画像もなく、メニューも`<ul><li>`でリスト表示されているような状況のものでした。
hoshi-takanori

2021/11/19 04:15

参考記事のように arender の引数 wait (sleep も?) を指定する必要があるのでは?
lis

2021/11/19 06:52

「描画待ち」の箇所見落としていました。wait, sleep共に設定してみましたが、効果はなさそうでした(本文追記しました)。
guest

回答1

0

ベストアンサー

requests_htmlが対応していない可能性が高いです。

print(r.html.page.screenshot.__doc__)で確認すれば、スマホ用のオプションが出てくるかもしれませんが、望み薄です。

例えばPCブラウザからUser-Agentを偽装してそのページにアクセスしたとします。
この状況でどれだけブラウザサイズを大きくしても、トップ画像が表示され、メニューはハンバーガーメニューで折りたたまれているようなコンテンツです。

とのことでしたら、seleniumでスクリーンショットを取れば良いのではないかと思います。

Gooogleで 「selenium スクリーンショット」を検索するといろいろなサイトが表示されますので,それを参考にいてみてはいかがでしょうか。

投稿2021/11/18 23:05

ppaul

総合スコア24666

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

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

lis

2021/11/19 06:58

本文に追記しましたが、`print(r.html.page.screenshot.__doc__)`を見てみましたが、本件に影響しそうなオプションは得られませんでした。 > requests_htmlが対応していない可能性が高いです。 > > とのことでしたら、seleniumでスクリーンショットを取れば良いのではないかと思います。 requestsの系統できないか?と調べていた流れでrequests_htmlを知り、スクリーンショットが撮れることまでは分かっただけに残念です。 望み薄そうですが、もう少し探ってみて、ダメそうであればseleniumを検討してみようと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問