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を使うのが正しい方法です