ラベル selenium の投稿を表示しています。 すべての投稿を表示
ラベル selenium の投稿を表示しています。 すべての投稿を表示

2024年2月2日金曜日

Python で selenium を動かすサンプルコード

Python で selenium を動かすサンプルコード

概要

現状の環境で動作するのか確認したかったのでメモ
Chrome は起動中のウィンドウを使います

環境

  • macOS 11.7.10
  • chrome 120.0.6099.216
  • chromedriver 120.0.6099.109

chromedriver

  • brew install chromedriver

インストール

  • pipenv install selenium

chrome 起動

  • "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222

サンプルコード

特定のサイトの商品IDの一覧を先に取得しその後 ID を元に商品のリンク先に飛びリンク先のテキスト情報を表示する流れです

(どうしても安定しないところは sleep やリトライを入れるしかないのだろうか)

import time

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

# 既存chromeを起動
chromeoptions = Options()
chromeoptions.debugger_address = "127.0.0.1:9222"
driver = webdriver.Chrome(options=chromeoptions)


def init():
    driver.get("https://your.target.site")
    driver.find_element(By.XPATH, '//*[@id="js-list"]/div/a').click()


def init_ids() -> list:
    init()
    ids = []
    products = driver.find_elements(By.XPATH, '//*[@id="js-list"]/ul/li/div')
    for p in products:
        id = p.get_attribute("id")
        ids.append(id)
    return ids


def show_product_info(id: str):
    init()
    driver.find_element(By.XPATH, f'//div[@id="{id}"]').click()
    time.sleep(2)
    driver.find_element(By.XPATH, '//*[@id="js-product-tabs"]/div[1]/cite/a').click()
    try:
        driver.find_element(By.XPATH, '//*[@id="a_performer"]').click()
    except NoSuchElementException:
        pass
    print(driver.find_element(By.XPATH, '//*[@id="title"]').text)
    print(driver.find_element(By.XPATH, '//*[@id="performer"]').text)
    # 戻る
    driver.back()


def close():
    driver.close()


if __name__ == "__main__":
    ids = init_ids()
    for id in ids:
        show_product_info(id)
    close()

最後に

selenium は相変わらずDOMの表示タイミングなどがシビアなので安定して動かすのが大変な印象です
仕方なくブラウザからしか情報が取得できない場合を除きできる限り selenium は使わないほうがいいと思います

個人のツールとしてならありかなと思います

参考サイト

2021年5月26日水曜日

Selenium でダイアログなしでファイルをダウンロードする方法

Selenium でダイアログなしでファイルをダウンロードする方法

概要

重要なのは Firefox を使わずに Chrome を使う点です

参考記事

環境

  • macOS 11.3.1
  • Ruby 3.0.0
    • selenium 4.0.0.beta3
  • Chrome

サンプルコード

一部抜粋です ポイントはプリファレンスを使って Chrome にオプションを渡すところです

download_pref = {
  'prompt_for_download' => false,
  'default_directory' => '/tmp',
  'directory_upgrade' => true
}
options = Selenium::WebDriver::Chrome::Options.new
options.add_preference(:download, download_pref)

@driver = Selenium::WebDriver.for :chrome, options: options

最後に

自分が試した限りこれならダイアログなしでファイルのダウンロードができました 念を押しますが Firefox はハマるので諦めて ChromeDriver を使いましょう

なお Selenium は localhost でも動作しましたし remote (docker) でも動作しました

2021年5月24日月曜日

Ruby + selenium + chrome のシンプルなサンプルコード

Ruby + selenium + chrom のシンプルなサンプルコード

概要

動作に必要な最低限の設定のみ紹介します

環境

  • macOS 11.3.1
  • Ruby 3.0.0
    • selenium-webdriver 4

gem インストール

  • bundle init
  • vim Gemfile
gem "selenium-webdriver", "4.0.0.beta3"

chromedriver のインストール

  • brew install chromedriver

サンプル

  • vim test.rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome
driver.get('https://www.yahoo.co.jp/')

実行

  • bundle exec ruby test.rb

2021年5月23日日曜日

Selenium + Firefox でファイルをダウンロードのダウンロードはできなさそう

Selenium + Firefox でファイルをダウンロードのダウンロードはできなさそう

概要

ブラウザでダウンロードする際にダウンロードするファイルをどうするかという確認のダイアログが表示されます これを Selenium + Firefox で消そうと思ったのですがどうやってもできなかったので紹介します

環境

  • macOS 11.3.1
  • Ruby 3.0.0
    • selenium-webdriver 4.0.0.beta3
  • Firefox 88

Ruby3 を使う場合は selenium-webdriver 4 が必要になります

インストール

  • bundle init
  • vim Gemfile
gem "selenium-webdriver", "4.0.0.beta3"
  • bundle install

プロファイルを指定して Firefox を起動すれば特定のファイルのダウンロードルールを使えるのでは

既存の Firefox でダウンロードしたいファイルを一度ダウンロードします その際に指定のファイルは次回以降同じ設定でダウンロードすることができるという機能があります

この機能を使ってプロファイルを作成しそのプロファイルを selenium で指定することでプロファイル付きの Firefox を起動することができるようになります

options = Selenium::WebDriver::Firefox::Options.new(args: ['-profile', '/path/to/profile'])

@driver = Selenium::WebDriver.for :remote, url: "http://#{host}:4444/wd/hub", options: options

一応公式でも手順が公開されてはいるのですがバグの回避策として紹介されている感じです 確かにプロファイル付きで Firefox は起動できるのですがそのあと selenium に接続することができません

どうやらプロファイル付きだと geckodriver が見つからなくなってしまうようで結局動作しません

調べてみると marionette を有効にすれば動作するという記事もみたのですが自分はダメでした

プロファイルを設定すればいけるという情報がかなりあったがダメだった

例えば以下のような感じでプロファイルを設定し Firefox ドライバを作成します これで localhost でも docker 上でも試したのですが結局ダイアログが出なくなることはありませんでした

profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.folderList'] = 2
profile['browser.download.useDownloadDir'] = true
profile['browser.download.dir'] = '/tmp'
profile['browser.download.lastDir'] = '/tmp'
profile['browser.download.downloadDir'] = '/tmp'
profile['browser.download.defaultFolder'] = '/tmp'
profile['browser.download.manager.showWhenStarting'] = false
profile['browser.download.manager.useWindow'] = false
profile['browser.download.manager.focusWhenStarting'] = false
profile['browser.download.manager.showAlertOnComplete'] = false
profile['browser.download.manager.closeWhenDone'] = true
profile['browser.download.viewableInternally.enabledTypes'] = ""
profile['browser.helperApps.alwaysAsk.force'] = false
profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/plane,text/csv,application/x-ofx,text/comma-separated-values,application/octet-stream,application/vnd.ms-excel,application/x-gzip,text/txt,application/gzip,application/zip,text/html,txt,text'

options = Selenium::WebDriver::Firefox::Options.new(:profile => profile)

@driver = Selenium::WebDriver.for :remote, url: "http://#{host}:4444/wd/hub", options: options

原因を考える

もしかしたら自分の設定が足りていないだけかもしれないので少し原因を考えてみました

content-type が足りていない

browser.helperApps.neverAsk.saveToDisk にダイアログを表示しない content-tyep を記載するのですがそこにダウンロードするファイルの content-type がない可能性があります

しかし自分の場合はちゃんとブラウザなどで content-type を調べた上で記載したので漏れはないかなと思っています

handlers.json が優先されているのか

上記のプロファイルの記載よりもプロファイルフォルダ配下にある handlers.json の設定が優先されているのかもしれません むしろここに記載がないと意味がない可能性すらありそうです

なので今回プロファイル付きの Firefox を起動するようにしたのですが結局 selenium 経由では動作できませんでした 別の方法で handlers.json を上書きできればもしかしたら動作させることができるかもしれません

最後に

いろいろ試してみたのですが結局 Selenium + Firefox でダウンロードのダイアログを消すことはできませんでした

回避策としては chrome や edge ドライバを使うことかなと思います

参考サイト