Το Target.com είναι από εκείνα τα sites που δείχνουν εύκολα για scraping — μέχρι να το δοκιμάσεις στην πράξη. Αν έχεις γράψει ποτέ ένα γρήγορο Python script με Requests και BeautifulSoup, το έστειλες σε μια σελίδα προϊόντος του Target και είδες το πεδίο της τιμής να επιστρέφει ως None, τότε είσαι σε πολύ καλή παρέα.
Έχοντας δοκιμάσει προσεγγίσεις scraping στα περισσότερα μεγάλα retail sites, μπορώ να το επιβεβαιώσω: το Target συγκαταλέγεται σταθερά στα πιο δύσκολα. Με 208–280 εκατομμύρια μηνιαίες επισκέψεις, είναι χρυσωρυχείο δεδομένων προϊόντων — τιμές, αξιολογήσεις, απόθεμα, κριτικές — αλλά ο συνδυασμός React-based client-side rendering και του bot detection της Akamai σημαίνει ότι η αφελής προσέγγιση αποτυγχάνει σχεδόν αμέσως. Υπάρχουν όμως τρεις μέθοδοι με Python που όντως δουλεύουν. Θα περάσω από καθεμία, θα εξηγήσω γιατί η πρώτη προσπάθεια σπάει πάντα και θα σου δείξω και μια no-code λύση όταν το Python δεν αξίζει τον κόπο.
Γιατί το πρώτο σου Python scrape στο Target.com επιστρέφει None
Πριν από τις λύσεις, ας δούμε το πρόβλημα. Αυτό είναι το code που γράφουν οι περισσότεροι αρχάριοι:
import requests
from bs4 import BeautifulSoup
url = "https://www.target.com/p/some-product/-/A-12345678"
response = requests.get(url, headers={"User-Agent": "Mozilla/5.0"})
soup = BeautifulSoup(response.text, "html.parser")
price = soup.select_one('[data-test="current-price"]')
print(price) # None
Το αποτέλεσμα; None. Κάθε φορά.
Δεν είναι bug στο code σου. Το HTML που επιστρέφει το requests.get() από το Target είναι ουσιαστικά ένας σκελετός — ένα React shell που λέει «φόρτωσε αυτό το JavaScript για να εμφανιστεί η πραγματική σελίδα». Οι τιμές προϊόντων, οι αξιολογήσεις, οι κριτικές και η διαθεσιμότητα εισάγονται όλα μέσω JavaScript μετά το αρχικό φόρτωμα της σελίδας. Επειδή η Requests library της Python δεν εκτελεί JavaScript, αυτά τα στοιχεία απλώς δεν υπάρχουν στην απάντηση.
Τα forum threads είναι γεμάτα με developers που χτυπούν σε αυτόν τον τοίχο. Μια ανάλυση του ScrapeOps το λέει ωμά: «Ένα στοιχείο εμφανίζεται ως None επειδή αποδίδεται με Javascript και το requests δεν μπορεί να τραβήξει HTML που αποδίδεται με Javascript.» Ένα tutorial του Crawlbase το επιβεβαιώνει: «Όταν στέλνεις HTTP request στο Target URL, η HTML response δεν περιέχει ουσιαστικά δεδομένα.»
Και ακόμη κι αν λύσεις το θέμα του JavaScript, υπάρχει κι άλλο επίπεδο: το Akamai bot detection του Target fingerprintάρει το TLS handshake σου και σημαδεύει τη library requests της Python πριν ανταλλαχθεί ούτε ένα byte HTML. Περισσότερα γι’ αυτό σε λίγο.
Τι κάνει το Target.com τόσο δύσκολο στο scraping με Python
Το Target δεν είναι απλώς «ένα site που χρησιμοποιεί JavaScript». Είναι ένα πολυεπίπεδο αμυντικό σύστημα — και η κατανόηση κάθε επιπέδου είναι ο τρόπος να διαλέξεις τη σωστή μέθοδο scraping.
Δεδομένα προϊόντων που αποδίδονται με JavaScript
Το Target.com είναι χτισμένο σε React. Όταν φορτώνεις μια σελίδα προϊόντος ή αναζήτησης σε πραγματικό browser, συμβαίνουν τα εξής:
- Ο server στέλνει ένα ελάχιστο HTML shell
- Φορτώνονται και εκτελούνται τα JavaScript bundles
- Το frontend καλεί το εσωτερικό Redsky API του Target
- Τα δεδομένα προϊόντος (τιμές, αξιολογήσεις, εικόνες, διαθεσιμότητα) αποδίδονται στο DOM
Αν παραλείψεις τα βήματα 2–4 — και ακριβώς αυτό κάνει το requests.get() — παίρνεις μια κενή σελίδα. Το GroupBWT το μέτρησε αυτό: τα στατικά HTTP requests πιάνουν περίπου 30% των διαθέσιμων δεδομένων στο Target. Το υπόλοιπο 70% απαιτεί εκτέλεση JavaScript ή πρόσβαση στο API.
Οι σελίδες αποτελεσμάτων αναζήτησης είναι ακόμα χειρότερες. Μόνο λίγα προϊόντα εμφανίζονται στο αρχικό HTML· τα υπόλοιπα φορτώνουν όσο κάνεις scroll.
Οι άμυνες anti-bot του Target: πέρα από τη γενική συμβουλή «βάλε proxies»
Οι περισσότερες οδηγίες scraping περνούν τα anti-bot μέτρα με το αόριστο «απλώς χρησιμοποίησε proxies». Οι άμυνες του Target αξίζουν περισσότερη ακρίβεια.
TLS Fingerprinting (το μεγάλο ζήτημα). Κατά το HTTPS handshake, ο client σου στέλνει ένα packet «Client Hello» που αποκαλύπτει την έκδοση TLS, τα cipher suites, τα extensions και τις ελλειπτικές καμπύλες που χρησιμοποιεί. Αυτά γίνονται hash σε ένα JA3 fingerprint. Η library requests της Python παράγει ένα στατικό, γνωστό hash — 8d9f7747675e24454cd9b7ed35c58707 — το οποίο οι anti-bot βάσεις δεδομένων σημαδεύουν αμέσως. Το Chrome στέλνει 16 προσεκτικά ταξινομημένα cipher suites με GREASE values· η Python στέλνει 60+ με μη browser σειρά. Το μπλοκάρισμα γίνεται πριν ανταλλαχθεί οποιοδήποτε HTTP content.
Αξιολόγηση φήμης IP. Η Akamai κατηγοριοποιεί τα IPs σε επίπεδα εμπιστοσύνης. Τα datacenter IPs παίρνουν, με τα λόγια της Scrapfly, «σημαντικά αρνητικά trust scores, καθώς είναι πιθανό να χρησιμοποιούνται από bots». Τα residential IPs παίρνουν θετικά scores. Στο Target ειδικά, τα ranges των datacenter IPs σημαδεύονται αμέσως.
JavaScript fingerprinting. Η Akamai εισάγει JavaScript που συλλέγει τις προδιαγραφές της JS engine σου, τις δυνατότητες hardware, τα δεδομένα του λειτουργικού, τις γραμματοσειρές, τα plugins και behavioral data (ταχύτητα πληκτρολόγησης, κίνηση ποντικιού, χρονισμό κλικ). Έτσι δημιουργείται το cookie _abck — ένα stateful fingerprint token. Χωρίς έγκυρο _abck, τα requests μπλοκάρονται.
Rate limiting. Το Target ενεργοποιεί 429 errors περίπου στα 30–60 requests ανά λεπτό ανά IP. Μερικοί χρήστες αναφέρουν ότι λαμβάνουν παραπλανητικές αποκρίσεις 200 OK που στην πραγματικότητα περιέχουν τη σελίδα μπλοκαρίσματος «Pardon Our Interruption» — κάτι που κάνει την αυτοματοποιημένη ανίχνευση δύσκολη.
Το ScrapeOps βαθμολογεί τη δυσκολία του Target 7/10 συνολικά. Το συγκεκριμένο Akamai bypass βαθμολογείται 9/10.
3 μέθοδοι για να κάνεις scrape το Target.com με Python (δίπλα-δίπλα)
Δεν υπάρχει ένα άρθρο εκεί έξω που να συγκρίνει και τις τρεις βιώσιμες προσεγγίσεις σε ένα σημείο. Ορίστε τες, αξιολογημένες με ειλικρίνεια:
| Κριτήριο | Requests + BS4 | Selenium / Playwright | Redsky API |
|---|---|---|---|
| Υποστηρίζει απόδοση JS | ❌ Όχι | ✅ Ναι | ✅ Ναι (JSON) |
| Ταχύτητα ανά στοιχείο | ⚡ ~0.5–1s | 🐢 ~5–10s | ⚡ ~0.5–1s |
| Κίνδυνος anti-bot | ⚠️ Υψηλός (TLS fingerprint) | ⚠️ Μεσαίος | ⚠️ Μεσαίος (μπορεί να αλλάξουν τα auth keys) |
| Πολυπλοκότητα setup | Χαμηλή | Μεσαία | Μεσαία-Υψηλή (reverse-engineering) |
| Πληρότητα δεδομένων | ~30% (μόνο static HTML) | ~95% (πλήρης σελίδα) | ~90% (δομημένο JSON) |
| Καλύτερο για | Static metadata, __TGT_DATA__ | Πλήρεις σελίδες προϊόντων, κριτικές | Μαζικά δεδομένα προϊόντων σε μεγάλη κλίμακα |
Ας χτίσουμε την καθεμία.
Μέθοδος 1: Scrape Target.com με Python Requests και BeautifulSoup
Αυτή η μέθοδος δεν θα σου δώσει τιμές που αποδίδονται με JavaScript στις σελίδες αναζήτησης. Είναι όμως γρήγορη και ελαφριά και εξάγει περισσότερα απ’ όσα περιμένεις — αν ξέρεις πού να κοιτάξεις.
Το κόλπο: το Target ενσωματώνει κάποια δεδομένα προϊόντος σε <script> tags που περιέχουν μια μεταβλητή __TGT_DATA__ με __PRELOADED_QUERIES__. Αυτό το JSON blob περιλαμβάνει ονόματα προϊόντων, περιγραφές, χαρακτηριστικά και μερικές φορές τιμές σε μεμονωμένες σελίδες προϊόντων. Μπορείς επίσης να πάρεις τίτλους προϊόντων και URLs από το HTML των αποτελεσμάτων αναζήτησης.
Βήμα 1: Ρύθμισε το Python περιβάλλον σου
Δημιούργησε έναν φάκελο project και εγκατέστησε τα dependencies:
mkdir target-scraper && cd target-scraper
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install requests beautifulsoup4 curl_cffi
Χρησιμοποίησε το curl_cffi αντί για το standard requests εδώ. Προσποιείται browser TLS fingerprints, και αυτός είναι ο σημαντικότερος παράγοντας για να αποφύγεις blocks στο Target. Τα benchmarks δείχνουν 92% anti-bot evasion rate με curl_cffi έναντι μόλις 12% με standard requests — βελτίωση 15x.
Βήμα 2: Κάνε scrape τα αποτελέσματα αναζήτησης του Target
Η μορφή του URL αναζήτησης του Target είναι απλή: https://www.target.com/s?searchTerm={keyword}
from curl_cffi import requests as cureq
from bs4 import BeautifulSoup
import time, random
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
}
url = "https://www.target.com/s?searchTerm=bluetooth+headphones"
resp = cureq.get(url, headers=headers, impersonate="chrome124")
soup = BeautifulSoup(resp.text, "html.parser")
# Οι κάρτες προϊόντων χρησιμοποιούν αυτό το data-test attribute
cards = soup.find_all("div", {"data-test": "@web/site-top-of-funnel/ProductCardWrapper"})
for card in cards:
link_tag = card.find("a")
title = link_tag.get_text(strip=True) if link_tag else "N/A"
href = "https://www.target.com" + link_tag["href"] if link_tag and link_tag.get("href") else "N/A"
print(f"{title} — {href}")
Θα πάρεις ονόματα προϊόντων και URLs. Τιμές; Πιθανότατα όχι από αυτό το HTML. Αυτό είναι αναμενόμενο.
Βήμα 3: Εξαγωγή ενσωματωμένων JSON δεδομένων από τις σελίδες προϊόντων
Οι μεμονωμένες σελίδες προϊόντων ενσωματώνουν πλουσιότερα δεδομένα στο script tag __TGT_DATA__:
import re, json
product_url = "https://www.target.com/p/some-product/-/A-12345678"
resp = cureq.get(product_url, headers=headers, impersonate="chrome124")
soup = BeautifulSoup(resp.text, "html.parser")
# Βρες το script __TGT_DATA__
scripts = soup.find_all("script")
for script in scripts:
if script.string and "__TGT_DATA__" in script.string:
# Εξαγωγή JSON από το περιεχόμενο του script
match = re.search(r'__TGT_DATA__\s*=\s*({.*?});?\s*$', script.string, re.DOTALL)
if match:
tgt_data = json.loads(match.group(1))
# Πλοήγηση στη δομή JSON για τα στοιχεία του προϊόντος
queries = tgt_data.get("__PRELOADED_QUERIES__", {})
# Τα δεδομένα προϊόντος είναι εμφωλευμένα μέσα — η δομή αλλάζει ανά σελίδα
print(json.dumps(queries, indent=2)[:500]) # Προεπισκόπηση της δομής
Η δομή JSON μέσα στο __TGT_DATA__ περιέχει ονόματα προϊόντων, περιγραφές, χαρακτηριστικά και συχνά δεδομένα τιμών. Το ακριβές nesting διαφέρει, οπότε θα χρειαστεί να επιθεωρήσεις το output και να πλοηγηθείς ανάλογα.
Βήμα 4: Διαχείριση της σελιδοποίησης
Η pagination αναζήτησης του Target χρησιμοποιεί την παράμετρο Nao. Η σελίδα 1 είναι Nao=0, η σελίδα 2 είναι Nao=24, η σελίδα 3 είναι Nao=48 και ούτω καθεξής (με αύξηση ανά 24):
for page in range(0, 120, 24): # Πρώτες 5 σελίδες
paginated_url = f"https://www.target.com/s?searchTerm=bluetooth+headphones&Nao={page}"
resp = cureq.get(paginated_url, headers=headers, impersonate="chrome124")
# Ανάλυση και εξαγωγή...
time.sleep(random.uniform(2, 5)) # Να είσαι ευγενικός
Βήμα 5: Αποθήκευση των scraped δεδομένων σου
import csv
with open("target_products.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["title", "url", "price", "description"])
writer.writeheader()
for product in products:
writer.writerow(product)
Τι θα πάρεις: Τίτλους προϊόντων, URLs, περιγραφές και ενσωματωμένα metadata. Τι δεν θα πάρεις αξιόπιστα: Δυναμικές τιμές και αξιολογήσεις από τις σελίδες αποτελεσμάτων αναζήτησης. Για αυτά, χρειάζεσαι τη Μέθοδο 2 ή 3.
Μέθοδος 2: Scrape Target.com με Selenium ή Playwright
Ένας headless browser αποδίδει JavaScript, φορτώνει δυναμικό περιεχόμενο και προσομοιώνει πραγματική συμπεριφορά χρήστη. Αυτή είναι η μέθοδος που σου δίνει τιμές, αξιολογήσεις και κριτικές.
Στο ερώτημα Selenium vs. Playwright: το Playwright έχει ξεπεράσει το Selenium σε υιοθέτηση — 45.1% έναντι 22.1% το 2026 — και τα benchmarks δείχνουν ότι είναι 2.5x πιο γρήγορο (11s αντί 28s για 20 σελίδες). Θα δείξω Selenium εδώ επειδή έχει μεγαλύτερη κοινότητα και περισσότερα tutorials, αλλά το Playwright είναι η καλύτερη επιλογή αν ξεκινάς από την αρχή.
Βήμα 1: Εγκατάστησε Selenium και ChromeDriver
pip install selenium webdriver-manager
Το webdriver-manager χειρίζεται αυτόματα τις εκδόσεις του ChromeDriver — τέλος το άγχος «ChromeDriver version mismatch»:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1920,1080")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
Βήμα 2: Φόρτωσε σελίδες του Target και περίμενε το περιεχόμενο
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.get("https://www.target.com/s?searchTerm=bluetooth+headphones")
# Περίμενε να αποδοθούν οι κάρτες προϊόντων (explicit wait > time.sleep)
WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, '[data-test="product-title"]'))
)
Τα explicit waits είναι κρίσιμα. Το time.sleep(10) σπαταλά χρόνο σε γρήγορα φορτώματα και δεν αρκεί σε αργά — το χειρότερο και από τους δύο κόσμους. Το WebDriverWait κάνει polling κάθε 500ms μέχρι να εμφανιστεί το στοιχείο ή να λήξει το timeout.
Βήμα 3: Κάνε scroll στη σελίδα για να φορτώσουν όλα τα προϊόντα
Το Target φορτώνει προϊόντα σταδιακά όσο κάνεις scroll. Χωρίς scrolling, θα πάρεις 4–5 προϊόντα αντί για ολόκληρη τη σελίδα:
import time
last_height = driver.execute_script("return document.body.scrollHeight")
for _ in range(10):
driver.execute_script("window.scrollBy(0, 300);")
time.sleep(1.5)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
Οι δοκιμές του ScrapeOps επιβεβαιώνουν ότι 10 επαναλήψεις scroll με καθυστέρηση 1.5 δευτερολέπτου δίνουν 8+ προϊόντα αντί για 4–5 χωρίς scrolling. Κάθε βήμα scroll θα πρέπει να είναι 200–300px ώστε να μιμείται ανθρώπινη συμπεριφορά.
Βήμα 4: Εξαγωγή δεδομένων προϊόντων από τη σελίδα που αποδόθηκε
products = []
cards = driver.find_elements(By.CSS_SELECTOR, '[data-test="@web/site-top-of-funnel/ProductCardWrapper"]')
for card in cards:
try:
title = card.find_element(By.CSS_SELECTOR, '[data-test="product-title"]').text
except:
title = "N/A"
try:
price = card.find_element(By.CSS_SELECTOR, '[data-test="current-price"]').text
except:
price = "N/A"
try:
link = card.find_element(By.CSS_SELECTOR, 'a[href*="/p/"]').get_attribute("href")
except:
link = "N/A"
products.append({"title": title, "price": price, "link": link})
for p in products:
print(f'{p["title"]} — {p["price"]}')
Βασικοί data-test selectors για το Target (επιβεβαιωμένοι το 2026):
| Πεδίο δεδομένων | Selector |
|---|---|
| Κάρτα προϊόντος | data-test="@web/site-top-of-funnel/ProductCardWrapper" |
| Τίτλος προϊόντος | data-test="product-title" |
| Τρέχουσα τιμή | data-test="current-price" |
| Βαθμολογία | data-test="rating-value" |
| Αριθμός αξιολογήσεων | data-test="rating-count" |
Βήμα 5: Εξαγωγή κριτικών προϊόντος (bonus)
Πήγαινε σε μεμονωμένες σελίδες προϊόντων, κάνε scroll μέχρι την ενότητα κριτικών και εξήγαγε τα δεδομένα των reviews:
from bs4 import BeautifulSoup
driver.get("https://www.target.com/p/some-product/-/A-12345678")
# Κάνε scroll προς τα κάτω για να φορτώσουν οι κριτικές
for _ in range(5):
driver.execute_script("window.scrollBy(0, 500);")
time.sleep(2)
soup = BeautifulSoup(driver.page_source, "html.parser")
reviews = soup.find_all("div", {"data-test": "review-card--text"})
for review in reviews:
print(review.get_text(strip=True)[:100])
Οι κριτικές φορτώνονται μέσω Bazaarvoice integration και υποστηρίζουν σελιδοποίηση (έως 51 σελίδες), ταξινόμηση ανά χρονική σειρά και φίλτρο μόνο με φωτογραφίες. Τα benchmarks του ScrapeOps δείχνουν περίπου 5.1 δευτερόλεπτα ανά στοιχείο με Selenium.
Μην ξεχάσεις να κλείσεις τον browser όταν τελειώσεις:
driver.quit()
Μέθοδος 3: Scrape Target.com χρησιμοποιώντας το Redsky API
Το frontend του Target τραβά όλα τα δεδομένα από ένα εσωτερικό API στο redsky.target.com. Μπορείς να το καλέσεις απευθείας με Python — χωρίς parsing HTML, χωρίς browser, χωρίς rendering JavaScript. Η απάντηση είναι καθαρό JSON με 40+ πεδία δεδομένων που καλύπτουν τιμολόγηση, αξιολογήσεις, κριτικές, εικόνες, διαθεσιμότητα, fulfillment, specs και variants. Για μαζικά δεδομένα προϊόντων, αυτή είναι με διαφορά η πιο γρήγορη και αξιόπιστη μέθοδος.
Βήμα 1: Εντόπισε το Redsky API με το Chrome DevTools
Τα περισσότερα tutorials προσπερνούν εντελώς αυτό το σημείο. Δες πώς θα βρεις μόνος σου το API:
- Άνοιξε οποιαδήποτε σελίδα προϊόντος του Target στο Chrome
- Άνοιξε το DevTools (F12) → καρτέλα Network
- Φίλτραρε με Fetch/XHR
- Κάνε reload τη σελίδα
- Ψάξε για requests προς
redsky.target.comήredsky.a]target.com - Κάνε κλικ σε ένα — εξέτασε το Request URL και τα Headers
Θα δεις κάτι σαν:
https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key=9f36aeafbe60771e321a7cc95a78140772ab3e96&tcin=12345678&store_id=2148&zip=55401
Τα βασικά parameters:
key— API key (στατικό, όχι rotating — διαφορετικά endpoints χρησιμοποιούν διαφορετικά keys)tcin— Target.com Item Number (το 8ψήφιο product ID)store_id— τοποθεσία καταστήματος Targetzip— ZIP code για fulfillment data
Εξήγαγε το API key από τα request headers. Είναι ενσωματωμένο στο URL ως query parameter.
Βήμα 2: Κάνε απευθείας Python request στο Redsky API
from curl_cffi import requests as cureq
import json
API_KEY = "9f36aeafbe60771e321a7cc95a78140772ab3e96" # Εξαγωγή από DevTools
TCIN = "12345678"
url = f"https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key={API_KEY}&tcin={TCIN}&store_id=2148&zip=55401"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept": "application/json",
"Origin": "https://www.target.com",
"Referer": "https://www.target.com/",
"Sec-Fetch-Site": "same-site",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
}
resp = cureq.get(url, headers=headers, impersonate="chrome124")
data = resp.json()
# Εξαγωγή στοιχείων προϊόντος από το JSON response
product = data.get("data", {}).get("product", {})
title = product.get("item", {}).get("product_description", {}).get("title", "N/A")
price = product.get("price", {}).get("formatted_current_price", "N/A")
rating = product.get("ratings_and_reviews", {}).get("statistics", {}).get("rating", {}).get("average", "N/A")
print(f"{title} — {price} — Βαθμολογία: {rating}")
Δεν χρειάζεται parsing HTML. Η απάντηση είναι δομημένη, καθαρή και γρήγορη.
Βήμα 3: Κάνε scrape τα αποτελέσματα αναζήτησης προϊόντων μέσω του API
Το endpoint product_summary_with_fulfillment_v1 δέχεται πολλαπλά TCINs ταυτόχρονα:
tcins = ["12345678", "23456789", "34567890"]
tcin_str = ",".join(tcins)
search_url = f"https://redsky.target.com/redsky_aggregations/v1/web/product_summary_with_fulfillment_v1?key={API_KEY}&tcins={tcin_str}&store_id=2148&zip=55401"
resp = cureq.get(search_url, headers=headers, impersonate="chrome124")
results = resp.json()
for item in results.get("data", {}).get("product_summaries", []):
title = item.get("title", "N/A")
price = item.get("price", {}).get("formatted_current_price", "N/A")
print(f"{title} — {price}")
Για να πάρεις TCINs, μπορείς είτε να τα εξαγάγεις από το HTML της σελίδας αναζήτησης (εμφανίζονται στα URLs των προϊόντων ως /A-XXXXXXXX) είτε από το ενσωματωμένο JSON του __TGT_DATA__.
Βήμα 4: Κλιμάκωσε με ταυτόχρονες αιτήσεις
from concurrent.futures import ThreadPoolExecutor
import time, random
def fetch_product(tcin):
url = f"https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key={API_KEY}&tcin={tcin}&store_id=2148&zip=55401"
time.sleep(random.uniform(2, 5))
resp = cureq.get(url, headers=headers, impersonate="chrome124")
return resp.json()
tcin_list = ["12345678", "23456789", "34567890", "45678901"]
with ThreadPoolExecutor(max_workers=3) as executor:
results = list(executor.map(fetch_product, tcin_list))
Κράτα τη concurrency συντηρητική — 3–5 threads με τυχαίες καθυστερήσεις 2–5 δευτερολέπτων. Το rate limit του Target βρίσκεται περίπου στα 30–60 requests ανά λεπτό ανά IP.
Σημαντικές επιφυλάξεις για το Redsky API
Πριν χτίσεις production pipeline πάνω σε αυτό, λίγες επιφυλάξεις:
- Τα API keys είναι στατικά αλλά endpoint-specific. Διαφορετικά Redsky endpoints χρησιμοποιούν διαφορετικά keys. Δεν αλλάζουν συχνά, αλλά το Target μπορεί να τα αλλάξει οποιαδήποτε στιγμή.
- Πρόκειται για undocumented internal API. Η engineering ομάδα του Target έχει επιβεβαιώσει ότι είναι σκόπιμα δημόσιο-facing, κάτι που μειώνει τον νομικό κίνδυνο, αλλά δεν είναι υποστηριζόμενο δημόσιο API με SLAs.
- Τα product variants (χρώματα, μεγέθη) έχουν το καθένα μοναδικά TCINs. Πρέπει να κάνεις query για κάθε variant ξεχωριστά.
- Η έλλειψη
Sec-Fetch-*headers προκαλεί άμεσο μπλοκάρισμα. Αυτό είναι συχνό παγίδι — να περιλαμβάνεις πάνταSec-Fetch-Site,Sec-Fetch-ModeκαιSec-Fetch-Dest.
Συμβουλές για scraping του Target.com σε μεγάλη κλίμακα χωρίς μπλοκάρισμα
Αυτές οι πρακτικές ισχύουν σε production κλίμακα, ανεξάρτητα από τη μέθοδο.
Κάνε rotate residential proxies (όχι datacenter)
Η υλοποίηση της Akamai στο Target σημαδεύει τα datacenter IP ranges με το που τα δει. Τα residential proxies είναι υποχρεωτικά για sustained scraping. Οι τιμές διαφέρουν πολύ — το Smartproxy/Decodo ξεκινά από $4.50/GB, το Bright Data από $5.04/GB, και πέφτουν στα $3–4/GB σε υψηλό όγκο.
Κάνε rotate IPs κάθε 50–100 requests ή σε κάθε request αν το proxy pool σου το υποστηρίζει.
Πλαστογράφησε τα TLS fingerprints με curl_cffi
Αυτή είναι η αλλαγή με τη μεγαλύτερη επίδραση. Drop-in replacement για το requests:
from curl_cffi import requests as cureq
# Standard requests — 12% success rate σε προστατευμένα sites
# resp = requests.get(url, headers=headers)
# curl_cffi — 92% success rate
resp = cureq.get(url, headers=headers, impersonate="chrome124")
Το curl_cffi (8,200+ GitHub stars) υποστηρίζει εκδόσεις Chrome από chrome99 έως chrome146, καθώς και Safari, Edge και mobile variants. Είναι 20–30% πιο γρήγορο από το tls_client σε synchronous mode.
Ρύθμισε ρεαλιστικό ρυθμό αιτήσεων και headers
- Τυχαίες καθυστερήσεις: 2–7 δευτερόλεπτα ανάμεσα στα requests (όχι σταθερό διάστημα — η τυχαιότητα μετράει)
- Rotate User-Agent: Κράτα μια δεξαμενή από 5–10 πραγματικά browser User-Agent strings και κάνε rotate
- Session warmup: Επισκέψου πρώτα την αρχική σελίδα του
target.comπριν πας στις σελίδες προϊόντων, για να δημιουργηθούν cookies - Συνέπεια στα headers: Το
Sec-Ch-Uaπρέπει να ταιριάζει με την έκδοση browser που δηλώνει το User-Agent. ΤοSec-Ch-Ua-Platformπρέπει να ταιριάζει με το OS που δηλώνεις. Οι ασυνέπειες προδίδουν αμέσως το bot. - Διατήρηση session: Κράτα cookies ανά request μέσα στο ίδιο session. Το Scraperly προτείνει σταθερότητα session 48 ωρών με rotating residential proxies.
Παράκαμψε το code: Scrape Target.com με Thunderbit (no-code εναλλακτική)
Το Target.com είναι, ειλικρινά, από τα πιο δύσκολα retail sites για programmatic scraping. JavaScript rendering, TLS fingerprinting της Akamai, ανίχνευση datacenter proxies, πονοκέφαλοι με εκδόσεις ChromeDriver — είναι πολλά κινούμενα μέρη. Αν μαθαίνεις Python, είναι εξαιρετική άσκηση. Αν χρειάζεσαι δεδομένα προϊόντων Target για πραγματική δουλειά, το cost-benefit συχνά δεν βγαίνει.
Για αναγνώστες που χρειάζονται τα δεδομένα χωρίς το engineering project, το Thunderbit αναλαμβάνει αυτόματα τα δύσκολα κομμάτια.
Πώς το Thunderbit χειρίζεται τις προκλήσεις του Target.com
Το Thunderbit AI Web Scraper τρέχει μέσα στον browser σου, πράγμα που σημαίνει ότι αποδίδει φυσικά το JavaScript — χωρίς ρύθμιση Selenium, χωρίς headless browser configuration, χωρίς versioning του ChromeDriver. Ο browser είναι ο scraper.
Το workflow είναι το εξής:
- Εγκατέστησε το Thunderbit Chrome Extension και πήγαινε σε σελίδα προϊόντος ή αναζήτησης του Target
- Κάνε κλικ στο "AI Suggest Fields" — το Thunderbit διαβάζει τη σελίδα και προτείνει ονόματα στηλών (Product Title, Price, Rating, Image URL κ.λπ.)
- Κάνε κλικ στο "Scrape" — τα δεδομένα εξάγονται σε δευτερόλεπτα, απευθείας από τη σελίδα που αποδόθηκε
Χωρίς proxies να ρυθμίσεις. Χωρίς TLS fingerprints να πλαστογραφήσεις. Χωρίς αποτελέσματα None.
Κάνε scrape τις λίστες προϊόντων και τις σελίδες λεπτομερειών του Target
Η multi-page ροή είναι εκεί όπου τα πράγματα γίνονται ενδιαφέροντα. Κάνε scrape μια σελίδα αποτελεσμάτων αναζήτησης του Target για να πάρεις λίστα προϊόντων και μετά χρησιμοποίησε το Subpage Scraping για να επισκεφθείς αυτόματα κάθε URL προϊόντος και να εμπλουτίσεις τον πίνακά σου με δεδομένα από τη σελίδα λεπτομερειών — περιγραφές, πλήρεις κριτικές, προδιαγραφές — χωρίς να γράψεις code σελιδοποίησης ή να διαχειριστείς browser sessions.
Εξαγωγή απευθείας σε Excel, Google Sheets, Airtable ή Notion. Χωρίς boilerplate csv.writer, χωρίς προβλήματα κωδικοποίησης αρχείων.
Αυτοματοποίησε επαναλαμβανόμενα Target.com scrapes
Για συνεχή παρακολούθηση τιμών ή αποθέματος, το Scheduled Scraper του Thunderbit σου επιτρέπει να περιγράψεις το πρόγραμμα σε απλή γλώσσα (π.χ. «κάθε Δευτέρα στις 9 π.μ.»). Χωρίς cron jobs, χωρίς setup server, χωρίς να κρατάς ένα Python script ζωντανό σε VPS. Αυτό είναι ιδιαίτερα χρήσιμο για ecommerce ομάδες που παρακολουθούν τιμολόγηση ανταγωνιστών — το 81% των retailers στις ΗΠΑ χρησιμοποιεί πλέον αυτοματοποιημένο price scraping και το ROI της price intelligence φτάνει κατά μέσο όρο το 27:1.
Πότε να χρησιμοποιήσεις ποια μέθοδο για να κάνεις scrape το Target.com με Python
Ορίστε ένα γρήγορο πλαίσιο απόφασης:
| Η περίπτωσή σου | Προτεινόμενη μέθοδος |
|---|---|
| Μαθαίνεις Python, μικρό project | Μέθοδος 1: Requests + BS4 (για static data και __TGT_DATA__) |
| Χρειάζεσαι πλήρεις σελίδες προϊόντων με τιμές και κριτικές | Μέθοδος 2: Selenium / Playwright |
| Μαζική εξαγωγή δεδομένων προϊόντων σε κλίμακα | Μέθοδος 3: Redsky API |
| Χρειάζεσαι δεδομένα γρήγορα χωρίς να γράψεις code | Thunderbit (no-code) |
| Επαναλαμβανόμενη παρακολούθηση τιμών | Thunderbit Scheduled Scraper ή Redsky API + cron |
| Ερευνητικό project μιας χρήσης, μη τεχνική ομάδα | Thunderbit — ειλικρινά, η πιο γρήγορη διαδρομή |
Αν χτίζεις production data pipeline, η Μέθοδος 3 (Redsky API) σου δίνει την καλύτερη ταχύτητα και αξιοπιστία. Αν κάνεις one-off έρευνα ή η ομάδα σου δεν έχει Python expertise, το Thunderbit σε γλιτώνει ώρες. Και αν μαθαίνεις web scraping, η πορεία Μέθοδος 1 → Μέθοδος 2 → Μέθοδος 3 είναι μια φυσική εξέλιξη που σου μαθαίνει κάτι αληθινό σε κάθε βήμα.
Νομικές και ηθικές σκέψεις όταν κάνεις scrape το Target.com
Αξίζει να το καλύψουμε σύντομα. Το robots.txt του Target έχει περίπου 120+ Disallow paths αλλά αξιοσημείωτα δεν μπλοκάρει τα /p/ (προϊόντα) ή /c/ (κατηγορίες) — οι σελίδες προϊόντων και κατηγοριών επιτρέπονται ρητά για crawling. Οι σελίδες cart, account και checkout είναι περιορισμένες.
Οι Όροι Χρήσης του Target απαγορεύουν το automated access. Ωστόσο, το γεγονός ότι το Redsky API είναι σκόπιμα δημόσιο-facing (όπως επιβεβαιώνει η engineering ομάδα του Target) μειώνει τον νομικό κίνδυνο για συλλογή δεδομένων μέσω API.
Βασικά νομικά προηγούμενα που πρέπει να γνωρίζεις:
- hiQ κατά LinkedIn (Νοτιοδυτικό Εφετείο των ΗΠΑ, 2022): το scraping δημόσια διαθέσιμων δεδομένων δεν παραβιάζει τον CFAA
- Meta κατά Bright Data (2024): η Meta έχασε — το δικαστήριο έκρινε ότι δεν υπήρξε παραβίαση CFAA για scraping δημόσιων δεδομένων
Για εμπορικό scraping μεγάλης κλίμακας, συμβουλέψου νομικό. Για market research, σύγκριση τιμών και προσωπικά projects που χρησιμοποιούν δημόσια διαθέσιμα δεδομένα, βρίσκεσαι σε ισχυρό έδαφος. Σεβάσου πάντα τα rate limits και μην υπερφορτώνεις τους servers του Target.
Συμπέρασμα και βασικά σημεία
Το Target.com κερδίζει τη φήμη του ως δύσκολο site. Η αφελής προσέγγιση Requests + BeautifulSoup αποτυγχάνει επειδή το Target αποδίδει τα δεδομένα προϊόντων μέσω JavaScript και η Akamai fingerprintάρει το TLS handshake σου πριν καν πάρεις απάντηση. Με τη σωστή μέθοδο όμως, η εξαγωγή δεδομένων είναι απλή.
Οι τρεις μέθοδοι, με σειρά αξιοπιστίας:
- Redsky API — η πιο γρήγορη και αξιόπιστη για μαζικά δεδομένα, επιστρέφει καθαρό JSON. Απαιτεί reverse-engineering των API endpoints μέσω DevTools.
- Selenium / Playwright — χειρίζεται JavaScript rendering και σου δίνει ό,τι υπάρχει στη σελίδα. Πιο αργό αλλά πλήρες.
- Requests + BeautifulSoup — περιορίζεται σε static HTML και στο ενσωματωμένο JSON
__TGT_DATA__. Γρήγορο αλλά ελλιπές.
Τα μεγαλύτερα τεχνικά κέρδη:
- Χρησιμοποίησε
curl_cffiαντί για standardrequestsγια 15x βελτίωση στο anti-bot evasion - Τα residential proxies είναι υποχρεωτικά — τα datacenter IPs σημαδεύονται αμέσως
- Βάλε
Sec-Fetch-*headers σε κάθε request — αν λείπουν, το μπλοκάρισμα είναι άμεσο - Το session warmup (πρώτα επίσκεψη στην αρχική σελίδα) βελτιώνει σημαντικά τα success rates
Και αν η Python δεν αξίζει τον κόπο για τη δική σου χρήση, η Chrome extension του Thunderbit χειρίζεται αυτόματα το JavaScript rendering, τα anti-bot μέτρα και την εξαγωγή δεδομένων. Δοκίμασε το free tier και δες αν σου δίνει αυτό που χρειάζεσαι σε λεπτά αντί για ώρες.
Για περισσότερους οδηγούς scraping και συμβουλές εξαγωγής δεδομένων, δες το Thunderbit blog ή το κανάλι μας στο YouTube.
Συχνές ερωτήσεις
Μπορώ να κάνω scrape το Target.com μόνο με Python Requests και BeautifulSoup;
Μερικώς. Μπορείς να εξαγάγεις τίτλους προϊόντων, URLs και κάποια ενσωματωμένα JSON δεδομένα από τα script tags __TGT_DATA__ στις σελίδες προϊόντων. Όμως οι τιμές, οι αξιολογήσεις, οι κριτικές και η διαθεσιμότητα στις σελίδες αποτελεσμάτων αναζήτησης αποδίδονται με JavaScript και δεν θα εμφανιστούν με στατικά HTTP requests. Για πλήρη δεδομένα, χρησιμοποίησε Selenium/Playwright ή το Redsky API.
Γιατί το Target.com scraper μου επιστρέφει None για τις τιμές;
Το Target φορτώνει τα δεδομένα τιμολόγησης μέσω JavaScript μετά το αρχικό φόρτωμα της σελίδας. Όταν χρησιμοποιείς requests.get(), λαμβάνεις το pre-rendered HTML shell — πριν εκτελεστεί το JavaScript και εισαχθούν τα δεδομένα προϊόντος στο DOM. Τα στοιχεία της τιμής κυριολεκτικά δεν υπάρχουν στην απάντηση. Χρησιμοποίησε έναν headless browser (Selenium ή Playwright) που αποδίδει JavaScript, κάλεσε απευθείας το Redsky API για JSON δεδομένα ή χρησιμοποίησε ένα εργαλείο όπως το Thunderbit που κάνει scrape από τη σελίδα του browser αφού αποδοθεί.
Είναι νόμιμο να κάνω scrape το Target.com;
Η εξαγωγή δημόσια διαθέσιμων δεδομένων γενικά επιτρέπεται με βάση την τρέχουσα νομολογία στις ΗΠΑ (hiQ κατά LinkedIn, Meta κατά Bright Data). Το robots.txt του Target επιτρέπει crawling στις σελίδες προϊόντων και κατηγοριών. Ωστόσο, οι Όροι Χρήσης του Target απαγορεύουν το automated access, οπότε υπάρχει μια γκρίζα ζώνη. Για market research και σύγκριση τιμών με δημόσια δεδομένα, βρίσκεσαι σε λογικά ασφαλές νομικό έδαφος. Για εμπορικές λειτουργίες μεγάλης κλίμακας, συμβουλέψου δικηγόρο.
Τι είναι το Redsky API του Target και πώς το προσπελαύνω;
Το Redsky είναι το εσωτερικό API του Target που τροφοδοτεί τα δεδομένα προϊόντων στο frontend. Δεν είναι δημόσιο API με τεκμηρίωση και signup για API keys — είναι το backend στο οποίο καλεί η React εφαρμογή τους για να αποδώσει τις σελίδες προϊόντων. Μπορείς να εντοπίσεις τα endpoints του ανοίγοντας το Chrome DevTools, φιλτράροντας την καρτέλα Network σε XHR/Fetch και ψάχνοντας requests προς redsky.target.com. Το API key είναι ενσωματωμένο στο request URL ως query parameter. Η engineering ομάδα του Target έχει επιβεβαιώσει ότι το API είναι σκόπιμα δημόσιο-facing.
Πώς αποφεύγω να μπλοκαριστώ όταν κάνω scrape το Target.com;
Η πιο επιδραστική μεμονωμένη αλλαγή είναι να χρησιμοποιήσεις curl_cffi αντί για standard Python requests ώστε να πλαστογραφήσεις browser TLS fingerprints — αυτό μόνο του ανεβάζει τα success rates από 12% σε 92%. Πέρα από αυτό: χρησιμοποίησε residential proxies (όχι datacenter), κάνε rotate User-Agent strings, βάλε τυχαίες καθυστερήσεις 2–7 δευτερολέπτων ανάμεσα στα requests, συμπερίλαβε όλα τα Sec-Fetch-* headers και κάνε warm up τα sessions επισκεπτόμενος πρώτα την αρχική σελίδα. Εναλλακτικά, χρησιμοποίησε ένα εργαλείο όπως το Thunderbit που χειρίζεται αυτόματα τα anti-bot μέτρα χωρίς καμία ρύθμιση.
Μάθε περισσότερα


