Puppeteerissa tuttu vikatilanne menee usein näin: ensimmäiset pyynnöt onnistuvat, mutta myöhemmät alkavat palauttaa 403- tai 429-virhettä, aikakatkaistuvat tai ohjautuvat haastesivulle. Silti monet oppaat käsittelevät pyöriviä proxyeja kuin kyse olisi vain kahden rivin asetuksesta.
Ei ole. Ero esimerkin "lisää --proxy-server-lippu" ja oikeasti ylläpidettävän järjestelmän välillä on valtava. Tässä oppaassa käydään läpi koko selaimen kattava kierrätys, todennetut gatewayt, selainten jakaminen tai ulkoiset välityspalvelimet, yhtenäiset selainprofiilit, tuotantotason virheenkäsittely sekä rehellinen vastaus siihen, milloin proxyeja ei kannata hallita itse lainkaan.
Mikä on pyörivä proxy ja miksi Puppeteer tarvitsee sellaisen?
Proxy toimii välikätenä Puppeteer-instanssisi ja kohdesivuston välillä. Sivusto näkee proxyn poistuvan IP-osoitteen, ei sinun konettasi. Pyörivä proxy vaihtaa näitä poistumis-IP-osoitteita poolista — joskus jokaisen pyynnön, joskus istunnon mukaan — jotta liikenne ei näytä yhdeltä asiakkaalta, joka hakkaa palvelinta tuhat kertaa peräkkäin.
Puppeteer tarvitsee tätä erityisesti siksi, että headless-Chromen tekemät sadat peräkkäiset pyynnöt yhdestä IP:stä ovat juuri se kuvio, jonka estojärjestelmät on rakennettu tunnistamaan. Cloudflaren oma dokumentaatio kuvaa useita samanaikaisia tunnistuskerroksia — heuristiikkaa, JavaScript-sormenjälkien tarkistusta, koneoppimismalleja ja käyttäytymisen poikkeamien analysointia. Pyörivä IP ratkaisee näistä vain yhden. Vain yhden.
On kolme proxylajia, jotka kannattaa tuntea, eikä niitä voi käyttää ristiin ihan miten tahansa:
- Datacenter-proxyt — edullisia, nopeita ja hosting-palveluntarjoajilta peräisin. Kohteiden on helppo liputtaa ne, koska ASN (verkkolohko) paljastaa ne datakeskukseksi, ei kotiliittymäksi.
- Residential-proxyt — kulkevat oikeiden kuluttajaliittymien kautta, joten ne näyttävät aidommilta kotiyhteyksiltä. Hitaampia ja kalliimpia, mutta paljon uskottavampia.
- Mobiiliproxyt — operaattoriverkon IP-osoitteita, yleensä kallein vaihtoehto ja hyödyllinen silloin, kun mobiiliverkkomainen identiteetti on aidosti tarpeen.
Residential-poistumispisteet voivat ASN-luokituksessa näyttää vähemmän ilmeisiltä kuin datacenter-poistumiset, mutta kumpikaan ryhmä ei ole immuuni estolle. Mitään yleispätevää tunnistustasoa ei ole: lopputulos riippuu kohteesta, poistumisosoitteen maineesta, sijainnista, istuntohistoriasta, selainprofiilista ja pyyntöjen käyttäytymisestä.
Yksi lisäero sekoittaa monia: itse hallitsemasi staattinen lista (sinä ylläpidät poolia, valitset seuraavan IP:n ja käsittelet virheet) ei ole sama asia kuin backconnect/gateway-proxy (sinä käytät yhtä päätepistettä, ja palveluntarjoaja vaihtaa poistumisosoitteita taustalla). Molemmat toimivat; ero on vain siinä, missä monimutkaisuus asuu.
Miksi pyörivät proxyt kannattaa asentaa Puppeteerissa? Tavallisimmat käyttötapaukset
Rehellinen vastaus on: et todennäköisesti tarvitse kierrätystä ennen kuin tarvitset, ja kun tarvitset, tarvitset sitä kunnolla.
| Käyttötapaus | Miksi kierrätys on tärkeää |
|---|---|
| Hintaseuranta tuotekatalogeissa | Toistuvat katalogipyynnöt yhdestä IP:stä kasvattavat rate limit -rajojen ja maineen perusteella tehtyjen estojen riskiä |
| Liidien rikastus / yhteystietojen poiminta | Toistuvat profiilikäynnit yhdestä IP:stä näyttävät scrapaamiselta, eivät selaamiselta, ja käyttäytymismallit liputtavat ne |
| SERP-scraping | Hakukoneet rajoittavat IP-pohjaista liikennettä ja CAPTCHA-esteitä kaikkein aggressiivisimmin |
| Kilpailijaseuranta | Saman domainin jatkuva haku päivien ajan luo sormenjäljen, joka liittyy IP:hen ja evästehistoriaasi |
| Sisällön aggregointi | Paljon sivuja, vähän arvoa per sivu — juuri sellaista liikennettä bot-tunnistus on viritetty havaitsemaan |
Mikään sivusto ei julkaise pysyvää nyrkkisääntöä kuten "Amazon blokkaa pyynnön 51 jälkeen". Sivustot eivät kerro yleisiä raja-arvoja julkisesti, ja kontrollit voivat muuttua endpointin, tilin tilan, ASN-maineen ja liikennemallin mukaan. Aloita pienimmällä sallitulla pyyntinopeudella, validoi sisältö myös statuskoodien lisäksi ja lisää kierrätystä vasta, kun mitattu käyttäytyminen ja kohteen säännöt sitä oikeasti edellyttävät.
Kolme proxy-kierrätysstrategiaa Puppeteerissa: minkä tarvitset?

Tämä on se osa, jonka useimmat oppaat ohittavat kokonaan — tai näyttävät vain karkean, yksinkertaisimman version. Granulariteettitasoja on kolme, ja väärän valitseminen joko tuhlaa aikaa tai tekee yksinkertaisesta työstä tarpeettoman monimutkaisen.
| Kierrätysstrategia | Tarkkuustaso | Tarvitaanko selaimen uudelleenkäynnistys? | Monimutkaisuus | Sopii parhaiten |
|---|---|---|---|---|
Per-selain (--proxy-server) | 1 proxy per selaininstanssi | Kyllä | Matala | Yksinkertaiset, vähävolyymiset scrapat |
Gateway-hallittu (proxy-chain + backconnect-endpoint) | Tarjoajan / istunnon politiikka | Ei | Keskitaso | Todennetut kierrättävät gatewayt |
| Selainten jakaminen tai ulkoinen relay | 1 proxy per selainpalikka tai relay-sääntö | Ei yhtä prosessissa tapahtuvaa vaihtoa | Korkea | Hallittu rinnakkaisuus ja tarkka reititys |
Pieni huomio ennen valintaa: Puppeteerin omat verkko-interception-dokumentit ovat selkeitä siitä, että setRequestInterception ei ole siisti "vaihda proxy jokaiselle pyynnölle" -kytkin — jokainen keskeytetty pyyntö odottaa, kunnes jatkat, vastaat tai perut sen erikseen. Oikea per-pyyntö-reititys tarkoittaa yleensä pyyntöjen ajamista paikallisen ohjelmoitavan gatewayn, kuten proxy-chainin, läpi, ei proxyjen säätämistä suoraan interception-käsittelijässä. Pidä tämä mielessä ennen kuin sitoudut alla olevaan menetelmään 3.
Näin asetat pyörivät proxyt Puppeteerissa: vaiheittainen opas
Vaativuustaso: Keskitaso
Aika: noin 30–45 minuuttia kaikkiin kolmeen menetelmään
Tarvitset: Node.js 18+, npm, proxy-listan tai tarjoajatilin (muoto: protocol://user:pass@host:port) sekä paketit puppeteer, proxy-chain ja puppeteer-extra
Esivaatimukset: mitä tarvitset ennen aloittamista
Asenna peruspaketit:
npm install puppeteer proxy-chain puppeteer-extra puppeteer-extra-plugin-stealth
Hanki proxy-lista palveluntarjoajalta (residential on suositeltava kaikkeen muuhun kuin satunnaiseen testaukseen) tai vähintään muutama testiproxy, joilla voit varmistaa koodin toiminnan ennen kuin alat käyttää oikeaa request-volyymia. Säilytä tunnistetiedot ympäristömuuttujissa — älä koskaan kovakoodaa niitä äläkä laita niitä URL-osoitteeseen, joka päätyy lokiin.
Menetelmä 1: Per-selain proxy-kierrätys --proxy-server-lipulla
Tämä on perusmalli, josta kaikki aloittavat, ja syystä — se on ennustettava. Puppeteerin LaunchOptions-dokumentaatio kuvaa args-kentän tuetuksi tavaksi välittää Chromen komentorivilippuja, ja --proxy-server on Chromiumin natiivi lippu.
import puppeteer from 'puppeteer';
const proxyPool = [
'http://proxy1.example:8080',
'http://proxy2.example:8080',
'http://proxy3.example:8080',
];
let proxyIndex = 0;
async function scrapeWithRotation(url) {
const proxy = proxyPool[proxyIndex % proxyPool.length];
proxyIndex++;
const browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${proxy}`],
});
const page = await browser.newPage();
// Jos proxysi vaatii tunnistautumista, tämän täytyy tapahtua ennen ensimmäistä navigointia
await page.authenticate({
username: process.env.PROXY_USER,
password: process.env.PROXY_PASS,
});
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
const content = await page.content();
await browser.close(); // sulje ennen kuin vaihdat proxyyn
return content;
}
Huomaa, että page.authenticate() kytkee Puppeteerin omien dokumenttien mukaan hiljaisesti request interceptionin taustalla — se on pieni suorituskykymaksu, joka kannattaa tiedostaa, jos alat ihmetellä miksi kaikki tuntuu hitaammalta kuin odotit.
Odote: jokainen kutsu käynnistää uuden selaimen, joka on sidottu eri proxyyn. Kierrättääksesi proxyä suljet selaimen ja avaat sen uudelleen — startup-overheadia ei voi kiertää. 50 sivun scrappauksessa tämä on käytännössä selvästi hitaampi kuin kaksi muuta menetelmää, puhtaasti selaimen käynnistysajan vuoksi.
Milloin käyttää: matalan rinnakkaisuuden skriptit, kertaluonteiset scrapat, tilanteet joissa yksinkertainen debuggaus on tärkeämpää kuin nopeus.
Menetelmä 2: Todennettu kierrättävä gateway proxy-chain-kirjastolla
Chrome ei hyväksy proxy-URL:iin upotettuja user:pass@host-tunnuksia. proxy-chain -paketti (Apifyn ylläpitämä) ratkaisee tämän ongelman luomalla paikallisen anonyymin proxyn, joka välittää liikenteen todennetulle upstreamille. Jos upstream on palveluntarjoajan kierrättävä tai backconnect-gateway, palveluntarjoaja vaihtaa poistumis-IP-osoitteita tämän yhden päätepisteen takana istuntopolitiikkansa mukaan. proxy-chain itse ei jaa eri proxyä jokaiselle olemassa olevalle Puppeteer-sivulle.
import puppeteer from 'puppeteer';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
async function scrapeThroughGateway(upstreamProxyUrl, targetUrl) {
const localProxy = await anonymizeProxy(upstreamProxyUrl);
let browser;
try {
browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${localProxy}`],
});
const page = await browser.newPage();
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
return await page.content();
} finally {
if (browser) await browser.close();
await closeAnonymizedProxy(localProxy, true); // siivoa aina
}
}
Tuo finally-lohko ei ole koriste — orvoksi jääneet paikalliset proxy-palvelimet vuotavat portteja, ja olen nähnyt scrapaajien syövän yön aikana hiljaa kaikki vapaat file descriptorit, koska anonymisoitua proxya ei koskaan suljettu. proxy-chain myös nostaa esiin tietyt virhekoodit (593 DNS-ongelmille, 594 connection refused -tilanteille, 597 autentikointivirheille), jotka ovat aidosti hyödyllisiä virheiden luokittelussa — palataan tähän myöhemmin.
Milloin käyttää: todennetut residential- tai datacenter-gatewayt, joissa kierrätys määräytyy tarjoajan endpointin tai session parametrien mukaan. Jos tarvitset useita kiinteitä proxy-identiteettejä samanaikaisesti, käytä erillisiä selainprosesseja (browser sharding) tai tarkoitukseen rakennettua ulkoista relayta; natiivissa Puppeteerissa ei ole tuettua per-sivun proxy-asetusta.
Menetelmä 3: Per-pyyntö-reititys vaatii ulkoisen relayn
Tämä on korkein granulariteettitaso — teoriassa jokainen sivun kuva, skripti ja API-kutsu voisi mennä eri poistumisosoitteen kautta. Käytännössä tämä on haurainta ja vähiten dokumentoitua, koska Puppeteerin request interception on suunniteltu pyyntöjen suodattamiseen ja muokkaamiseen, ei verkkoliikenteen vaihtamiseen jokaisen pyynnön kohdalla.
import puppeteer from 'puppeteer';
async function inspectRequests(url) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', async (request) => {
// Käytännössä oikea per-pyyntö-proxyjen vaihtaminen vaatii liikenteen ohjaamista
// paikallisen relayn (proxy-chain) kautta, ei selaimen kuljetuksen vaihtamista kesken lennon —
// Chrome ei tue sitä.
// Useimmat tuotantoympäristöt käyttävät tätä käsittelijää resurssityyppien
// suodattamiseen/perumiseen ja yhdistävät sen browser shardingiin tai gatewayhin.
if (['image', 'font', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
await page.goto(url, { waitUntil: 'networkidle2' });
await browser.close();
}
Rehellinen arvio: Puppeteerissa ei ole natiivisti mahdollista vaihtaa IP:tä aidosti jokaista pyyntöä kohden setRequestInterception()-metodilla. Jos tarvitset tuon tason tarkkuutta, reititä Chrome ohjelmoitavan ulkoisen relayn kautta tai käytä scrappaamiseen rakennettua frameworkia, joka perustuu proxy-istuntoihin. Useimmille projekteille yksi proxy per selainpalikka tai tarjoajan hallitsema kierrättävä gateway on helpompi operoida ja auditoida.
Koko anti-detection-pino: pelkkä pyörivä proxy ei riitä pitämään sinua ulos estolistalta
Yleinen valitus kuuluu: "Käytän proxyeja ja silti minut blokataan." IP-osoite on vain yksi signaaleista, joita moderni bottijärjestelmä voi arvioida. Jos kierrätät vain IP:tä ja kaikki muu pysyy epäjohdonmukaisena, lopputuloksena voi olla vielä vahvempi poikkeama. Selaimen väite olla Windows Chrome, vaikka sen client hints, aikavyöhyke tai locale kertovat muuta, on tästä hyvä esimerkki.
Kerros 1: Pyörivät residential-proxyt
Käsitelty yllä — residential-poistumispisteet ovat usein uskottavampia kuin datacenter-poistumiset, mutta mitään universaalia minimipoolin kokoa ei ole. Mitoita pooli mitatun request-volyymin, session pituuden, jäähdyttelyaikojen ja tarjoajan uudelleenkäyttökäytännön perusteella äläkä julkaise mielivaltaista IP-lukua.
Kerros 2: Stealth-plugin headless-Chromen jälkien peittämiseen
puppeteer-extra-plugin-stealth paikkaa joukon tunnettuja headless-merkkejä: navigator.webdriver, WebGL-vendor-tekstit, puuttuvat Chrome runtime -objektit ja muutamat muut CDP:n paljastamat vihjeet. Se on aidosti hyödyllinen yhteensopivuuskerros, mutta projektin oma README myöntää varsin rehellisesti, että kyse on kissa ja hiiri -leikistä eikä täydellinen suoja ole todennäköisesti mahdollinen. Ajattele sitä perustasona, ei takuuna.
Kerros 3: Yhtenäiset selainprofiilit ja järkevä rytmitys
User-agentin pitää olla sisäisesti linjassa kaiken muun kanssa, mitä selain ilmoittaa. Chromen User-Agent Client Hints paljastaa strukturoitua alustatietoa, joten käsin kirjoitettu user-agent voi olla ristiriidassa todellisen alustan kanssa. Suosi Chromen mukana tulevaa user agentia, pidä viewport, locale ja aikavyöhyke vakiona istunnon sisällä ja rytmitä pyynnöt maltillisesti sen sijaan, että keksit uuden sormenjäljen jokaiselle sivulle.
Tässä kaikki kolme kerrosta yhdistettynä yhdeksi launch-konfiguraatioksi:
import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain';
puppeteer.use(StealthPlugin());
function boundedDelay(minMs = 800, maxMs = 1800) {
return new Promise((r) => setTimeout(r, minMs + Math.random() * (maxMs - minMs)));
}
async function stableProfileScrape(targetUrl, upstreamProxy) {
const localProxy = await anonymizeProxy(upstreamProxy);
let browser;
try {
browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${localProxy}`, '--lang=en-US'],
});
const page = await browser.newPage();
await page.setViewport({ width: 1366, height: 768 });
await boundedDelay();
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
return await page.content();
} finally {
if (browser) await browser.close();
await closeAnonymizedProxy(localProxy, true);
}
}
Tämä on se kokonaisuus, jonka useimmat kilpailevat oppaat jättävät näyttämättä — proxy, stealth ja sormenjäljen satunnaistus yhdessä paikassa, valmiina kopioitavaksi ja mukautettavaksi.
Tuotantovalmiit virheenkäsittely ja proxyjen terveyden tarkistus

Useimmat oppaat pysähtyvät siihen, että onnistuva polku toimii. Oikeassa scrappauksessa epäonnistumisia tulee jatkuvasti — proxyt hajoavat, tunnukset vanhenevat, kohde rajoittaa nopeutta kesken ajon — eikä mikään näistä ratkea toivomalla parasta.
Uudelleenyrittäminen eksponentiaalisella backoffilla ja jitterillä
function backoffMs(attempt, base = 1000, cap = 30_000) {
const exponential = Math.min(cap, base * 2 ** attempt);
return Math.floor(exponential * (0.5 + Math.random() * 0.5)); // jitter estää thundering herd -ilmiön
}
async function withRetry(fn, maxRetries = 4) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries) throw err;
const delay = backoffMs(attempt);
console.warn(`Yritys ${attempt + 1} epäonnistui: ${err.message}. Uusi yritys ${delay} ms kuluttua`);
await new Promise((r) => setTimeout(r, delay));
}
}
}
Epäonnistuvien proxyjen automaattinen mustalistaus
const proxyStats = new Map(); // proxyUrl -> { success, failure }
function recordResult(proxyUrl, success) {
const stats = proxyStats.get(proxyUrl) || { success: 0, failure: 0 };
success ? stats.success++ : stats.failure++;
proxyStats.set(proxyUrl, stats);
}
function isHealthy(proxyUrl) {
const stats = proxyStats.get(proxyUrl);
if (!stats) return true;
const total = stats.success + stats.failure;
if (total < 5) return true; // ei vielä tarpeeksi dataa
return stats.failure / total < 0.5; // mustalistaa, jos epäonnistumisprosentti ylittää 50 %
}
function getHealthyProxy(pool) {
const healthy = pool.filter(isHealthy);
if (healthy.length === 0) throw new Error('Poolissa ei ole enää yhtään tervettä proxya');
return healthy[Math.floor(Math.random() * healthy.length)];
}
Seuraa virhetyyppiä, ei vain onnistui/epäonnistui -tilaa — 407 (väärät tunnukset) ja 429 (rate limit) vaativat täysin eri toimenpiteet. Proxyä, jonka autentikointi epäonnistuu, ei kannata hakata uusilla yrityksillä; oikea korjaus on tunnusten tarkistus, ei nopeampi kierrätys.
Yleisimmät pyörivien proxyjen virheet Puppeteerissa ja niiden ratkaisut
| Virhe | Todennäköinen syy | Korjaus |
|---|---|---|
ERR_PROXY_CONNECTION_FAILED | Proxy alhaalla tai tavoittamattomissa | Poista poolista, kokeile seuraavaa proxya |
407 Proxy Authentication Required | Väärät tunnukset tai tuettu autentikointi puuttuu | Tarkista page.authenticate()-tunnukset; käytä proxy-chain-kirjastoa URL:iin upotetulle authille |
TimeoutError | Hidas proxy tai kohteen estäminen | Nosta timeoutia; vaihda residential-proxyyn |
403 Forbidden | IP tai sormenjälki liputettu | Kierrätä proxy + ota stealth käyttöön + satunnaista UA |
ERR_TUNNEL_CONNECTION_FAILED | HTTPS-tunnelin ongelma | Tarkista CONNECT-metodin tuki; kokeile proxy-chain-paikallistunnelia |
Muutama asia, joka ei mahdu siististi taulukkoon: 200-statuskoodi ei tarkoita automaattisesti onnistumista. Pehmeät estot palauttavat usein täysin validin HTML-sivun — kirjautumisportin tai challenge-näkymän — normaalilla statuskoodilla, joten validoi itse sisältö, ei vain vastauskoodi. Ja kun jäät jumiin, Puppeteerin debuggausopas suosittelee ajamista headless: false -tilassa, slowMo-viiveen lisäämistä ja NODE_DEBUG="puppeteer:*"-asetusta yksityiskohtaisten protokollalokkien saamiseksi — mutta muista, että lokit voivat sisältää arkaluonteista pyyntödataa, joten älä jätä niitä pyörimään tuotantotunnuksilla.
Itse hallittu proxy-kierrätys vs. proxy-gateway vs. AI-extraction API
| Kriteeri | Itse hallittu listakierrätys | Backconnect-gateway (Bright Data, Oxylabs, Decodo) | AI Extraction API (Thunderbit) |
|---|---|---|---|
| Kustannus (pieni volyymi) | Matala–keskitaso | Keskitaso–korkea per GB | Matala (free tier, sitten yksikköperusteinen) |
| Luotettavuus | Riippuu health checkeistäsi | Korkea (tarjoajan hallitsema) | Korkea (hallittu infra) |
| Anti-detection | Itse tehtävä — rakennat itse | Osittainen (vain IP-kierrätys) | Sisäänrakennettu |
| Strukturoitu ulostulo | Ei (raakaa HTML:ää) | Ei (raakaa HTML:ää) | Kyllä (JSON skeeman mukaan) |
| Käyttöönottoaika | Tunteja | Minuutteja | Minuutteja |
| Hallinta | Täysi | Rajoittuu tarjoajan APIin | Rajoittuu skeemamalliin |
Nykyinen palveluntarjoajien hinnoittelu (tarkistettu 2026-08-07) antaa käsityksen gateway-vaihtoehdon kustannuskäyrästä: Bright Datan residential-hinnoittelu tarjoaa pay-as-you-go- ja volyymipaketteja, joiden kampanjat voivat muuttua; Oxylabs näyttää 6 $/GB viidellä gigalla ja 2,50 $/GB teratavun tasolla; ja Decodo (entinen Smartproxy) näyttää 3,75 $/GB kolmen gigan tasolla, 2,75 $/GB 100 gigalla sekä 4 $/GB pay-as-you-go -tarjouksen. Decodo mainostaa myös yli 115 miljoonan IP:n poolia ja 99,92 % onnistumisastetta — palveluntarjoajan omia väitteitä, ei riippumattomasti varmennettuja tuloksia.
Itse käyttämäni päätöspuu on tämä: pitääkö sinun olla vuorovaikutuksessa sivun kanssa — klikata, skrollata, täyttää lomakkeita, ylläpitää kirjautumisistuntoa? Rakenna Puppeteerilla ja proxyeilla. Tarvitsetko vain sivulla jo olevan datan? Katso ensin extraction API:a ennen kuin rakennat ikuisesti ylläpidettävän proxy-infran.
Milloin Puppeteer + proxyt on liioittelua: käytä sen sijaan API:a strukturoituun dataan
Jossain kolmannen kerran jälkeen, kun rakensin proxy-terveystarkistusjärjestelmän projektiin, joka tarvitsi vain tuotehinnat taulukkoon, tajusin asian: suurin osa tästä infrastruktuurista on olemassa ratkaisemaan ongelmaa — raakaa HTML:ää sivulta pois — joka ei oikeastaan ole kehittäjän lopullinen tavoite. Tavoite on strukturoitu data. HTML on vain kiusallinen välimuoto.
Thunderbitin Open API käsittelee ekstraktion ensisijaisena toimintona eikä sivuvaikutuksena selainautomaatiossa. POST /extract ottaa URL:n ja JSON Scheman ja palauttaa sovitetun strukturoidun datan — JS-renderöinnin, bot-suojausten ja CAPTCHA-haasteiden käsittely tapahtuu taustalla, eikä sinun tarvitse itse rakentaa stealth-pluginia ja proxy-poolia:
curl -X POST https://openapi.thunderbit.com/openapi/v1/extract \
-H "Authorization: Bearer $THUNDERBIT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"price": {"type": "number"}
},
"required": ["name", "price"]
}
}'
Käytettävissä on myös POST /distill-endpoint tilanteisiin, joissa haluat vain siistiä Markdownia tiukan skeeman sijaan, sekä batch-ekstraktio, jolla sama skeema voidaan ajaa usean URL:n yli yhdellä kutsulla. Thunderbitin nykyisen API-hinnoittelun mukaan Distill kuluttaa 1 yksikön per sivu ja Extract 20 yksikköä per sivu — ilmainen taso sisältää 600 kertaluonteista yksikköä, mikä riittää työnkulun testaukseen ennen sitoutumista.
Kehittäjille, jotka työskentelevät Clauden, Cursorin tai muun MCP-yhteensopivan asiakkaan sisällä, Thunderbit tarjoaa myös thunderbit_extract- ja thunderbit_distill-työkalut MCP:n kautta. Tällöin agentti voi kesken tehtävän päättää, milloin data pitää hakea sivulta, eikä erillistä scrapausvaihetta tarvita. Tarkistaisin silti aina live-version API-referenssistä ennen MCP-konfiguraation tekemistä, sillä työkalujen nimet ja parametrit voivat muuttua dokumentaatioversioiden välillä.
| Ominaisuus | Puppeteer + pyörivät proxyt | Thunderbit API |
|---|---|---|
| Käyttöönoton monimutkaisuus | Korkea — proxy pool, kierrätyslogiikka, stealth, retryt | Matala — yksi API-kutsu JSON Scheman kanssa |
| Bot-suojausten käsittely | Manuaalinen | Sisäänrakennettu |
| Ulostulo | Raaka HTML (vaatii parserin) | Strukturoitu JSON skeemasi mukaisesti |
| Ylläpito | Korkea — selektorit hajoavat, proxyt vanhenevat | Matala |
| Sopii parhaiten | Räätälöity automaatio, kirjautumiset, erikoistuneet vuorovaikutukset | Datan ekstraktio mittakaavassa |
DIY-polun puolustukseksi: jos käyttötapasi vaatii kirjautumista tilille, monivaiheisen flow’n klikkailua tai muuta, joka edellyttää tilan säilyttämistä istunnon yli, extraction API ei yleensä voi korvata sitä — Thunderbitin oma FAQ sanoo suoraan, että interaktiivisia kirjautumisflow’ta ei tällä hetkellä tueta API:n kautta. Siinä Puppeteer + proxyt voittaa yhä. Mutta jos tehtävä on "hanki data useilta julkisilta sivuilta omaan skeemaani", oman proxy-kierrätyspinon rakentaminen ratkaisee vaikeampaa ongelmaa kuin mitä sinulla oikeasti on. Tiimeille, jotka haluavat ohittaa koodin kokonaan, Thunderbit Chrome Extension tarjoaa saman AI-vetoisen ekstraktion klikkaa-ja-valitse-käyttöliittymällä — kannattaa katsoa, jos vertaat no-code-web scrappausta täyteen kehittäjäkokoonpanoon.
Yhteenveto ja tärkeimmät opit
Pyörivät proxyt Puppeteerissa eivät ole yksi ainoa tekniikka. Per-selain-kierrätys on yksinkertainen ja eristetty. Todennettu backconnect-gateway voi kierrättää poistumisosoitteita yhden selaintason päätepisteen takana. Tarkka per-pyyntö- tai samanaikainen identiteettien hallinta vaatii browser shardingia tai ulkoista relayta; request interception yksinään ei muuta Chromen verkkoreittiä.
Mikään tästä ei kuitenkaan auta paljoa ilman muuta pinoa. Proxyt ratkaisevat IP-maineen ongelman; stealth-pluginit ja sormenjäljen yhtenäisyys ratkaisevat selainsignaalien ongelman; jitter ja rytmitys ratkaisevat käyttäytymisen ongelman. Jätä jokin kerros pois, ja sinut voidaan yhä blokata — vain eri syystä.
Jos rakennat tämän itse, aloita proxy-chain-repositorysta ja yllä olevista koodipätkistä — niillä pääset pidemmälle kuin useimmilla maksullisilla kursseilla. Jos haluat mieluummin jättää proxyjen hallinnan kokonaan väliin ja saada takaisin vain strukturoitua dataa, Thunderbitin API-dokumentaatioon kannattaa käyttää kymmenen minuuttia ennen kuin käytät viikonlopun health check -infran rakentamiseen, jota joudut ylläpitämään ikuisesti. Molemmat polut ovat järkeviä — varmista vain, että ratkaiset oikean ongelman, et sen oletettua ongelmaa, jonka jokainen tutoriaali olettaa sinulla olevan. Jos haluat laajemman katsauksen siihen, miten AI muuttaa tätä kenttää, tutustu syväsukellukseemme aiheesta AI web scraping ja siihen, miten se vertautuu perinteisiin lähestymistapoihin.
UKK
Kuinka usein proxyt pitäisi kierrättää Puppeteerissa?
Se riippuu siitä, kuinka aggressiivinen kohteen rate limiting on. Sivustoilla, joilla bottitunnistus on tiukka, kierrätä sivukohtaisesti tai istuntokohtaisesti. Sallivammilla sivustoilla per istunto tai jopa yksi sticky-IP koko scrappauserälle voi toimia hyvin. Yleispätevää lukua ei ole — pidä 403-, 429- ja aikakatkaisuvirheitä signaalina kierrättää aggressiivisemmin, ei kiinteänä pyyntimääränä.
Voinko käyttää ilmaisia proxyeja Puppeteer-scrappaukseen?
Teknisesti kyllä, mutta en suosittelisi sitä muuhun kuin pikaiseen testaukseen. Ilmaiset proxy-listat ovat yleensä hitaita, epäluotettavia ja usein jo valmiiksi estettyjä niillä sivustoilla, joita yrität scrapata. Kaikkeen tuotantokäyttöön residential-proxyt maksulliselta tarjoajalta tai hallittu gateway ovat hinnan arvoisia.
Toimiiko puppeteer-extra-plugin-stealth kaikkia bottisuojausjärjestelmiä vastaan?
Ei, ja pluginin oma dokumentaatio sanoo sen suoraan. Se vähentää joitakin yleisiä headless-Chromen jälkiä, mutta kohde voi silti arvioida verkkomaineen, TLS-ominaisuudet, evästeet, client hintsit ja käyttäytymisen. Ajattele pluginiä yhtenä yhteensopivuuskerroksena, ei takuuna.
Mitä eroa on proxy-chain-kirjastolla ja --proxy-server-lipulla Puppeteerissa?
--proxy-server on natiivi Chromiumin käynnistyslippu, joka liittää yhden proxy-pisteen koko selaininstanssiin, eikä Chrome hyväksy siihen upotettuja proxy-tunnuksia. proxy-chain luo paikallisen anonyymin tunnelin todennettuun upstreamiin. Kierrätys tulee sitten käynnistämällä selain uudelleen toisen upstreamin kanssa, käyttämällä tarjoajan hallitsemaa backconnect-gatewayta tai erikseen rakennettua relayta — ei siitä, että proxy-chain jakaisi proxyja yksittäisille Puppeteer-sivuille.
Riittääkö pyörivä proxy estämään blokit kokonaan?
Ei — ja tämä on yleisin väärinkäsitys. Modernit bot-suojausjärjestelmät kuten Cloudflaren bot management yhdistävät IP-maineen, selaimen sormenjäljen, käyttäytymismallit ja istuntohistorian. Proxyt ratkaisevat IP-maineen osan; tarvitset silti stealth-asetukset, yhtenäiset sormenjäljet ja uskottavan ajoituksen, jotta et paljastu muiden signaalien perusteella.
Lisää luettavaa


