ฉันดึงรีวิว Amazon ด้วย Python อย่างไร (ข้ามด่านล็อกอินได้แล้ว)

อัปเดตล่าสุดเมื่อ April 16, 2026

ตัวดึงรีวิว Amazon ของฉันทำงานได้เป๊ะอยู่หกสัปดาห์ — แล้วอยู่ดี ๆ เช้าวันหนึ่งมันก็คืนค่า 200 OK มา แต่หน้าเว็บว่างเปล่า ไม่มี error ไม่มี CAPTCHA มีแต่ HTML โล่ง ๆ ตรงที่เมื่อก่อนเคยมีรีวิวนับร้อย

ถ้าฟังดูคุ้น ๆ คุณไม่ได้เจออยู่คนเดียว ช่วงปลายปี 2025 Amazon เริ่มบังคับให้เข้าไปดูหน้ารีวิวฉบับเต็มผ่านด่านล็อกอิน ทำให้สคริปต์ Python จำนวนมากพังกันข้ามคืน ช่วงหลายเดือนที่ผ่านมา ผมใช้เวลาใน แก้ปัญหานี้จากทั้งสองฝั่ง — ทั้งตอนพัฒนา AI scraper ของเรา และตอนดูแล pipeline รีวิว Python ของตัวเอง — เลยคิดว่าถึงเวลาจะเขียนคู่มือที่ผมอยากมีตั้งแต่วันที่สคริปต์ของผมล้มครั้งแรก บทความนี้จะพาไล่ตั้งแต่วิธีที่ใช้ได้จริง: การยืนยันตัวตนด้วยคุกกี้, การเลือก selector ที่นิ่งพอจะรอดจาก CSS obfuscation ของ Amazon, วิธีข้ามข้อจำกัดการแบ่งหน้า 10 หน้า, การรับมือ anti-bot และปิดท้ายด้วยส่วนวิเคราะห์ sentiment ที่เปลี่ยนข้อความรีวิวดิบ ๆ ให้กลายเป็น insight ทางธุรกิจได้จริง และถ้าคุณอ่านไปครึ่งทางแล้วคิดว่า “ฉันไม่อยากดูแลโค้ดพวกนี้แล้ว” ผมจะโชว์ให้ดูว่า ทำงานเดียวกันได้ในเวลาราวสองนาที โดยไม่ต้องใช้ Python เลย

การดึงรีวิว Amazon คืออะไร และทำไมถึงสำคัญ?

การดึงรีวิว Amazon คือการใช้โปรแกรมเก็บข้อมูลรีวิวลูกค้าจากหน้าสินค้าของ Amazon — เช่นคะแนนดาว, ข้อความรีวิว, ชื่อผู้เขียน, วันที่, ป้ายยืนยันการซื้อจริง — จากหน้าเว็บสินค้า Amazon โดยตรง นับตั้งแต่ Amazon (และไม่เคยเอากลับมาอีก) web scraping จึงกลายเป็นช่องทางอัตโนมัติแทบจะทางเดียวสำหรับเข้าถึงข้อมูลชุดนี้

ตัวเลขก็ยืนยันเรื่องนี้เหมือนกัน และ . การโชว์รีวิวแค่ 5 รีวิวบนหน้าสินค้าก็สามารถ . บริษัทที่วิเคราะห์ sentiment ของรีวิวอย่างเป็นระบบมีโอกาสเห็น . นี่ไม่ได้เป็นแค่ข้อมูลเชิงทฤษฎีด้าน data science แต่เป็นทั้ง competitive intelligence, สัญญาณพัฒนาสินค้า และถ้อยคำทางการตลาดที่ซ่อนอยู่ในข้อความธรรมดา ๆ บนเซิร์ฟเวอร์ของ Amazon

ทำไมต้องดึงรีวิว Amazon ด้วย Python

Python ยังเป็นภาษาหลักที่คนส่วนใหญ่เลือกใช้กับงานนี้ มันถูกจัดให้เป็นภาษา และ ecosystem ของมัน — requests, BeautifulSoup, pandas, Scrapy — ก็ทำให้การทำ web scraping เข้าถึงได้ แม้กับคนที่ไม่ได้เป็นนักพัฒนาเต็มเวลา

แต่ละทีมก็นำข้อมูลชุดนี้ไปใช้ต่างกันไป:

ทีมกรณีใช้งานสิ่งที่ดึงออกมา
Product / R&Dหา complaint ที่เกิดซ้ำและจัดลำดับการแก้ไขข้อความรีวิว 1–2 ดาว, ความถี่ของคีย์เวิร์ด
Salesติดตาม sentiment ของสินค้าคู่แข่งคะแนนดาว, แนวโน้มจำนวนรีวิว
Marketingดึงภาษาของลูกค้าไปใช้เขียนโฆษณาวลีเชิงบวกจากรีวิว, การกล่าวถึงฟีเจอร์
Ecommerce Opsติดตาม sentiment ของสินค้าตัวเองตามเวลาการกระจายคะแนนดาว, สัดส่วน verified purchase
Market Researchเปรียบเทียบผู้นำในหมวดสินค้าแต่ละฟีเจอร์ชุดข้อมูลรีวิวจากหลาย ASIN

แบรนด์เครื่องครัวแบรนด์หนึ่ง จากนั้นปรับสูตรสินค้าใหม่ แล้วกลับมาครองอันดับ #1 Best Seller ได้ภายใน 60 วัน บริษัทอุปกรณ์ติดตามการออกกำลังกายอีกแห่ง แล้วไล่สาเหตุจนพบว่าเกี่ยวกับอาการแพ้ลาเท็กซ์ จึงออกเวอร์ชัน hypoallergenic และลดการคืนสินค้าลงได้ 40% นี่แหละคือ ROI ที่ทำให้ความพยายามด้าน engineering คุ้มค่า

ด่านล็อกอิน: ทำไมตัวดึงรีวิว Amazon ของคุณถึงหยุดทำงาน

เมื่อวันที่ 14 พฤศจิกายน 2024 การเปลี่ยนแปลงนี้ได้รับการยืนยันจากทั้ง และ . ถ้าคุณเข้า /product-reviews/{ASIN}/ ในโหมดไม่ระบุตัวตน คุณจะถูกพาไปยังหน้าล็อกอินแทนที่จะเห็นข้อมูลรีวิว

python-web-scraping-diagram.webp

อาการมันแนบเนียนมาก: สคริปต์ของคุณได้ 200 OK จริง แต่เนื้อหา HTML กลับเป็นฟอร์มล็อกอิน (name="email", id="ap_password") แทนรีวิว ไม่มี error code ไม่มี CAPTCHA มีแต่... ไม่มีอะไรที่ใช้งานได้

Amazon ทำแบบนี้เพราะเหตุผลด้าน anti-bot และการปฏิบัติตามข้อกำหนดตามภูมิภาคต่าง ๆ การบังคับใช้งานก็ไม่ได้สม่ำเสมอ — บางครั้งหน้าต่างเบราว์เซอร์ใหม่อาจโหลดรีวิวมาได้ไม่กี่รายการก่อนจะเจอด่าน โดยเฉพาะหน้าแรก — แต่สำหรับ scraper ที่ทำงานในระดับใหญ่ คุณควรถือว่าด่านนี้เปิดอยู่ตลอด

โดเมนประเทศของ Amazon แต่ละแห่ง (.de, .co.uk, .co.jp) บังคับใช้ด่านนี้แยกจากกัน ตามที่ผู้ใช้ในฟอรั่มคนหนึ่งบอกไว้: “ต้องล็อกอินแยกตามแต่ละประเทศ” คุกกี้จาก .com จะใช้กับ .co.uk ไม่ได้

หน้าสินค้าของ Amazon (/dp/{ASIN}/) ยังแสดง “featured reviews” ราว โดยไม่ต้องยืนยันตัวตน รีวิวเหล่านี้เป็นรีวิวที่ Amazon คัดมาแล้วด้วยอัลกอริทึม จึงเหมาะไว้ดูภาพรวม sentiment แบบเร็ว ๆ แต่จะ sort, filter หรือไล่หน้าต่อเนื่องไม่ได้

หน้ารวมรีวิวฉบับเต็ม (/product-reviews/{ASIN}/) ซึ่งมีการเรียงตามรีวิวล่าสุด, กรองตามคะแนนดาว และแบ่งหน้าได้เป็นร้อย ๆ รีวิว จะต้องล็อกอิน

ถ้าคุณต้องการแค่รีวิวไม่กี่รายการเพื่อเช็คสภาพตลาดแบบเร็ว ๆ ให้ดึงจากหน้าสินค้า แต่ถ้าต้องการเป็นร้อยหรือเป็นพัน คุณต้องจัดการเรื่อง authentication ให้ได้

สิ่งที่ต้องเตรียมก่อนเริ่ม: Python และไลบรารีที่ใช้

ก่อนเขียนโค้ด มาดูสิ่งที่ต้องมี:

  • ระดับความยาก: ปานกลาง (คุ้นเคยกับ Python และ HTML เบื้องต้น)
  • เวลาที่ใช้: ประมาณ 45 นาทีสำหรับ pipeline เต็มรูปแบบ; ประมาณ 10 นาทีสำหรับการดึงแบบพื้นฐาน
  • สิ่งที่ต้องมี: Python 3.8+, เบราว์เซอร์ Chrome, บัญชี Amazon ที่ใช้งานได้

ติดตั้งไลบรารีหลัก:

1pip install requests beautifulsoup4 lxml pandas textblob

ตัวเลือกเสริม (สำหรับวิเคราะห์ sentiment ขั้นสูง):

1pip install transformers torch

ASIN คืออะไร? นี่คือรหัสสินค้าของ Amazon ยาว 10 ตัวอักษร คุณจะเจอใน URL ของสินค้า เช่นใน amazon.com/dp/B0BCNKKZ91 ค่า ASIN คือ B0BCNKKZ91 ซึ่งเป็นคีย์ที่คุณจะใช้ต่อใน URL ของหน้ารีวิว

ขั้นตอนที่ 1: ข้ามด่านล็อกอินด้วยการยืนยันตัวตนผ่านคุกกี้

วิธีที่เชื่อถือได้ที่สุดคือ ล็อกอินเข้า Amazon บนเบราว์เซอร์ของคุณ จากนั้นคัดลอก session cookies แล้วใส่เข้าไปใน requests.Session() ของ Python วิธีนี้ช่วยเลี่ยง CAPTCHA และ SMS 2FA ที่มักกวนใจเวลาใช้ Selenium ล็อกอินอัตโนมัติ

คุณต้องใช้คุกกี้ 7 ตัวนี้:

ชื่อคุกกี้หน้าที่
session-idรหัส session ที่เปลี่ยนหมุนเวียน
session-id-timeเวลาของ session
session-tokenโทเค็น session ที่เปลี่ยนหมุนเวียน
ubid-mainตัวระบุการท่องเว็บของผู้ใช้
at-mainโทเค็นยืนยันตัวตนหลัก
sess-at-mainการยืนยันตัวตนในระดับ session
x-mainตัวระบุที่ผูกกับอีเมลผู้ใช้

วิธีดึงคุกกี้จาก Chrome DevTools

  1. ล็อกอินเข้า amazon.com ใน Chrome
  2. เปิด DevTools (กด F12 หรือคลิกขวา → Inspect)
  3. ไปที่ ApplicationStorageCookieshttps://www.amazon.com
  4. หาแต่ละชื่อคุกกี้ในตาราง แล้วคัดลอกค่าออกมา
  5. จัดให้อยู่ในรูป string คั่นด้วยเซมิโคลอนสำหรับ Python

ตั้งค่า session แบบนี้:

1import requests
2session = requests.Session()
3# วางค่าคุกกี้ของคุณตรงนี้
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 เดิมซ้ำในทุกคำขอ วิธีนี้จะทำให้คุกกี้คงที่และดูคล้าย session ของเบราว์เซอร์จริง คุกกี้มักอยู่ได้ตั้งแต่หลายวันถึงหลายสัปดาห์ภายใต้ภาระการ scraping แต่ถ้าเริ่มถูกเด้งกลับไปหน้า login อีก ก็ให้รีเฟรชคุกกี้จากเบราว์เซอร์

สำหรับ marketplace ที่ไม่ใช่ .com ชื่อคุกกี้จะเปลี่ยนเล็กน้อย — amazon.de ใช้ at-acbde แทน at-main, amazon.co.uk ใช้ at-acbuk และอื่น ๆ แต่ละ marketplace ต้องมี session แยกกัน

ขั้นตอนที่ 2: สร้าง request และแยก HTML ของรีวิวด้วย BeautifulSoup

URL ของรีวิว Amazon มีรูปแบบแบบนี้:

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("พบด่านล็อกอิน — โปรดรีเฟรชคุกกี้ของคุณ")
9    if response.status_code != 200:
10        raise Exception(f"HTTP {response.status_code}")
11    return BeautifulSoup(response.text, "lxml")

มีทริกเล็ก ๆ ที่ช่วยได้: ก่อนจะเข้าไปยังหน้ารวมรีวิว ให้แวะเข้าหน้าสินค้าก่อน วิธีนี้ทำให้ session ของคุณดูเป็นพฤติกรรมการใช้งานจริงมากขึ้น

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: ใช้ selector ที่นิ่งเพื่อดึงข้อมูลรีวิว (หยุดพึ่ง CSS class ได้แล้ว)

นี่คือจุดที่บทเรียนส่วนใหญ่จากปี 2022–2023 พังกัน Amazon ทำให้ชื่อ CSS class สับสนและเปลี่ยนเป็นระยะ ๆ และอย่างที่นักพัฒนาหลายคนบ่นกันในฟอรั่มว่า “ไม่มีใครตั้งแพทเทิร์นชื่อ class ของ span tag ไว้เลยสักแบบ”

ทางแก้คือ Amazon ใช้แอตทริบิวต์ data-hook บนองค์ประกอบรีวิว และมันค่อนข้างเสถียรมาก นี่คือ identifier เชิงความหมายที่ frontend ของ Amazon เองใช้ จึงไม่ถูกสุ่มเปลี่ยนง่าย ๆ

ฟิลด์รีวิวselector ที่นิ่ง (data-hook)selector ที่เปราะบาง (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 (ขึ้นกับภูมิภาค)
ยืนยันการซื้อ[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        # ยืนยันการซื้อ
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

ผมใช้ชุด selector นี้กับหลาย ASIN มาหลายเดือนแล้ว และแอตทริบิวต์ data-hook ไม่เคยเปลี่ยนเลยสักครั้ง ในขณะที่ CSS class นั้นเปลี่ยนไปแล้วอย่างน้อยสองรอบในช่วงเวลาเดียวกัน

ขั้นตอนที่ 4: รับมือ Pagination และข้อจำกัด 10 หน้า ของ Amazon

Amazon จำกัดค่า pageNumber ไว้ที่ 10 หน้า หน้าละ 10 รีวิว — เป็นเพดานแข็งที่ประมาณ 100 รีวิวต่อหนึ่งชุดตัวกรอง ปุ่ม “Next page” จะหายไปหลังหน้า 10

ลูป pagination แบบพื้นฐาน:

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")

วิธีดึงรีวิว Amazon ให้เกิน 10 หน้า

ทางแก้คือใช้การแบ่งเป็น buckets ตามฟิลเตอร์ แต่ละชุดของ filterByStar และ sortBy จะได้หน้าต่างอิสระของตัวเองที่มีได้ 10 หน้า

ค่าฟิลเตอร์ดาว: one_star, two_star, three_star, four_star, five_star
ค่าการเรียงลำดับ: recent, helpful (ค่าเริ่มต้น)

เมื่อรวม 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                # ตัดข้อมูลซ้ำด้วยคู่ title + author
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)}")

จะมีข้อมูลทับซ้อนกันระหว่าง bucket ต่าง ๆ ดังนั้นการ deduplicate จึงสำคัญมาก ผมใช้คู่ title + author เป็นคีย์แบบเร็ว ๆ — ไม่สมบูรณ์แบบ แต่ช่วยตัดข้อมูลซ้ำได้ส่วนใหญ่

ขั้นตอนที่ 5: หลบการตรวจจับ Anti-Bot (หมุน, หน่วง, retry)

Amazon ใช้ AWS WAF Bot Control และมันเข้มขึ้นมาก การป้องกันชั้นเดียว (เช่นเปลี่ยน User-Agent อย่างเดียว หรือหน่วงเวลาอย่างเดียว) ไม่พอแล้ว

เทคนิควิธีทำ
หมุน User-Agentสุ่มจาก browser string จริง 10+ แบบ
Exponential backoffหน่วง retry เป็น 2s → 4s → 8s เมื่อเจอ 503
จำกัดอัตราคำขอหน่วง random.uniform(2, 5) วินาทีระหว่างหน้า
หมุนพร็อกซีสลับใช้ residential proxy
Session fingerprintคุกกี้ + headers ต้องคงที่ในแต่ละ session
TLS impersonationใช้ curl_cffi แทน requests ปกติใน production

ตัวอย่าง retry wrapper ที่ใช้งานได้จริง:

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("เจอด่านล็อกอิน — คุกกี้หมดอายุแล้ว")
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} ล้มเหลว: {e}")
33    return None

หมายเหตุเรื่องพร็อกซี: Amazon (AWS, GCP, Azure, DigitalOcean) ในระดับเครือข่าย ถ้าคุณ scrape มากกว่าสองสามร้อยหน้า residential proxy แทบจะจำเป็น — งบประมาณอาจอยู่ราว 50–200+ ดอลลาร์ต่อเดือนขึ้นกับปริมาณ สำหรับโปรเจกต์เล็ก ๆ (ต่ำกว่า 100 request/วัน) การหน่วงอย่างระวังจาก IP บ้านของคุณมักใช้งานได้

Amazon ยังตรวจ fingerprint ของ TLS ด้วย Python requests ปกติมี . สำหรับ scraper ระดับ production ลองพิจารณา curl_cffi ซึ่งเลียนแบบ TLS stack ของเบราว์เซอร์จริง ส่วนงานระดับบทเรียน (ไม่กี่ร้อยหน้า) requests พร้อม header ที่ดีมักจะเอาอยู่

ขั้นตอนที่ 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.0Best purchase this yearBattery lasts all day, screen is gorgeous...January 15, 2025the United StatesTrue
Mike T.2.0Disappointed after 2 weeksThe charging port stopped working...February 3, 2025the United StatesTrue
Priya K.4.0Great value for the priceDoes everything I need, minor lag on heavy apps...March 10, 2025the United StatesFalse

ถ้าจะส่งออกเป็น Excel ใช้: df.to_excel("amazon_reviews.xlsx", index=False) (ต้องติดตั้ง openpyxl)

สำหรับ Google Sheets ไลบรารี gspread ก็ใช้ได้ แต่ต้องผ่าน — สร้างโปรเจกต์, เปิดใช้ 2 API, สร้าง service account credentials, แชร์ชีต ฯลฯ ถ้าฟังดูเหมือนต้องเตรียมระบบมากกว่าการ scrape จริง คุณคิดไม่ผิดเลย (นี่คือหนึ่งในจังหวะที่เครื่องมืออย่าง ที่ส่งออกไป Google Sheets ได้ในคลิกเดียวเริ่มดูน่าสนใจมาก)

โบนัส: เพิ่มการวิเคราะห์ sentiment ให้กับรีวิวที่ดึงมาใน 5 บรรทัด Python

บทความสอน scraping ส่วนใหญ่หยุดแค่การ export CSV แต่การให้คะแนน sentiment คือสิ่งที่เปลี่ยนข้อมูลดิบให้กลายเป็นการตัดสินใจทางธุรกิจ

วิธีพื้นฐานที่เร็วที่สุดใช้ TextBlob:

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

สิ่งนี้จะให้คะแนน 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

สำหรับความแม่นยำระดับ production คำแนะนำคือใช้ Hugging Face Transformers และ เมื่อเทียบกับเครื่องมือแบบ lexicon tool โมเดล 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. Paid Scraping API vs. Thunderbit

ผมดูแล Python scraper สำหรับ Amazon มาหลายตัว และพูดตรง ๆ เลยว่า: มันพังได้เสมอ selector เปลี่ยน คุกกี้หมดอายุ Amazon เพิ่มชั้นตรวจจับบอทใหม่ แล้วเช้าวันเสาร์ของคุณก็กลายเป็นเวลานั่ง debug scraper แทนที่จะวิเคราะห์ข้อมูล ผู้ใช้ในฟอรั่มก็บ่นในแนวเดียวกัน — สคริปต์ DIY ที่ “ใช้ได้เมื่อเดือนที่แล้ว” ตอนนี้ต้อง patch ตลอดเวลา

มาดูการเปรียบเทียบสามแนวทางหลักกัน:

เกณฑ์DIY Python (BS4/Selenium)Paid Scraping APIThunderbit (No-Code)
เวลาในการตั้งค่า1–3 ชั่วโมง30 นาที (API key)2 นาที
ค่าใช้จ่ายฟรี (+ ค่าพร็อกซี)$50–200+/เดือนมีแผนใช้ฟรี
การจัดการด่านล็อกอินต้องจัดการคุกกี้เองมักมีให้จัดการอัตโนมัติ
การดูแลรักษาสูง (selector พังบ่อย)ต่ำ (ผู้ให้บริการดูแล)แทบไม่มี (AI ปรับตัว)
Paginationต้องเขียนโค้ดเองมีมาให้มีมาให้
รองรับหลายประเทศต้องแยก session ต่อโดเมนโดยทั่วไปรองรับใช้ผ่านเบราว์เซอร์ = ตาม locale ของคุณ
การวิเคราะห์ sentimentต้องเขียนโค้ดเองบางเจ้าให้มาexport ไป Sheets แล้ววิเคราะห์ต่อได้
เหมาะกับการเรียนรู้, ควบคุมได้หมดpipeline ระดับ productionดึงข้อมูลเร็ว, ทีมที่ไม่ใช่นักพัฒนา

Python ให้คุณควบคุมได้ทั้งหมด และเป็นวิธีที่ดีที่สุดในการเรียนรู้ว่า web scraping ทำงานอย่างไรภายใน แต่ถ้าโจทย์ของคุณคือ “ฉันต้องได้ข้อมูลรีวิวคู่แข่งลงสเปรดชีตภายในวันศุกร์” มากกว่า “ฉันอยากสร้าง data pipeline ระดับ production” ภาระการดูแล scraper แบบเขียนเองอาจไม่คุ้ม

วิธีดึงรีวิว Amazon ด้วย Thunderbit (ไม่ต้องเขียนโค้ด, ไม่ต้องดูแล)

เราออกแบบ มาเพื่อรับมือสถานการณ์ที่การดูแล Python scraper ดูเกินความจำเป็น เวิร์กโฟลว์เป็นแบบนี้:

  1. ติดตั้ง
  2. เปิดหน้ารีวิวสินค้าบน Amazon ในเบราว์เซอร์ของคุณ (คุณล็อกอินอยู่แล้ว ดังนั้นด่านล็อกอินไม่ใช่ปัญหา)
  3. คลิก “AI Suggest Fields” — Thunderbit จะอ่านหน้าเว็บและแนะนำคอลัมน์ เช่น Author, Rating, Title, Review Text, Date, Verified Purchase
  4. คลิก “Scrape” — ดึงข้อมูลได้ทันที พร้อม pagination ในตัว
  5. Export ไปยัง Excel, Google Sheets, Airtable หรือ Notion

ข้อดีหลักคือ AI ของ Thunderbit อ่านโครงสร้างหน้าเว็บใหม่ทุกครั้ง ไม่มี CSS selector ให้ต้องดูแล ไม่มีการจัดการคุกกี้ ไม่มีโค้ด anti-bot เมื่อ Amazon เปลี่ยน HTML AI ก็ปรับตัวได้ สำหรับผู้อ่านที่ต้องการเข้าถึงข้อมูลแบบโปรแกรมแต่ไม่อยากดูแลเองทั้งหมด Thunderbit ยังมี สำหรับดึงข้อมูลแบบมีโครงสร้างผ่าน API พร้อมตรวจจับฟิลด์ด้วย AI โดยไม่ต้องดูแล selector

ถ้าอยากอ่านเชิงลึกเรื่องข้อมูล Amazon เพิ่ม ดูคู่มือของเราเกี่ยวกับ และ

เคล็ดลับการดึงรีวิว Amazon ในระดับสเกลด้วย Python

ถ้าคุณกำลังดึงรีวิวจากหลาย ASIN มีแนวปฏิบัติไม่กี่อย่างที่จะช่วยลดปัญหาได้มาก:

  • จัด batch ของ ASIN และหน่วงเวลาระหว่างสินค้า ไม่ใช่แค่ระหว่างหน้า ผมใช้การพัก 10–15 วินาทีระหว่าง ASIN
  • ตัดข้อมูลซ้ำอย่างจริงจัง เมื่อรวมผลจากหลาย star filter และ sort order จะมีรีวิวซ้อนกัน ใช้ชุด (title, author, date) เป็น dedup key
  • บันทึกความล้มเหลว เก็บว่า ASIN + page + filter ชุดไหนล้มเหลว เพื่อจะ retry เฉพาะส่วนนั้นได้โดยไม่ต้อง scrape ใหม่ทั้งหมด
  • เก็บลงฐานข้อมูลสำหรับโปรเจกต์ใหญ่ SQLite แบบง่าย ๆ มักดีกว่า CSV ที่โตไปเรื่อย ๆ:
1import sqlite3
2conn = sqlite3.connect("reviews.db")
3df.to_sql("reviews", conn, if_exists="append", index=False)
  • ตั้งเวลาสำหรับการ scrape ซ้ำ ถ้าต้องติดตามต่อเนื่อง ให้ตั้ง cron job หรือใช้ฟีเจอร์ Scheduled Scraper ของ Thunderbit — ระบุ URL และตารางเวลา แล้วระบบจะจัดการที่เหลือให้โดยไม่ต้องมีเซิร์ฟเวอร์

สำหรับแนวทางเพิ่มเติม บทความของเราเรื่อง และ มีตัวเลือกอื่น ๆ ให้อ่านต่อ

หมายเหตุสั้น ๆ เรื่องกฎหมายและจริยธรรม

ของ Amazon ระบุชัดเจนว่าห้ามใช้ “robot, spider, scraper หรือวิธีอัตโนมัติอื่นใด” เพื่อเข้าถึงบริการ Amazon อย่างไรก็ตาม คดีในสหรัฐฯ ช่วงหลังค่อนข้างเอื้อกับผู้ scrape ข้อมูลสาธารณะ ในคดี ศาลรัฐบาลกลางตัดสินว่าการ scrape ข้อมูลที่เข้าถึงได้แบบสาธารณะไม่ขัดกับ ToS หากผู้ scrape ไม่ได้เป็น “user” ที่ล็อกอิน

ประเด็นสำคัญคือ การ scrape หลังล็อกอิน (ซึ่งบทความนี้ครอบคลุม) จะเข้าสู่มิติของกฎหมายสัญญา เพราะคุณยอมรับ ToS ของ Amazon ตอนสร้างบัญชีแล้ว การ scrape featured reviews ที่มองเห็นได้สาธารณะมีความเสี่ยงทางกฎหมายน้อยกว่าการ scrape ข้ามด่านล็อกอิน

แนวปฏิบัติที่เหมาะสม: อย่านำข้อมูลที่ดึงมาไปแจกจ่ายเชิงพาณิชย์, อย่าดึงข้อมูลส่วนตัวของผู้ใช้นอกเหนือจากที่แสดงสาธารณะ, เคารพ robots.txt และปรึกษาผู้เชี่ยวชาญด้านกฎหมายหากจะใช้งานในระดับใหญ่หรือเชิงพาณิชย์ นี่ไม่ใช่คำแนะนำทางกฎหมาย หากต้องการอ่านภาพรวมเพิ่มเติม ดูบทความ

สรุป: จะดึงรีวิว Amazon ด้วย Python หรือข้ามโค้ดไปเลยก็ได้

สรุปสิ่งที่คู่มือนี้พาไล่ไป:

  • ด่านล็อกอินมีจริง แต่แก้ได้ด้วยการยืนยันตัวตนผ่านคุกกี้ — คัดลอก 7 คุกกี้จากเบราว์เซอร์แล้วใส่เข้า requests.Session()
  • ใช้ selector แบบ data-hook ไม่ใช่ CSS class เพื่อให้การดึงข้อมูลไม่พังทุกไม่กี่สัปดาห์
  • รวม star filter และ sort order เพื่อเอาชนะข้อจำกัด 10 หน้า และเข้าถึงรีวิวได้ 500+ รายการต่อสินค้า
  • เพิ่ม sentiment analysis ด้วย TextBlob เพื่อ baseline แบบเร็ว หรือใช้ Hugging Face Transformers เพื่อความแม่นยำระดับ production
  • ดูแลมาตรการ anti-bot: การหน่วงเวลา, การหมุน User-Agent, exponential backoff และ residential proxies เมื่อสเกลใหญ่

Python ให้คุณควบคุมได้เต็มที่ และเป็นวิธีที่ดีที่สุดในการเข้าใจการทำงานภายในทั้งหมด แต่ถ้าโจทย์ของคุณคือ “ฉันต้องการข้อมูลรีวิวคู่แข่งลงสเปรดชีตภายในวันศุกร์” มากกว่าจะเป็น “ฉันอยากสร้าง data pipeline ระดับ production” ภาระการดูแล scraper เองอาจไม่คุ้ม

จัดการทั้งการยืนยันตัวตน, selector, pagination และการ export ได้ในไม่กี่คลิก — ลองใช้ แล้วดูว่าเข้ากับเวิร์กโฟลว์ของคุณไหม ในขณะที่ Amazon เพิ่มความเข้มงวดด้าน anti-bot เครื่องมือที่ใช้ AI และปรับตัวได้แบบเรียลไทม์กำลังจะกลายเป็น “จำเป็น” มากกว่า “ของน่ามี”

คุณยังสามารถดู สำหรับวิดีโอสอนเวิร์กโฟลว์การ scraping ได้อีกด้วย

คำถามที่พบบ่อย

1. ดึงรีวิว Amazon โดยไม่ล็อกอินได้ไหม?

ได้ แต่จะได้เพียงประมาณ 8 “featured reviews” ที่แสดงบนหน้าสินค้า (/dp/{ASIN}/) เท่านั้น หน้ารวมรีวิวฉบับเต็มที่มีการเรียงลำดับ, กรอง, และแบ่งหน้าต้องยืนยันตัวตนตั้งแต่ปลายปี 2024 เป็นต้นมา สำหรับ use case ทางธุรกิจส่วนใหญ่ คุณจะต้องจัดการด่านล็อกอิน

2. การดึงรีวิว Amazon ผิดกฎหมายไหม?

เงื่อนไขการใช้งานของ Amazon ห้ามการ scrape แบบอัตโนมัติ อย่างไรก็ตาม คดีในสหรัฐฯ ช่วงหลัง (Meta v. Bright Data, 2024; hiQ v. LinkedIn) สนับสนุนการ scrape ข้อมูลที่เปิดให้เข้าถึงสาธารณะ การ scrape หลังล็อกอินมีความเสี่ยงทางกฎหมายสูงกว่าเพราะคุณยอมรับ ToS ของ Amazon ไปแล้ว ควรปรึกษาผู้เชี่ยวชาญด้านกฎหมายหากใช้งานเชิงพาณิชย์

3. ต่อหนึ่งสินค้าจะดึงรีวิว Amazon ได้กี่รายการ?

Amazon จำกัดหน้ารวมรีวิวไว้ 10 หน้า ต่อหนึ่งชุดของ sort order และ star filter หากใช้ครบ 5 ฟิลเตอร์ดาว × 2 การเรียงลำดับ คุณจะเข้าถึงได้สูงสุด 100 หน้า หรือราว 1,000 รีวิวต่อสินค้า ถ้าใช้ keyword filter เพดานเชิงทฤษฎีจะสูงกว่านั้นมาก แต่ก็จะมีข้อมูลซ้ำค่อนข้างเยอะ

4. ไลบรารี Python ที่ดีที่สุดสำหรับดึงรีวิว Amazon คืออะไร?

requests + BeautifulSoup สำหรับ parsing HTML แบบ static เป็นชุดที่พบบ่อยและเชื่อถือได้มากที่สุด Selenium เหมาะเมื่อจำเป็นต้องเรนเดอร์ JavaScript ถ้าต้องการตัวเลือก no-code ที่จัดการด่านล็อกอินและ pagination ให้โดยอัตโนมัติ ลอง

5. จะหลีกเลี่ยงการถูกบล็อกตอนดึงรีวิว Amazon ได้อย่างไร?

หมุนสตริง User-Agent จากชุด browser จริง 10+ แบบ, เพิ่มการหน่วงแบบสุ่ม 2–5 วินาทีระหว่างคำขอ, ทำ exponential backoff เมื่อเจอ error 503/429, ใช้ residential proxy เมื่อต้องสเกลใหญ่ (เพราะ IP ของดาต้าเซ็นเตอร์มักถูกบล็อกไว้แล้ว), และใช้คุกกี้ session เดิมให้สอดคล้องกันในทุกคำขอ หากต้องการแนวทางที่ไม่ต้องดูแลเอง Thunderbit จะจัดการ anti-bot ให้ผ่าน session ของเบราว์เซอร์คุณโดยอัตโนมัติ

เรียนรู้เพิ่มเติม

สารบัญ

ลองใช้ Thunderbit

ดึงลีดและข้อมูลอื่น ๆ ได้ใน 2 คลิก ขับเคลื่อนด้วย AI

รับ Thunderbit ใช้ฟรี
ดึงข้อมูลด้วย AI
ส่งข้อมูลไปยัง Google Sheets, Airtable หรือ Notion ได้อย่างง่ายดาย
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week