Scarnox · Blog

Scrape โดยไม่ถูกบล็อก: คู่มือปฏิบัติพร้อมโค้ด

การถูกบล็อกระหว่าง scraping มักหมายถึงสามสิ่ง: คุณส่ง request มากเกินไปเร็วเกินไป client ของคุณดูไม่เหมือนเบราว์เซอร์หรือบอทที่รู้จักเลย หรือ IP address ของคุณอยู่ในรายการที่เว็บไซต์เชื่อถือน้อยลง คุณลดทั้งสามอย่างได้ด้วยนิสัยไม่กี่อย่าง: สังเกตการบล็อกให้เร็ว ชะลอเมื่อเว็บไซต์ตอบโต้ รักษาตัวตนที่สม่ำเสมอและซื่อตรง และใช้ proxy เฉพาะที่เหมาะสม คู่มือนี้อธิบายแต่ละข้อพร้อมโค้ดที่ใช้งานได้ ใช้สำหรับเว็บไซต์ที่คุณได้รับอนุญาตให้ scrape

รู้จักการบล็อก

การบล็อกไม่ได้เป็นหน้า error เสมอไป ให้สังเกต:

บันทึก status code และตัวอย่างสั้น ๆ ของ body สำหรับทุกความล้มเหลว การบล็อกที่คุณมองไม่เห็นใน log คือการบล็อกที่คุณแก้ไม่ได้

ถอยออกด้วย retry

เมื่อเว็บไซต์บอกว่า "ช้าลง" โค้ดของคุณต้องช้าลงมากกว่าเล็กน้อย การถอยแบบ exponential พร้อมจำกัดจำนวนครั้งที่ลองเป็นแนวทางมาตรฐาน และยังเคารพ Retry-After เมื่อเว็บไซต์ส่งมา:

import time
import requests

session = requests.Session()
session.headers.update({
    "User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
    "Accept-Language": "en-US,en;q=0.9",
})

def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
    delay = 2.0
    resp = None
    for _ in range(max_attempts):
        resp = session.get(url, timeout=30)
        if resp.status_code not in (429, 503):
            return resp
        retry_after = resp.headers.get("Retry-After", "")
        wait = float(retry_after) if retry_after.isdigit() else delay
        time.sleep(wait)
        delay *= 2
    return resp  # ยังถูกบล็อกอยู่: คืน response สุดท้ายให้ผู้เรียกจัดการ

resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))

สังเกตสิ่งที่ฟังก์ชันนี้ไม่ทำ มันไม่ retry การตอบกลับ 403 และไม่หมุนผ่านตัวตนเพื่อเลี่ยงการบล็อกหนึ่งครั้ง 403 คือการตัดสินใจให้หยุด ไม่ใช่ปริศนาที่ต้องแก้

วินิจฉัยการบล็อกทีละขั้น

เมื่อการรันเริ่มล้มเหลว ให้ไล่ตรวจตามนี้ก่อนเปลี่ยนอย่างอื่น:

  1. ดู URL ที่ล้มเหลวเป็นครั้งแรกและ status code การบล็อกมักเริ่มที่จุดเฉพาะ ไม่ใช่สุ่ม
  2. เปรียบเทียบอัตรา request ในไม่กี่นาทีก่อนความล้มเหลวแรก การพุ่งเป็นชุดคือสาเหตุที่พบบ่อยที่สุด
  3. ตรวจว่าความล้มเหลวผูกกับ path หนึ่ง ส่วนหนึ่ง หรือช่วงเวลาของวันหรือไม่
  4. เปิด URL เดียวกันด้วยมือในเบราว์เซอร์ปกติหนึ่งครั้ง หากเบราว์เซอร์โหลดได้ ความต่างอยู่ที่รูปแบบ request ของคุณ หากเบราว์เซอร์ถูกบล็อกด้วย แสดงว่าเว็บไซต์หยุดให้บริการหน้านั้นกับคุณชั่วคราว
  5. แก้โค้ดหลังจากนั้นเท่านั้น ชะลอก่อน เพิ่ม backoff ที่สอง และทบทวนตัวตนเป็นอย่างสุดท้าย

การเปลี่ยนหลายอย่างพร้อมกันทำให้ไม่สามารถรู้ได้ว่าอะไรช่วย

รักษาตัวตนที่สม่ำเสมอและซื่อตรง

scraper มักถูกบล็อกเมื่อตัวตนเปลี่ยนไประหว่าง request หรือเมื่อไม่ตรงกับทราฟฟิกอื่น session เดียวที่มี User-Agent ชัดเจนหนึ่งตัวคือตัวตนที่เสถียรที่สุดและเรียบง่ายที่สุด ตั้งชื่อบอทของคุณ เพิ่มลิงก์สำหรับติดต่อ และส่งเฉพาะ header ที่ client ปกติจะส่ง การเปลี่ยน User-Agent เพื่อให้ดูเหมือนผู้เข้าชมหลายคนเป็นรูปแบบหนึ่งของการหลบเลี่ยง และมักทำให้การบล็อกมีแนวโน้มมากขึ้น ไม่ใช่น้อยลง

หากเว็บไซต์ให้เนื้อหาต่างกันกับเบราว์เซอร์และ HTTP client ธรรมดา ให้ใช้เบราว์เซอร์จริงสำหรับหน้าเหล่านั้น และรักษา rate limit เดิม นั่นเป็นเส้นทางที่ชอบด้วยกฎหมาย และทำให้รูปแบบ request สมเหตุสมผล

ใช้ proxy อย่างระมัดระวัง

proxy เปลี่ยน address ที่ request มาจาก มันเป็นเครื่องมือสำหรับความจำเป็นที่ชอบด้วยกฎหมาย เช่น การทดสอบจากภูมิภาคเฉพาะบนเว็บไซต์ที่คุณได้รับอนุญาตให้ทดสอบ หรือการกระจายภาระไปยังโครงสร้างพื้นฐานของคุณเอง มันไม่ใช่วิธีหนีจากข้อจำกัดที่เว็บไซต์ตั้งไว้กับคุณ รูปแบบของ proxy คือรูปแบบที่ task type ของ proxy ใช้:

proxies = {
    "http": "http://user:pass@proxy.example.net:8000",
    "https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)

การเลือกประเภท proxy เป็นคำถามอีกข้อหนึ่ง ซึ่งอธิบายไว้ใน residential vs datacenter proxies และ rotating proxies สำหรับ scraping

เมื่อการบล็อกกลายเป็น captcha

บางเว็บไซต์ตอบปัญหาอัตราด้วย captcha แทนการบล็อกแบบแข็ง ลำดับที่เหมาะสมคือ หยุด ชะลอ ตรวจกฎอีกครั้ง และจึงพิจารณาการ solve สำหรับ PopularCaptcha widget API ที่ใช้งานได้จริงของ Scarnox คืน token ที่คุณส่งในฟิลด์ h-captcha-response สำหรับ captcha ประเภทอื่น ให้ตรวจรายการที่ใช้งานได้จริง เพราะการรองรับ reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF และ Arkose กำลังจะมาเร็ว ๆ นี้ คู่มือโดยละเอียดคือ web scraping captcha

หากคุณเริ่มเห็นการบล็อกบนเว็บไซต์หนึ่ง สาเหตุเกือบทุกครั้งคือรูปแบบของ request การหลีกเลี่ยง captcha เมื่อ scraping ครอบคลุมนิสัยที่ป้องกันปัญหานี้

Scrape อย่างมีความรับผิดชอบ

ขั้นตอนถัดไป