PythonでAmazonレビューを取得する方法(ログイン壁の突破法)

最終更新日 April 16, 2026

私のAmazonレビュー用スクレイパーは、6週間ものあいだ完璧に動いていました。ところがある朝、返ってきたのは 200 OK と、何も入っていないページだけ。エラーでもCAPTCHAでもなく、以前は何百件ものレビューが並んでいた場所が、空っぽのHTMLになっていたのです。

もしこの状況に見覚えがあるなら、あなただけではありません。2025年後半、Amazonはレビュー全文ページにログイン必須の壁を導入し、その影響で大量のPythonスクレイピングスクリプトが一夜にして動かなくなりました。私はここ数か月、でAIスクレイパーの開発に取り組む一方、自分自身のPythonレビュー取得パイプラインも維持してきました。その両面からこの問題に向き合ってきたので、スクリプトが止まったときに本当はこういう記事が欲しかった、という内容をまとめようと思ったのです。この記事では、実際に動く手順として、Cookieベース認証、AmazonのCSS難読化を回避できる安定したセレクター、10ページ制限への対処法、ボット対策、さらにレビュー本文を実際のビジネスインサイトに変える感情分析まで解説します。途中で「ここまでコードを保守するのはちょっと大変だな」と感じたら、同じ処理をPython不要で約2分でこなすの方法も紹介します。

Amazonレビューのスクレイピングとは?なぜ重要なのか?

Amazonレビューのスクレイピングとは、商品ページから星評価、レビュー本文、投稿者名、投稿日、Verified Purchaseバッジなどの顧客レビュー情報をプログラムで抽出することです。Amazonはため、このデータをプログラムで取得するにはWebスクレイピングしかありません。

数字を見ても、その重要性は明らかです。うえ、からです。商品ページにレビューを5件だけ表示するだけでもことがあります。レビュー感情を体系的に分析している企業では、という報告もあります。これは抽象的なデータサイエンスの話ではなく、競合分析、製品改善のヒント、マーケティングで使える生の言葉が、Amazonのサーバー上にそのまま眠っているということです。

なぜPythonでAmazonレビューを取得するのか

この用途では、今でもPythonが最有力です。であり、requests、BeautifulSoup、pandas、Scrapy などのエコシステムがあるため、専業開発者でなくてもWebスクレイピングに取り組みやすいからです。

チームごとに、このデータの使い方はさまざまです。

チーム用途抽出する情報
製品 / R&D繰り返し出る不満を特定し、改善の優先順位を決める星1〜2レビュー本文、頻出キーワード
営業競合商品の評価傾向を監視する評価、レビュー件数の推移
マーケティング広告コピーに使える顧客の言葉を集めるポジティブな表現、機能への言及
EC運用自社商品の評価推移を追跡する星分布、Verified Purchase比率
市場調査カテゴリー上位商品の特徴を比較する複数ASINのレビューセット

あるキッチン用品ブランドはことを発見し、製品を改良した結果、60日以内に再びカテゴリ1位のベストセラーを獲得しました。あるフィットネストラッカー企業は、ラテックスアレルギーの問題を特定して低刺激版を投入し、返品率を40%削減しました。こうした成果があるからこそ、エンジニアリングの手間をかける価値があるのです。

ログイン壁:Amazonレビュー用スクレイパーが動かなくなった理由

2024年11月14日、。この変更はでも確認されています。シークレットウィンドウで /product-reviews/{ASIN}/ にアクセスすると、レビューではなくサインインページへリダイレクトされます。

python-web-scraping-diagram.webp

症状は分かりにくいです。スクリプトは 200 OK を受け取るのに、HTML本文にはレビューの代わりにログインフォーム(name="email"id="ap_password")が入っている。エラーコードは出ません。CAPTCHAも出ません。ただ、何も役に立つものが返ってこないだけです。

Amazonがこれを行った理由は、ボット対策と地域ごとの規制対応です。実際の適用にはばらつきがあり、特に1ページ目では壁がかかる前に数件のレビューだけ見えてしまうこともありますが、本格的にスクレイピングするなら、常に壁がある前提で考えるべきです。

Amazonの各国ドメイン(.de.co.uk.co.jp など)は、それぞれ個別にこの制限を適用しています。あるフォーラムユーザーの言葉を借りれば、「国ごとにログインが必要」です。.com のCookieは .co.uk では使えません。

目玉レビューと全文レビュー:ログインなしで今も取れるもの

Amazonの商品ページ(/dp/{ASIN}/)では、認証なしでもおよそが表示されます。これはAmazonのアルゴリズムが選んだレビューで、ざっと雰囲気をつかむには便利ですが、並び替えや絞り込み、ページ送りはできません。

全文レビューのページ(/product-reviews/{ASIN}/)は、新着順の並び替え、星評価でのフィルタリング、何百件にも及ぶページネーションを使うにはログインが必要です。

もし数件だけをざっくり確認したいなら、商品ページを取得すれば十分です。何百件、何千件と取りたいなら、認証対応が必須になります。

事前準備:Python環境と必要なライブラリ

コードを書く前に、まずは以下を用意します。

  • 難易度: 中級(Pythonに慣れていて、HTMLの基本を理解している方向け)
  • 所要時間: სრულიパイプラインで約45分、基本的な取得だけなら約10分
  • 必要なもの: Python 3.8以上、Chromeブラウザ、有効なAmazonアカウント

主要ライブラリをインストールします。

1pip install requests beautifulsoup4 lxml pandas textblob

必要に応じて、より高度な感情分析用にこちらも使えます。

1pip install transformers torch

ASINとは? Amazonの商品識別子で、10文字のコードです。商品URLの中に必ず入っています。たとえば amazon.com/dp/B0BCNKKZ91 なら、ASINは B0BCNKKZ91 です。これをレビューURLに差し込みます。

ステップ1:Cookieベース認証でログイン壁を越える

最も安定した方法は、ブラウザでAmazonにログインし、セッションCookieをコピーして、Pythonの requests.Session() に入れるやり方です。これなら、Seleniumでログインを自動化したときに発生しがちなCAPTCHAやSMSの2要素認証を回避できます。

必要なCookieは次の7つです。

Cookie名役割
session-id変動するセッション識別子
session-id-timeセッションのタイムスタンプ
session-token変動するセッショントークン
ubid-mainユーザーの閲覧識別子
at-main主要な認証トークン
sess-at-mainセッション単位の認証情報
x-mainメールアドレスに紐づく識別子
  1. Chromeで amazon.com にログインする
  2. DevTools を開く(F12 または右クリック → 検証)
  3. ApplicationStorageCookieshttps://www.amazon.com に進む
  4. 表にある各Cookie名を見つけて値をコピーする
  5. Python用にセミコロン区切りの文字列として整える

セッションは次のように設定します。

1import requests
2session = requests.Session()
3# ここにCookieの値を貼り付ける
4cookies = {
5    "session-id": "YOUR_SESSION_ID",
6    "session-id-time": "YOUR_SESSION_ID_TIME",
7    "session-token": "YOUR_SESSION_TOKEN",
8    "ubid-main": "YOUR_UBID_MAIN",
9    "at-main": "YOUR_AT_MAIN",
10    "sess-at-main": "YOUR_SESS_AT_MAIN",
11    "x-main": "YOUR_X_MAIN",
12}
13headers = {
14    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
15    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
16    "Accept-Language": "en-US,en;q=0.5",
17}
18session.cookies.update(cookies)
19session.headers.update(headers)

重要: 以降のすべてのリクエストで同じ session オブジェクトを使い回してください。こうすることでCookieの整合性が保たれ、実際のブラウザ操作に近い挙動になります。Cookieの有効期限は、スクレイピング負荷が高くなければ通常数日〜数週間は持ちますが、再びログイン画面に飛ばされるようなら、ブラウザからCookieを取り直してください。

.com 以外のマーケットプレイスではCookie名が少し変わります。たとえば amazon.de では at-main の代わりに at-acbde、amazon.co.uk では at-acbuk を使います。マーケットプレイスごとに独立したセッションが必要です。

ステップ2:リクエストを作成し、BeautifulSoupでレビューHTMLを解析する

AmazonレビューのURLは次の形式です。

1https://www.amazon.com/product-reviews/{ASIN}/ref=cm_cr_arp_d_viewopt_srt?sortBy=recent&pageNumber=1

基本となる関数は次の通りです。

1from bs4 import BeautifulSoup
2import time, random
3def get_soup(session, url):
4    time.sleep(random.uniform(2, 5))  # 丁寧な間隔を入れる
5    response = session.get(url, timeout=15)
6    # ログイン壁の検知
7    if "ap_email" in response.text or "Amazon Sign-In" in response.text:
8        raise Exception("ログイン壁を検知しました — Cookieを更新してください")
9    if response.status_code != 200:
10        raise Exception(f"HTTP {response.status_code}")
11    return BeautifulSoup(response.text, "lxml")

ひとつ効く小技があります。レビューURLに行く前に、先に商品ページへアクセスしてください。そうすると、セッション内で自然な閲覧パターンが作れます。

1# 先に商品ページへアクセスする(通常の閲覧に近づける)
2product_url = f"https://www.amazon.com/dp/{asin}"
3session.get(product_url, timeout=15)
4time.sleep(random.uniform(1, 3))
5# その後でレビュー一覧へアクセスする
6reviews_url = f"https://www.amazon.com/product-reviews/{asin}/ref=cm_cr_arp_d_viewopt_srt?sortBy=recent&pageNumber=1"
7soup = get_soup(session, reviews_url)

ステップ3:安定したセレクターでレビュー情報を抽出する(CSSクラス頼みはやめる)

ここで、多くの2022〜2023年の解説記事は破綻します。AmazonはCSSクラス名を難読化しており、定期的に変わります。あるフォーラムでは、困った開発者が「spanタグのクラス名に共通パターンがまったく見つからなかった」と嘆いていました。

解決策は、レビュー要素に付いている data-hook 属性を使うことです。これは驚くほど安定しています。Amazonのフロントエンド自身が依存している意味ベースの識別子なので、ランダム化されにくいのです。

レビュー項目安定したセレクター(data-hook壊れやすいセレクター(class)
レビュー本文[data-hook="review-body"].review-text-content(変わりやすい)
星評価[data-hook="review-star-rating"].a-icon-alt(曖昧)
レビュータイトル[data-hook="review-title"].review-title(場合による)
投稿者名span.a-profile-name比較的安定
投稿日[data-hook="review-date"].review-date(地域差あり)
Verified Purchase[data-hook="avp-badge"]span.a-size-mini

data-hook を使った抽出コードはこちらです。

1import re
2def extract_reviews(soup):
3    reviews = []
4    review_divs = soup.select('[data-hook="review"]')
5    for div in review_divs:
6        # 星評価
7        rating_el = div.select_one('[data-hook="review-star-rating"]')
8        rating = None
9        if rating_el:
10            rating_text = rating_el.get_text(strip=True)
11            match = re.search(r'(\d\.?\d?)', rating_text)
12            if match:
13                rating = float(match.group(1))
14        # タイトル
15        title_el = div.select_one('[data-hook="review-title"]')
16        title = title_el.get_text(strip=True) if title_el else ""
17        # 本文
18        body_el = div.select_one('[data-hook="review-body"]')
19        body = body_el.get_text(strip=True) if body_el else ""
20        # 投稿者名
21        author_el = div.select_one('span.a-profile-name')
22        author = author_el.get_text(strip=True) if author_el else ""
23        # 日付と国
24        date_el = div.select_one('[data-hook="review-date"]')
25        date_text = date_el.get_text(strip=True) if date_el else ""
26        # 例: "Reviewed in the United States on January 15, 2025"
27        country_match = re.search(r'Reviewed in (.+?) on', date_text)
28        date_match = re.search(r'on (.+)$', date_text)
29        country = country_match.group(1) if country_match else ""
30        date = date_match.group(1) if date_match else ""
31        # Verified Purchase
32        verified_el = div.select_one('[data-hook="avp-badge"]')
33        verified = bool(verified_el)
34        reviews.append({
35            "author": author,
36            "rating": rating,
37            "title": title,
38            "content": body,
39            "date": date,
40            "country": country,
41            "verified": verified,
42        })
43    return reviews

私はこのセレクターセットを複数のASINで数か月動かしていますが、data-hook 属性は一度も変わっていません。一方でCSSクラスの方は、その期間に少なくとも2回は変わりました。

ステップ4:ページネーションとAmazonの10ページ制限に対処する

Amazonでは pageNumber パラメータが、10ページ × 各10件、つまりフィルターの組み合わせごとに最大約100件までという厳しい上限になっています。10ページ目以降は「次へ」ボタン自体が消えます。

基本のページネーションループは次の通りです。

1all_reviews = []
2for page in range(1, 11):
3    url = f"https://www.amazon.com/product-reviews/{asin}/ref=cm_cr_arp_d_viewopt_srt?sortBy=recent&pageNumber={page}"
4    soup = get_soup(session, url)
5    page_reviews = extract_reviews(soup)
6    if not page_reviews:
7        break  # このページにはもうレビューがない
8    all_reviews.extend(page_reviews)
9    print(f"Page {page}: {len(page_reviews)} reviews")

10ページ以上のAmazonレビューを取る方法

回避策はフィルターの分割です。filterByStarsortBy の組み合わせごとに、独立した10ページ枠が与えられます。

星フィルターの値: one_startwo_starthree_starfour_starfive_star
並び替えの値: recenthelpful(デフォルト)

5種類の星フィルター × 2種類の並び替えを組み合わせれば、商品ごとに最大100ページ、1,000件のレビューにアクセスできます。星の分布が偏っている商品なら、実際にはほぼ全件に近いレビューを取れることも少なくありません。

1star_filters = ["one_star", "two_star", "three_star", "four_star", "five_star"]
2sort_orders = ["recent", "helpful"]
3all_reviews = []
4seen_titles = set()  # 簡易的な重複排除
5for star in star_filters:
6    for sort in sort_orders:
7        for page in range(1, 11):
8            url = (
9                f"https://www.amazon.com/product-reviews/{asin}"
10                f"?filterByStar={star}&sortBy={sort}&pageNumber={page}"
11            )
12            soup = get_soup(session, url)
13            page_reviews = extract_reviews(soup)
14            if not page_reviews:
15                break
16            for review in page_reviews:
17                # タイトル + 投稿者名で重複排除
18                key = (review["title"], review["author"])
19                if key not in seen_titles:
20                    seen_titles.add(key)
21                    all_reviews.append(review)
22            print(f"[{star}/{sort}] Page {page}: {len(page_reviews)} reviews")
23print(f"Total unique reviews: {len(all_reviews)}")

バケット同士には重なりが出るので、重複排除は必須です。私はレビュータイトル + 投稿者名の組み合わせを簡易キーとして使っています。完璧ではありませんが、ほとんどの重複はこれで弾けます。

ステップ5:ボット対策をかわす(ローテーション、間隔、リトライ)

Amazonは AWS WAF Bot Control を使っており、かなり攻撃的になっています。User-Agentを回すだけ、遅延を入れるだけ、のような単一対策ではもはや十分ではありません。

手法実装方法
User-Agentのローテーション10種類以上の実ブラウザ文字列からランダム選択
指数バックオフ503時に 2秒 → 4秒 → 8秒 と待機
リクエスト間隔の調整ページ間で random.uniform(2, 5) 秒待つ
プロキシのローテーション住宅系プロキシを順番に切り替える
セッションフィンガープリントセッションごとにCookieとヘッダーを固定する
TLSのなりすまし本番では標準の requests ではなく curl_cffi を使う

本番運用向けのリトライラッパーは次のようになります。

1import time, random
2USER_AGENTS = [
3    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
4    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
5    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:149.0) Gecko/20100101 Firefox/149.0",
6    "Mozilla/5.0 (Macintosh; Intel Mac OS X 15_7_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15",
7    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
8]
9def scrape_with_retries(session, url, max_retries=3):
10    for attempt in range(max_retries):
11        try:
12            session.headers["User-Agent"] = random.choice(USER_AGENTS)
13            time.sleep(random.uniform(2, 5))
14            response = session.get(url, timeout=15)
15            # ブロック検知
16            if "validateCaptcha" in response.url or "Robot Check" in response.text:
17                wait = (2 ** attempt) * 5
18                print(f"CAPTCHAを検知しました。{wait}秒待機します...")
19                time.sleep(wait)
20                continue
21            if response.status_code in (429, 503):
22                wait = (2 ** attempt) * 2
23                print(f"レート制限を受けました ({response.status_code})。{wait}秒待機します...")
24                time.sleep(wait)
25                continue
26            if "ap_email" in response.text:
27                raise Exception("ログイン壁 — Cookieの期限が切れています")
28            return BeautifulSoup(response.text, "lxml")
29        except Exception as e:
30            if attempt == max_retries - 1:
31                raise
32            print(f"Attempt {attempt + 1} failed: {e}")
33    return None

プロキシについて一言。Amazonは 。数百ページ以上をスクレイピングするなら、住宅系プロキシはほぼ必須で、規模にもよりますが月50〜200ドル以上は見ておくべきです。小規模(1日100リクエスト未満)なら、自宅回線から慎重に間隔を空けて送るだけでもうまくいくことがあります。

AmazonはTLSフィンガープリントも確認します。Python標準の requests ライブラリは、WAFに事前ブロックされやすい 。本番用途では、実ブラウザのTLSスタックを模倣できる curl_cffi の使用を検討してください。チュートリアル規模(数百ページ程度)なら、適切なヘッダーを付けた requests でもたいてい十分です。

ステップ6:取得したAmazonレビューをCSVまたはExcelに出力する

レビューを取得したら、pandas を使って使いやすい形式にまとめるのは簡単です。

1import pandas as pd
2df = pd.DataFrame(all_reviews)
3df.to_csv("amazon_reviews.csv", index=False)
4print(f"Exported {len(df)} reviews to amazon_reviews.csv")

出力例:

authorratingtitlecontentdatecountryverified
Sarah M.5.0今年いちばんの買い物バッテリーが1日持つし、画面もとてもきれい...January 15, 2025the United StatesTrue
Mike T.2.02週間でがっかり充電ポートが動かなくなった...February 3, 2025the United StatesTrue
Priya K.4.0値段以上の価値必要なことはすべてできるけれど、重いアプリでは少しもたつく...March 10, 2025the United StatesFalse

Excelに出すなら: df.to_excel("amazon_reviews.xlsx", index=False)openpyxl が必要です)。

Google Sheets に出す場合は gspread が使えますが、必要です。プロジェクト作成、2つのAPIの有効化、サービスアカウント資格情報の生成、シート共有などが発生します。もし「スクレイピング本体より設定の方が大変では?」と感じるなら、その感覚は正しいです。(こういうときこそ、 のようにワンクリックでGoogle Sheetsへ出力できるツールが魅力的に見えてきます。)

おまけ:たった5行でスクレイピング結果に感情分析を加える

多くのスクレイピング解説はCSV出力で終わります。でも、感情スコアを付けることで、単なるデータが意思決定材料に変わります。

最も手軽なベースラインは TextBlob です。

1from textblob import TextBlob
2df["sentiment"] = df["content"].apply(lambda x: TextBlob(str(x)).sentiment.polarity)

これで各レビューに -1.0(非常にネガティブ)から +1.0(非常にポジティブ)までのスコアが付きます。出力例:

content(抜粋)ratingsentiment
"Battery lasts all day, screen is gorgeous..."5.00.65
"The charging port stopped working after..."2.0-0.40
"Does everything I need, minor lag on..."4.00.25
"Absolute garbage. Returned immediately."1.0-0.75
"It's okay. Nothing special but works."3.00.10

面白いのは、星評価と文章のニュアンスがズレている行です。たとえば3星なのに文章はかなり好意的、あるいは5星なのに言い回しがネガティブ、といったケースです。こうしたズレは、星だけでは見えない細かな本音を示してくれます。

ai-review-analysis.webp

本番レベルの精度を求めるなら、Hugging Face Transformers をおすすめします。ですし、とされています。nlptown/bert-base-multilingual-uncased-sentiment モデルなら、1〜5星を直接予測することもできます。

1from transformers import pipeline
2clf = pipeline("sentiment-analysis",
3               model="nlptown/bert-base-multilingual-uncased-sentiment")
4df["predicted_stars"] = df["content"].apply(
5    lambda x: int(clf(str(x)[:512])[0]["label"][0])
6)

Amazonレビューはを示します。5星に大きな山、1星に小さめの山、その間は谷になりやすいのです。つまり、平均星評価は実際の品質を測る指標としてはあまり当てになりません。1星群を分けて共通点を探すと、たいていそこに修正可能な欠陥が潜んでいます。

本音の比較:自作Python vs 有料スクレイピングAPI vs Thunderbit

私はAmazon用のPythonスクレイパーを何本も保守してきましたが、正直に言うと、壊れます。セレクターは変わり、Cookieは切れ、Amazonは新しいボット検知を導入し、気づけば土曜の朝がデータ分析ではなくスクレイパーのデバッグで終わります。フォーラムでも同じ不満が多く、「先月は動いていた」スクリプトが、今は頻繁な修正なしでは使えないという声が目立ちます。

3つの主要アプローチを比べるとこうなります。

比較項目自作Python(BS4/Selenium)有料スクレイピングAPIThunderbit(ノーコード)
初期設定時間1〜3時間30分(APIキーのみ)2分
コスト無料(+プロキシ費用)月50〜200ドル以上無料枠あり
ログイン壁対応Cookieを手動管理たいてい対応済み自動対応
保守工数高い(セレクターが壊れる)低い(提供側が保守)ほぼゼロ(AIが適応)
ページネーション自作コードが必要標準機能標準機能
多国対応ドメインごとに別セッションたいてい対応ブラウザベースなのでロケールに準拠
感情分析自分で実装場合によって含まれるSheetsへ出して自由に分析可能
向いている用途学習、完全な制御が必要な場合スケール運用、本番パイプラインすぐ欲しいデータ、非開発チーム

Pythonは自由度が高く、Webスクレイピングの仕組みを内部から学ぶには最良の方法です。課金API(ScrapingBee、Oxylabs、Bright Data など)は、コストより稼働率が重要な本番パイプラインに向いています。そして、開発工数をかけずにレビュー情報が必要なチーム、たとえば競合商品の動向を毎週追うEC運用や、広告コピー用の顧客の言葉を集めたいマーケティングチームには、もうひとつ別の選択肢があります。

ThunderbitでAmazonレビューを取得する方法(ノーコード、保守不要)

私たちは、Pythonスクレイパーを保守し続けるのが大げさに感じられる場面のためにを作りました。使い方は次の通りです。

  1. をインストールする
  2. ブラウザでAmazonの商品レビューページを開く(すでにログインしているので、ログイン壁は気になりません)
  3. 「AI Suggest Fields」 をクリックする — Thunderbit がページを読み取り、Author、Rating、Title、Review Text、Date、Verified Purchase などの列を提案します
  4. 「Scrape」 をクリックする — ページネーション込みで即座にデータを抽出します
  5. Excel、Google Sheets、Airtable、Notion にエクスポートする

最大の利点は、ThunderbitのAIが毎回その時点のページ構造を読み直すことです。CSSセレクターの保守も、Cookie管理も、ボット対策コードも不要です。AmazonがHTMLを変えても、AIが追従します。プログラム的に使いたいが完全自作は避けたい人向けには、 もあります。これはAIによる項目検出つきの構造化データ抽出APIで、セレクター保守は不要です。

Amazonデータをさらに深掘りしたい方は、 もご覧ください。

PythonでAmazonレビューを大規模に取得するコツ

複数のASINにまたがってレビューを取得するなら、次の工夫でトラブルをかなり減らせます。

  • ASINごとにまとめて処理し、商品間にも待機時間を入れる。 ページ間だけでなく、商品間でも間隔を空けましょう。私はASINごとに10〜15秒の休止を入れています。
  • 重複排除は厳しめに行う。 複数の星フィルターや並び替え条件を組み合わせると、同じレビューが重複します。(title, author, date) のタプルをキーにすると便利です。
  • 失敗を記録する。 どのASIN+ページ+フィルターの組み合わせが失敗したかを残しておけば、全体を取り直さずに再試行できます。
  • 大規模案件ではDBに保存する。 CSVを増やし続けるより、SQLiteのような軽量DBのほうがはるかに扱いやすいです。
1import sqlite3
2conn = sqlite3.connect("reviews.db")
3df.to_sql("reviews", conn, if_exists="append", index=False)
  • 定期実行を組む。 継続的な監視なら、cronジョブを設定するか、Thunderbitの Scheduled Scraper 機能を使いましょう。URLとスケジュールを指定するだけで、サーバーなしで自動実行できます。

他の方法も知りたい方は、 も参考になります。

法律と倫理に関する簡単な注意

Amazonのでは、「ロボット、スパイダー、スクレイパー、その他の自動手段を使ってAmazonサービスへアクセスすること」を明確に禁じています。一方で、近年の米国判例では、公開データのスクレイピングに有利な判断も出ています。 では、連邦裁判所が、ログインしていない「ユーザー」ではないスクレイパーによる公開データの取得は利用規約違反に当たらないと判断しました。

ただし重要なのは、ログイン後の取得(このチュートリアルが扱っている部分)では契約法の領域に入ることです。Amazonアカウントを作成した時点で利用規約に同意しているからです。公開表示されている目玉レビューを取得する方が、ログイン壁の向こう側を取得するよりも法的リスクは低くなります。

実務上のガイドラインとしては、取得データを商用で再配布しない、公開表示されている範囲を超える個人データを取らない、robots.txt を尊重する、大規模利用や商用利用では法務に相談する、という点が重要です。これは法的助言ではありません。法的な論点をさらに知りたい方は、 の解説もご覧ください。

まとめ:PythonでAmazonレビューを取得するか、コード自体をやめるか

このガイドで扱った内容を振り返ると、次の通りです。

  • ログイン壁は実在するが、Cookieベース認証で突破できる — ブラウザから7つのCookieをコピーし、requests.Session() に入れる
  • 抽出にはCSSクラスではなく data-hook セレクターを使う — 数週間ごとに壊れるのを避けられる
  • 星フィルターと並び替えを組み合わせて10ページ制限を回避し、商品ごとに500件以上のレビューへアクセスする
  • TextBlobで簡易的に感情分析を追加するか、Hugging Face Transformers で本番精度を狙う
  • ボット対策として、間隔調整、User-Agentローテーション、指数バックオフ、住宅系プロキシを維持する

Pythonは完全な自由度を与えてくれますし、仕組みを内部から理解するには最適です。ただし、やりたいことが「本番用データパイプラインを組みたい」ではなく「金曜日までに競合レビューをスプレッドシートに入れたい」なのであれば、自作スクレイパーの保守負担は見合わないかもしれません。

なら、認証、セレクター、ページネーション、エクスポートまでクリックだけで完結します。 を試して、あなたのワークフローに合うか確認してみてください。Amazonがボット対策をさらに強化するにつれて、リアルタイムで適応するAIツールは「あれば便利」ではなく「必要なもの」になっていくはずです。

スクレイピングの手順を動画で見たい方は、 もぜひご覧ください。

FAQ

1. ログインせずにAmazonレビューは取得できますか?

はい、ただし商品詳細ページ(/dp/{ASIN}/)に表示される約8件の「目玉レビュー」だけです。並び替え、絞り込み、ページネーションがある全文レビューは、2024年後半時点で認証が必要です。多くの業務用途では、ログイン壁への対応が必要になります。

2. Amazonレビューをスクレイピングするのは合法ですか?

Amazonの利用規約では自動スクレイピングが禁止されています。ただし、米国の最近の判例(Meta v. Bright Data、2024年、hiQ v. LinkedIn)は、公開アクセス可能なデータのスクレイピングを支持する傾向があります。ログイン後の取得は、Amazonの利用規約に同意しているため、法的リスクが高くなります。商用利用では法務に相談してください。

3. 1商品あたり何件のAmazonレビューを取得できますか?

Amazonは、並び替えと星フィルターの組み合わせごとにレビュー表示を10ページまでに制限しています。5種類の星フィルター × 2種類の並び替えを使うと、1商品あたり最大100ページ(おおむね1,000件)までアクセスできます。キーワードフィルターを使えば理論上はもっと増えますが、重複もかなり多くなります。

4. Amazonレビューのスクレイピングに最適なPythonライブラリは何ですか?

静的HTMLの解析なら、requests + BeautifulSoup の組み合わせが最も一般的で安定しています。JavaScriptの描画が必要な場合は Selenium が役立ちます。ログイン壁やページネーションを自動で処理したいノーコード代替案としては、 を試してみてください。

5. Amazonスクレイピングでブロックされない方法は?

10種類以上の実ブラウザ由来のUser-Agentをローテーションする、リクエスト間に2〜5秒のランダム遅延を入れる、503/429エラーでは指数バックオフを行う、スケールするなら住宅系プロキシを使う(データセンターIPは事前ブロックされやすい)、そしてリクエスト間でセッションCookieを一貫させる、という方法があります。保守不要で進めたいなら、Thunderbit がブラウザセッション経由でボット対策を自動処理します。

さらに詳しく

目次

Thunderbitを試す

リードや各種データをわずか2クリックで取得。AI搭載。

Thunderbitを入手 無料です
AIでデータを抽出
Google Sheets、Airtable、Notionへ簡単にデータ転送
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week