Ruby とseleniumでアマゾンの価格チェックアプリを作ったメモ

仕様

特定の商品の価格が一定以下に下がったら、LINEに通知するアプリを作りました。

環境

Amazon.co.jpの商品データを取得する

selenium-webdriverのインストール

$ gem install selenium-webdriver

chrome driverのインストール

$ sudo apt-get install google-chrome-stable

# ダウンロード
$ wget https://chromedriver.storage.googleapis.com/94.0.4606.41/chromedriver_linux64.zip

# 解凍
$ unzip chromedriver_linux64.zip

# パスを通す
echo 'export DISPLAY="${DISPLAY:-:0}"' >> ~/.zshrc

fetchする

require 'selenium-webdriver'

# Selenium::WebDriver::Chrome::Optionsクラスをインスタンス化する
session = Selenium::WebDriver::Chrome::Options.new

# GUIでは無くCUIで動作させるためheadlessモードにする
session.add_argument('--headless')

# ブラウザとオプションを指定する
page = Selenium::WebDriver.for :chrome, options: session

# ページ遷移する
page.navigate.to VISIT_URL

https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/Chrome/Options.html

データを整形する

商品名、出版社、金額、リンクをLINEに通知します。

titleを取得する

p page.title 
# プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発 | Boris Cherny, 今村 謙士, 原 隆文 |本 | 通販 | Amazon

https://www.seleniumqref.com/api/ruby/window_get/Ruby_title.html

class属性から要素を取得する

page.find_element(:class, 'a-text-price').text

https://www.seleniumqref.com/api/ruby/element_get/Ruby_find_element_class_name.html

find_elementとfind_elementsの違い

find_elementが最初に一致する要素を返すのに対しfind_elementsは一致するすべての要素を配列で返します。

string型の金額データをint型にする

string型のままでは金額を比べられないので、int型にします

price.delete('^0-9').to_i

delete('^0-9')で数値以外の¥,を取り除いて、to_iでint型にしています。

LINEに通知する

https://blog.hatena.ne.jp/kei_kmj/kei-kmj.hatenablog.com/edit?entry=4207112889921799540

ソースコード

https://github.com/kei-kmj/price_notifier

Nokogiriというgemを使う方法もある

require 'open-uri'
require 'nokogiri'
require 'net/http'

html = URI.parse(FETCH_URL).open
page = Nokogiri::HTML.parse(html)

でも同じことができます。

https://nokogiri.org/