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

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

新規登録して質問してみよう
ただいま回答率
85.34%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

selenium

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

Q&A

解決済

2回答

257閲覧

seleniumで、URLパラメータ付のリンク先のPDFをダウンロードしたい。

KENTATANAKA

総合スコア3

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

selenium

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

0グッド

1クリップ

投稿2024/09/12 01:52

実現したいこと

Seleniumでページ内の複数のリンク先のPDFファイルをダウンロードして、特定のフォルダに保存したい。

前提

Windows10 Anaconda Python3.8.18
selenium 3.14.1 (社内ネットワークだとver4以上にすると 「ConnectionResetError (10054, '既存の接続はリモート ホストに強制的に切断されました。', None, 10054, None)」が出てしまう)

links = browser.find_elements_by_class_name('File')
でページ内のリンクを取得し
for link in links:
link.click()
によってdownloadにPDFが正しく保存されることは確認しました。この保存先をページごとに異なるフォルダにしたいのです。

linkはこのような表記です。
link = 'http://xxxxx.co.jp/xxxxxx/DownloadFile?FileId=xxxxxxxx&Title=xxxxxx-xx.pdf&FileKind=xxxxxx'

発生している問題・エラーメッセージ

requests.getでダウンロードを試みましたがresponse は<Response [502]>でした。

response = requests.get(link)
print(response)

<Response [502]>

linkにURLパラメータが付いているためではないかと思い、requestの仕方を変える必要があるかと思うのですが、見つけられませんでした。よろしくお願いいたします。

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

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

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

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

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

otn

2024/09/12 08:47

そのPDFは、そのサイトにログインした状態でないとダウンロードできない物ですか? それとも、そのサイトにログインしてないブラウザのアドレスバーにそのURLをコピペしても、ダウンロードできる物ですか?
KENTATANAKA

2024/09/12 13:16

ログインした状態でしかダウンロードできません。
guest

回答2

0

ベストアンサー

手元の環境は Python 3.12.3/Selenium 4.31.1/Chromedriver 128.0.6613.137 です。そちらは Selenium 3.14.1 とのことなので、以下のサンプルコードは適宜書き換える必要がありますが、想定する動作にはならないかもしれません。

この保存先をページごとに異なるフォルダにしたい

保存先のフォルダを selenium.webdriver.chromium.webdriver.ChromiumDriver.execute_cdp_cmd — Selenium 4.24.0 documentation で指定します。(コードでは適当に /path/to/download_?? としています) ダウンロードの完了については JavaScript で監視していて(browser.execute_script(...))、60秒でタイムアウトします。(WebDriverWait(browser, 60, 2).until(complete_every_downloads)) ダウンロード処理に時間が掛かる場合は、タイムアウト値を増やす必要があります。

python

1from selenium import webdriver 2from selenium.webdriver.chrome.options import Options 3from selenium.webdriver.common.by import By 4from selenium.webdriver.support.ui import WebDriverWait 5from selenium.webdriver.support import expected_conditions as EC 6 7def complete_every_downloads(browser): 8 if not browser.current_url.startswith('chrome://downloads/'): 9 browser.get('chrome://downloads/') 10 return browser.execute_script(""" 11 items = document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList').items; 12 if (items.length == 0) return false; 13 return items.every(e => e.state === 2); 14 """) 15 16options = Options() 17options.add_experimental_option('prefs', {'plugins.always_open_pdf_externally': True}) 18browser = webdriver.Chrome(options=options) 19browser.implicitly_wait(10) 20 21urls = [ 22 'https://.../', 23 'https://.../', 24] 25 26for i, url in enumerate(urls): 27 browser.execute_cdp_cmd('Page.setDownloadBehavior', { 28 'behavior': 'allow', 29 'downloadPath': f'/path/to/download_{i:02d}' 30 }) 31 32 browser.get(url) 33 links = browser.find_elements(By.CLASS_NAME, 'File') 34 for link in links: 35 link.click() 36 37 WebDriverWait(browser, 60, 2).until(complete_every_downloads) 38 39browser.quit()

投稿2024/09/12 22:23

melian

総合スコア20710

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

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

KENTATANAKA

2024/09/13 00:24

Selenium 3.14.1 でも動作しました。とても助かりました。ありがとうございました。
guest

0

ログインした状態でしかダウンロードできません。

単に requests.get(link) するとログインしてないので、駄目ですね。「python requests ログイン」で検索すると、ログインする方法の情報があります。requestsでログインできるなら、Selenium要らないかもしれません。

Selenumでやりたい場合だと、ブラウザ起動前にoptionsの設定でダウンロードディレクトリーを指定出来ますが、起動後に変更する手段はちょっと分かりません。

この保存先をページごとに異なるフォルダにしたいのです。

だと、
案1:ページ毎に、ダウンロード先を変更したdriver = webdriver.Chrome(options=options)をし直す。ページ数が多いと実行時間が掛かるが。
案2:ダウンロード後に、ダウンロード先のディレクトリーから希望のディレクトリーに移動する。ファイル名が分からないと「前回から増えたファイル」を調べることになるが、全体ロジックの流れは変えなくて良い。
案3:JavaScriptでなんとかする手段があるかも知れない。

投稿2024/09/12 14:21

otn

総合スコア85976

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

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

bsdfan

2024/09/12 14:43

案2と同じことを、「watchdog でダウンロード先を監視し、対象のファイルができたら移動する」というスクリプトを別で動かしておくやり方で、実現したことがあります。一つのスクリプトですべてやる必要がないなら、お試しください。
KENTATANAKA

2024/09/13 00:26

otn 様 ご提案、ありがとうございます。 badfan 様 この方法でも動作しそうです。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問