kakashi-blog・カカシブログ・

Python備忘録を書きドローンやバイクなど好きな事で生きて行こうとしているブログ

Python

Amazonのスクレイピングは禁止?Seleniumで試した結果と正しい方法

投稿日:2020年2月15日 更新日:

PythonでAmazonの商品名・価格・ASINコードを集めようとして、普通のスクレイピングでは取れず、何時間も悩んだことがあります。

結論から言うと、Amazonは利用規約でロボットなどによる自動のデータ収集を禁止しています。商品データを使いたいなら、Amazonアソシエイト向けの公式API(今はCreators API)を使うのが正しい方法です。

この記事は、私がBeautifulSoupとSeleniumで試したときの勉強の記録です。当時のコードは今のSeleniumでは動かないので、その理由もあわせて書いておきます。

要点

  • BeautifulSoupだけでは、Amazonの商品データは安定して取れませんでした
  • Seleniumでブラウザを動かすと取れましたが、規約で禁止されている方法です
  • 当時のコードは、今のSelenium(4.3以降)ではエラーになります
  • 正規の方法は、Amazonアソシエイトに登録してCreators APIを使うことです

BeautifulSoupではAmazonのデータが取れなかった

最初はBeautifulSoupで、Amazonの商品名と価格を集めようとしました。ところが、取れるときと取れないときがあり、原因がわかりませんでした。バグだと思って、何時間も無駄にしました。

取得したHTMLを翻訳してみると、自動アクセスを断る文言が書かれていました。Amazonは自動でのデータ収集を規約で禁止していて、こうしたアクセスを弾いていたのです。

Amazonのスクレイピングは規約で禁止されている

Amazonの利用規約では、サービスの利用は個人的な利用に限られ、データマイニングやロボットなどを使った情報の収集は認められていません。技術的に取れるかどうかとは別に、規約違反になる という点は知っておいてください。アクセスが弾かれたり、アカウントに影響が出たりするおそれもあります。

正しい方法:Creators APIを使う

Amazonの商品データを正規に使いたい場合は、Amazonアソシエイト(アフィリエイト)に登録して、公式のAPIを使います。

以前はPA-API(Product Advertising API)5.0という仕組みでしたが、2026年に提供が終わり、今は後継の Creators API に移っています。古いPA-APIのコードは、そのままでは使えません。利用するには、アソシエイトでの売上実績などの条件があります。条件は変わることがあるので、Amazonアソシエイトの公式ページで確認してください。

私も当時アソシエイトに登録しましたが、手軽に試したくて、次のSeleniumを使いました。

Seleniumで試したときのコード(当時の記録)

Seleniumは、実際のブラウザ(Chrome)を自動で動かすライブラリです。「人がブラウザを操作している」形でページを開き、そのHTMLから商品名などを抜き出す、という作戦でした。

当時(2020年)はこのコードで、検索結果の一番上の商品について、商品名・価格・ASINコードが取れました。ただし、価格やASINが入っている場所は商品によってバラバラで、取れない商品もありました。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup as bs
import re
import time

inp=input()

amazon='https://www.amazon.co.jp/'

class get_sous:

    def __init__(self,url,browser):
        self.url=url
        self.browser=browser

    def getbrowser(self):
        sous=self.browser.page_source
        self.browser.close()
        return sous

    def openurl(self):
        self.browser.get(self.url)
        time.sleep(5)

    def search_(self,name):
        search_name=self.browser.find_element_by_id('twotabsearchtextbox')
        search_name.clear()
        search_name.send_keys(name)
        btn=self.browser.find_element_by_class_name("nav-input")
        btn.click()
        time.sleep(5)

webd=webdriver.Chrome()
open1=get_sous(amazon,webd)
open1.openurl()
sous1=open1.search_(inp)
sous1=open1.getbrowser()

soup=bs(sous1, 'html.parser')
link1=soup.find_all('a',class_="a-link-normal a-text-normal")
link1=(link1[0].get('href'))

open2=get_sous(amazon+link1,webdriver.Chrome())
open2.openurl()
sous2=open2.getbrowser()
soup=bs(sous2, 'html.parser')
name=soup.find("span",id='productTitle')
name=(name.get_text().strip())
print(name)

price=soup.find("span",id='priceblock_ourprice')
price=re.sub(r'\,','',price.get_text())
print(price)

asin=soup.find("input",class_="askAsin")
print(asin.get('value'))

※このコードは、素人が個人的な勉強のために書いたものです。使用による責任は負いかねます。

コードの流れ

  • input() で検索したい言葉を入力します
  • get_sous クラスで、ブラウザを開く・検索する・HTMLを取ってブラウザを閉じる、をまとめています
  • time.sleep(5) は、ページが表示されるまで5秒待つためのものです
  • 検索結果の一番上のリンクを開き、BeautifulSoupで商品名・価格・ASINを抜き出しています
  • 商品名の前後にある余分なスペースは strip() で消しています

このコードが今は動かない理由

Selenium 4.3以降でfind_element_by_idが使えない

Seleniumは2022年のバージョン4.3で、find_element_by_id や find_element_by_class_name といった書き方が削除されました。今のSeleniumでこのコードを動かすと、AttributeError: 'WebDriver' object has no attribute 'find_element_by_id' というエラーになります。

今の書き方は、By を使って次のようにします。

from selenium.webdriver.common.by import By

search_name = browser.find_element(By.ID, 'twotabsearchtextbox')
btn = browser.find_element(By.CLASS_NAME, 'nav-input')

古い記事のコードでこのエラーが出たら、この書き方に直せば動くことがほとんどです。Seleniumの基本は、Python備忘録 selenium 自動ログイン編やブラウザスクロール編にまとめています。

Amazonのページの作りが変わっている

priceblock_ourprice のような、価格が入っている場所の名前(id)は、当時の記事の時点でも商品によって違っていました。ページの作りはその後も変わっているので、書き方を直しても同じようには取れないと思います。

まとめ

  • BeautifulSoupだけではAmazonの商品データは取れず、Seleniumなら当時は取れました
  • ただし、Amazonは規約で自動のデータ収集を禁止しています
  • 当時のコードは、Selenium 4.3以降の書き方の変更とページの変更で、今は動きません
  • Amazonの商品データを使うなら、Amazonアソシエイトに登録してCreators APIを使うのが正しい方法です

-Python
-, ,

執筆者:


comment

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

関連記事

Python Tkinter入門|ウインドウ・ラベル・入力欄・ボタンの基本

PythonのTkinter(ティーケーインター)を使うと、ボタンや入力欄のある画面(GUI)を作れます。この記事では、ウインドウを開いて、ラベル、テキストの入力欄、ボタンを付けるまでの基本をまとめま …

PythonでExcelを操作する方法|openpyxlの基本

Pythonの勉強で覚えた、Excelを操作する方法をまとめました。初心者向けの備忘録です。 結論から言うと、openpyxlで load_workbook() で開き、wb[‘シート名’] でシート …

Tkinterのメッセージボックスで出る謎ウインドウの消し方

Pythonのtkinterでメッセージボックスだけを出したいのに、何もない小さなウインドウ(謎ウインドウ)が一緒に出てきて、処理が止まってしまうことがあります。 結論から言うと、謎ウインドウの正体は …

Seleniumで自動ログインする方法|Python備忘録

前回はSeleniumでブラウザをスクロールさせました。今回は、ログイン画面にIDとパスワードを自動で入力して、ログインするところまでやってみます。 結論から言うと、開発者ツール(F12)で入力欄とボ …

計算カードをPythonで自作|子供のズル対策アプリ(Tkinter)

うちの小学1年生の子の宿題に「計算カード」があります。学校からは「時間を計ってやりなさい」と言われているようです。 ところが、もちろん計算なんかせず、どれだけ早くめくれるかが目的になってしまっていまし …