рдХреИрд╕реЗ Scrapeless Scraping рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдПрдХ Etsy рд╕реНрдХреНрд░реИрдкрд░ рдмрдирд╛рдПрдВ: рд╡реНрдпрд╛рдкрдХ рдЧрд╛рдЗрдб 2026 (Node.js)
Scraping and Proxy Management Expert
рдореБрдЦреНрдп рдмрд╛рддреЗрдВ:
- Scrapeless Scraping Browser рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдПрдЖрдИ рдмреНрд░рд╛рдЙрдЬрд░ рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдЬреЛ Etsy рдХреЗ DataDome рдПрдВрдЯреА-рдмреЙрдЯ рд▓реЗрдпрд░ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯрд┐рдВрдЧ, рдЖрд╡рд╛рд╕реАрдп рдкреНрд░реЙрдХреНрд╕реА рдФрд░ CAPTCHA рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИред
- рдПрдХ CONFIG рдмреНрд▓реЙрдХ рд╕реЗ рдЪрд╛рд░ рдбрд┐рд╕реНрдХрд╡рд░реА рдореЛрдб тАФ рдЙрддреНрдкрд╛рдж URL, рд╢реНрд░реЗрдгреА URL, рдХреАрд╡рд░реНрдб рдЦреЛрдЬ (рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд╕рд╛рде) рдФрд░ рджреБрдХрд╛рди URLред рдЗрдирдкреБрдЯреНрд╕ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░реЗрдВ, рд╡рд╣реА рдкрд╛рдЗрдкрд▓рд╛рдЗрдиред
- рдЖрда рд╕рдВрд░рдЪрд┐рдд рдлрд╝рд┐рд▓реНрдЯрд░ (рдмрд┐рдХреНрд░реА рдкрд░, рдлреНрд░реА-рд╢рд┐рдкрд┐рдВрдЧ, рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп, рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдиреНрдпреВрдирддрдо/рдЕрдзрд┐рдХрддрдо рдХреАрдордд, рд╕реНрдерд┐рддрд┐, рдХреНрд░рдо рджреНрд╡рд╛рд░рд╛) рдХрд┐рд╕реА рднреА рдбрд┐рд╕реНрдХрд╡рд░реА рдореЛрдб рдХреЗ рд╕рд╛рде рдорд┐рд╢реНрд░рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рдЦреЛрдЬ рдпрд╛ рд╢реНрд░реЗрдгреА URLs рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
- рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдХреАрдорд╛ рдкреНрд░рддрд┐ рдЙрддреНрдкрд╛рдж 30+ рдлрд╝реАрд▓реНрдб рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ
variations,breadcrumbs,listedDate,reviews[].photosрдФрд░ рдЕрджреНрд╡рд┐рддреАрдп рд╡рд┐рдкрдгрди рд╕рдВрдХреЗрдд (isBestseller,isStarSeller,isFreeShipping,inStock,favoritesCount, рдкреНрд░рддрд┐-рд░рд┐рд╡реНрдпреВ рдЙрдк-рд╕реНрдХреЛрд░) рд╢рд╛рдорд┐рд▓ рд╣реИрдВред - рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рд▓реВрдк (рдбрд┐рдлрд╝реЙрд▓реНрдЯ
maxRetries: 10, рдмрдврд╝рддрд╛ рдмреИрдХрдСрдлрд╝ 3 рд╕реЗрдХрдВрдб тЖТ 47 рд╕реЗрдХрдВрдб) рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЗ рдмреАрдЪ рддрд╛рдЬрд╛ рд╕рддреНрд░ рдФрд░ рдЖрд╡рд╛рд╕реАрдп IP рдХреА рдУрд░ рдШреВрдорддрд╛ рд╣реИ, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрд╕реНрдерд╛рдпреА 403s рдХреЛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдкрд░рд┐рдЪрдп: рдПрдВрдЯреА-рдбрд┐рдЯреЗрдХреНрд╢рди рдХреНрд▓рд╛рдЙрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ Etsy
Etsy рдИ-рдХреЙрдорд░реНрд╕ рдЦреБрдлрд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЦрдЬрд╛рдирд╛ рд╣реИ: рджреБрдХрд╛рди рдорд╛рд▓рд┐рдХреЛрдВ рдХреЗ рд▓рд┐рдП рддреБрд▓рдирд╛рддреНрдордХ рд╡рд┐рдХреНрд░реЗрддрд╛ рдореВрд▓реНрдп, рдПрдордПрд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рднрд╛рд╡рдирд╛-рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЙрд░реНрдкрд╕ рдФрд░ рдбреНрд░реЙрдкрд╢рд┐рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдирд┐рдЪреЗ рдЦреЛрдЬ рд╕рднреА рдЙрд╕реА рд╕реВрдЪреАрдХрд░рдг рдкреГрд╖реНрдареЛрдВ рд╕реЗ рдкреНрд░рд╡рд╛рд╣рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдЖрдзрд┐рдХрд╛рд░рд┐рдХ Etsy API рдХрд╛ рд╕реАрдорд┐рдд рдкрд╣реБрдВрдЪ рдФрд░ рд▓рдВрдмрд╛ рд╕реНрд╡реАрдХреГрддрд┐ рдЪрдХреНрд░ рд╣реИ, рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдбреЗрдЯрд╛ рдкреБрдирд░реНрд╡рд┐рдХреНрд░реЗрддрд╛ рдорд╣рдВрдЧреЗ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдХрд╕реНрдЯрдо рд╕реНрдХреНрд░реИрдкрд░ рдХреЛ DataDome рдХреЗ рдЦрд┐рд▓рд╛рдл рдЪрд▓ рд░рд╣реЗ рд░рдЦрд░рдЦрд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ Etsy рдХреЗ рдлреНрд░рдВрдЯрдПрдВрдб рдкрд░ рд▓рдЧрд╛рддрд╛рд░ CSS рд╡рд░реНрдЧ рдирд╛рдореЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрддрд╛ рд╣реИред
рдпрд╣ рдЧрд╛рдЗрдб рдПрдХ рдПрдХрд▓ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддреА рд╣реИ рдЬреЛ Scrapeless Scraping Browser рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ рдЬреЛ рд╕рднреА рдХрдард┐рди рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдкрд╣рд▓реЗ рд╣реА рд╕рдВрднрд╛рд▓ рд▓реЗрддреА рд╣реИ: рдПрдВрдЯреА-рдбрд┐рдЯреЗрдХреНрд╢рди рдХреНрд▓рд╛рдЙрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░, рдЖрд╡рд╛рд╕реАрдп рдкреНрд░реЙрдХреНрд╕реА, рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдФрд░ рджреБрдХрд╛рди рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐-рдЙрддреНрдкрд╛рдж рд╕рдореГрджреНрдзрд┐ рдФрд░ рд╡рд╣ рдмрд╣реБ-рдкреВрдВрдЫ рд╡рд┐рд╕реНрддрд╛рд░ рддрдХрдиреАрдХ рдЬреЛ рдПрдХ рдПрдХрд▓ рдмреЗрд╕ рдХреАрд╡рд░реНрдб рд╕реЗ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЕрдзрд┐рдХ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддреА рд╣реИ рдЬрд┐рддрдирд╛ рдХрд┐ Etsy рдХреЗ рдкреНрд░рддрд┐-рдЦреЛрдЬ рдХреА рдЫрдд рд╕рд╛рдорд╛рдиреНрдпрддрдГ рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рд╡рд╣реА рд╕реНрдХреНрд░реИрдкрд░ рдЪрд╛рд░ рд╕реНрд╡рддрдВрддреНрд░ рдбрд┐рд╕реНрдХрд╡рд░реА рдореЛрдб рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ тАФ рдЗрд╕реЗ рдЙрддреНрдкрд╛рдж URL, рд╢реНрд░реЗрдгреА URL, рдХреАрд╡рд░реНрдб рдЦреЛрдЬ рдпрд╛ рджреБрдХрд╛рди URL рджреЗрдВ тАФ рдФрд░ рд╣рд░ рдЖрдЙрдЯрдкреБрдЯ рдкрдВрдХреНрддрд┐ рд╕реВрдЪреАрдХрд░рдг рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рд╡рд╣реА рд╕рдореГрджреНрдз 30-рдлреАрд▓реНрдб рд╕реНрдХреАрдорд╛ рд▓реЗ рдЖрддреА рд╣реИред
рдЖрдк рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
Etsy рдбреЗрдЯрд╛ рдПрдХ рдмрд╣реБрдкрд░рдХрд╛рд░реА рд╕рдВрдкрддреНрддрд┐ рд╣реИ, рдЬреЛ рдЙрддреНрдкрд╛рдж рдЕрдиреБрд╕рдВрдзрд╛рди рд╕реЗ рд▓реЗрдХрд░ рдЙрдиреНрдирдд рдПрдЖрдИ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рддрдХ рдЙрдЪреНрдЪ-рдкреНрд░рднрд╛рд╡ рд╡рд╛рд▓реЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рдЪрд▓рд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдкрд╛рдВрдЪ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдЙрдкрдпреЛрдЧ рд╣реИрдВ, рд╕рднреА рдЙрд╕реА рдХреЛрдбрдмреЗрд╕ рд╕реЗ рдкреНрд░рд╛рдкреНрдп, рдЕрдХреНрд╕рд░ рдХреЗрд╡рд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗ рд╕рд╛рде:
- рдбреНрд░реЙрдкрд╢рд┐рдкрд┐рдВрдЧ рдЕрдиреБрд╕рдВрдзрд╛рди рдФрд░ рдЙрддреНрдкрд╛рдж рдЦреЛрдЬрдирд╛ тАФ рдХреАрд╡рд░реНрдб-рдЦреЛрдЬ рдореЛрдбред рд╕реНрдХреНрд░реИрдкрд░ рдХреЛ
"macram├й plant hanger"рдкрд░expandStrategy: "keywords"рдХреЗ рд╕рд╛рде["boho", "modern", "minimalist"]рдкрд░ рдЪрд▓рд╛рдПрдВ,maxProducts: 200рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреЛfavoritesCount ├Ч ratingрдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреНрд░рдо рджреЗрдВред рдЙрди рджреБрдХрд╛рдиреЛрдВ рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдВ рдЬрд╣рд╛рдБisStarSeller: trueрд╣реИ рдФрд░ favoritesCount рдФрд╕рдд рд╕реЗ рдХрд╛рдлреА рдКрдкрд░ рд╣реИ тАФ рдпреЗ рдЖрдкрдХреЗ рдбреНрд░реЙрдкрд╢рд┐рдкрд┐рдВрдЧ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдореА CSV рдХреЛ Shopify рдпрд╛ рдПрдХ рдирд┐рдЬреА рдЖрдкреВрд░реНрддрд┐рдХрд░реНрддрд╛ рд╕реВрдЪреА рдореЗрдВ рдЫреЛрдбрд╝ рджреЗрдВред рдпрд╣реА рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд▓реЛрдЧ Etsy рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд░рд╛рдЬрд╕реНрд╡ рдореЗрдВ рдмрджрд▓рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рддрд░реАрдХрд╛ рд╣реИред - рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдореВрд▓реНрдп рдирд┐рдЧрд░рд╛рдиреА тАФ рдЙрддреНрдкрд╛рдж-URL (рдкреНрд░рддреНрдпрдХреНрд╖-URL) рдореЛрдбред рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рд╕реВрдЪреА URL рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ
startUrlsрдореЗрдВ рд░рдЦреЗрдВ рдФрд░ рд╕реНрдХреНрд░реИрдкрд░ рдХреЛ рд░рд╛рдд рдореЗрдВ рдЪрд▓рд╛рдПрдБред рдкреНрд░рддреНрдпреЗрдХ JSON рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЛ рдЗрд╕рдХреАscrapedAtрдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдХреЗ рд╕рд╛рде рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВ рдФрд░ рдХреАрдордд,originalPrice,discountPercentрдФрд░ рдЪрд▓рди рдореЗрдВ рд╕реНрдЯреЙрдХ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░реЗрдВред рдХреНрдпрд╛ рдореВрд▓реНрдп рдореЗрдВ 10% рд╕реЗ рдЕрдзрд┐рдХ рдЧрд┐рд░рд╛рд╡рдЯ рд╣реИ? рд╕реНрд▓реИрдХ рдЕрд▓рд╛рд░реНрдоредinStocktrueрд╕реЗfalseрдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ? рдЖрдкреВрд░реНрддрд┐ рд╕рдВрдХреЗрдд рдХреЗ рд░реВрдк рдореЗрдВ рдЭрдВрдбрд╛ред рдЖрдк рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЬреЛ рдкреВрд░реНрдг рдореВрд▓реНрдп рдЗрддрд┐рд╣рд╛рд╕ рдмрдирд╛рддреЗ рд╣реИрдВ рд╡рд╣ рд╣рд░ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзрд╛-рдЦреБрдлрд┐рдпрд╛ рдбреИрд╢рдмреЛрд░реНрдб рдХрд╛ рдореБрдЦреНрдп рдЖрдзрд╛рд░ рд╣реИред - рдХреАрд╡рд░реНрдб рдФрд░ рдкреНрд░рд╡реГрддреНрддрд┐ рдЕрдиреБрд╕рдВрдзрд╛рди тАФ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рд╢реНрд░реЗрдгреА-URL рдореЛрдбред
categoryUrlрдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ Etsy рд╢реНрд░реЗрдгреА рдХреА рдУрд░ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ (рдЬреИрд╕реЗ/c/bags-and-purses/wallets-and-money-clips/wallets), рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ (filters.onSale: true,filters.condition: "new",filters.orderBy: "date_desc"), рдХреБрдЫ рд╕реМ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдореЗрдВtagsрдФрд░materialsрдХреЛ рдЦреАрдВрдЪреЗрдВ, рдЙрдирдХреА рдЖрд╡реГрддреНрддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░favoritesCountрдХреЗ рдпреЛрдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВред рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рд╕реВрдЪрд┐рдпреЛрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдЯреИрдЧ рд▓реЗрдХрд┐рди рдкреБрд░рд╛рдиреЗ рдореЗрдВ рдирд╣реАрдВ рдЖрдкрдХреЗ рдмрдврд╝рддреЗ рдЙрдк-рдирд┐рдЪреЗ рд╣реИрдВред - рдПрдордПрд▓ рдФрд░ рдмрд╛рдЬрд╛рд░ рдЕрдиреБрд╕рдВрдзрд╛рди рдХреЗ рд▓рд┐рдП рд╕рдореАрдХреНрд╖рд╛ рд╕рдВрдЧреНрд░рд╣рдг тАФ рдХреАрд╡рд░реНрдб рдпрд╛ рд╢реНрд░реЗрдгреА рдореЛрдбред рдПрдХ рд╡рд░реНрдЯрд┐рдХрд▓ (рд╣реИрдВрдбрдореЗрдб рдореЛрдордмрддреНрддрд┐рдпрд╛рдБ, рдХрд╣реЗрдВ, рдпрд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЖрднреВрд╖рдг) рдореЗрдВ рд╣рдЬрд╛рд░реЛрдВ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдореЗрдВ
reviews[]рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░реЗрдВ,reviews[].textрдХреЛ рдПрдХ рднрд╛рд╡рдирд╛ рд╡рд░реНрдЧреАрдХрд░рдгрдХрд░реНрддрд╛ рдореЗрдВ рдлреАрдб рдХрд░реЗрдВ рдФрд░ рдЙрдирдХреЗ рдЙрдкрд╕реНрдерд┐рдд рд╣реЛрдиреЗ рдкрд░ рд╕реБрдкрд░рд╡рд╛рдЗрдЬреНрдб рдЯреНрд░реЗрдирд┐рдВрдЧ рд▓реЗрдмрд▓ рдХреЗ рд░реВрдк рдореЗрдВitemQuality/shipping/customerServiceрдЙрдк-рд░реЗрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдкреНрд░рддрд┐-рд░рд┐рд╡реНрдпреВ рдлрд╝реЛрдЯреЛ (reviews[].photos[]) рдЖрдкрдХреЛ рдПрдХ рд╕рдорд╛рди рдЫрд╡рд┐ рдХреЙрд░реНрдкрд╕ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рдЖрдкрдХреЛ рджреГрд╢реНрдп рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред - рджреБрдХрд╛рди рдкреНрд░рджрд░реНрд╢рди рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ тАФ рджреБрдХрд╛рди-рдпреВрдЖрд░рдПрд▓ рдореЛрдбред рдмрд┐рдВрджреБ
shopUrlрдХреЛ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдХреА рджреБрдХрд╛рди рдкреГрд╖реНрда рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ (рдЬреИрд╕реЗhttps://www.etsy.com/shop/TexasValleyLeather),maxPagesPerQuery: 5рд╕реЗрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЙрдирдХреЗ рдкреВрд░реЗ рдХреИрдЯрд▓реЙрдЧ рдХреЛ рдкреГрд╖реНрдард╛рдВрдХрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдФрд░ рд╕реНрдХреНрд░реИрдкрд░ рдЙрди рд╕рднреА рд╕реВрдЪреАрдХрд░рдгреЛрдВ рдХреЛ рд╕рдВрдЦреНрдпрд╛рдмрджреНрдз рдХрд░реЗ рдЬреЛ рд╡рд╣ рджреБрдХрд╛рди рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдмреЗрдЪрддреА рд╣реИред рд╕рдорд╛рди рд╢реНрд░реЗрдгреА рдореЗрдВ рд╡рд┐рдХреНрд░реЗрддрд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВshop.totalSales,shop.openedYear,rating,reviewsCountрдФрд░isStarSellerрджреНрд╡рд╛рд░рд╛ред
рдХреНрдпреЛрдВ рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕
рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЖрдкрдХреЗ рд╕реНрдХреНрд░реИрдкрд░ рдХреЛ рдПрдХ рдЙрддреНрдкрд╛рджрди-рдЧреНрд░реЗрдб рдХреНрд▓рд╛рдЙрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдИрдЯреАрд╕реА рдХреЗ рдбреЗрдЯрд╛ рдбреЛрдо рдЪреЗрдХ рдХреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдХреЛрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рдл рдХрд░рддрд╛ рд╣реИ тАФ рдХреЛрдИ рд╕реНрдЯреЗрд▓реНрде рдкреНрд▓рдЧрдЗрдиреНрд╕, рдХреЛрдИ рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдЯреНрдпреВрдирд┐рдВрдЧ, рдХреЛрдИ рдкреНрд░реЙрдХреНрд╕реА рд░реЛрдЯреЗрд╢рди рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕ рдирд╣реАрдВ рдЬреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Puppeteer рдпрд╛ Playwright рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ WebSocket рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рдФрд░ рдЕрд╡рд╕рдВрд░рдЪрдирд╛ рдПрдВрдЯреА-рдмреЙрдЯ рд▓реЗрдпрд░ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рджреЗред
рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдЖрдкрдХреЛ рдорд┐рд▓рддрд╛ рд╣реИ:
- рдПрдВрдЯреА-рдбрд┐рдЯреЗрдХреНрд╢рди рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯрд┐рдВрдЧ рдЬреЛ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рд╕рддреНрд░реЛрдВ рдореЗрдВ рдЯрд┐рдХрд╛рдК рд░рд╣рддреА рд╣реИ
- рд╕реНрдерд╛рдпреА рдкреНрд░реЙрдХреНрд╕реА
195+ рджреЗрд╢реЛрдВ рдореЗрдВ (рдЕрд▓рдЧ рд╕реЗ US, GB, DE рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рдг) - рд╕реНрд╡рдЪрд╛рд▓рд┐рдд CAPTCHA рд╕рдорд╛рдзрд╛рди рдЬрдм рдИрдЯреАрд╕реА рдПрдХ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ
- рд╕рддреНрд░ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдкрд┐рдЫрд▓реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЪрдпрдирдХрд░реНрддрд╛ рдЧрд┐рд░рд╛рд╡рдЯ рдХреА рд╕рдорд╕реНрдпрд╛ рдирд┐рд╡рд╛рд░рдг рдХреЗ рд▓рд┐рдП
- WebSocket рдПрдВрдбрдкреЙрдЗрдВрдЯреНрд╕ рдЬреЛ Puppeteer рдФрд░ Playwright рдЬреИрд╕реЗ CDP-рдЖрдзрд╛рд░рд┐рдд рдврд╛рдВрдЪреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ тАФ рдХреЛрдИ SDK рд╕реАрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ
- рдПрдЖрдИ рдПрдЬреЗрдВрдЯ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░: рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ MCP рд╕рд░реНрд╡рд░ рдЬреИрд╕реЗ рдЯреВрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдирд┐рд╡рд╛рд░рдг рдФрд░ рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕реБрдЪрд╛рд░реВ рд░реВрдк рд╕реЗ рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред
рд╕рдВрдпреЛрдЧ рдПрдХ-рд▓рд╛рдЗрди рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ: puppeteer.connect() рдХреЛ рдПрдХ рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рдпреВрдЖрд░рдПрд▓ рдкрд░ рдЗрдВрдЧреАрдд рдХрд░реЗрдВ рди рдХрд┐ рд╕реНрдерд╛рдиреАрдп рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд░ред рдмрд╛рдХреА рдХреЛрдб рдмрд┐рд▓реНрдХреБрд▓ рд╡рд╣реА рд░рд╣рддрд╛ рд╣реИ тАФ рдорд╛рдирдХ CDP, рдорд╛рдирдХ рдЪрдпрдирдХрд░реНрддрд╛, рдорд╛рдирдХ рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣ред рд╕рднреА рдбреЗрдЯрд╛ рдбреЛрдо рдЬрдЯрд┐рд▓рддрд╛ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░, рдЖрдкрдХреЗ рдХреЛрдбрдмреЗрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд░рд╣рддреА рд╣реИред
app.scrapeless.com рдкрд░ рдирд┐рдГрд╢реБрд▓реНрдХ рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрдкрдирд╛ API рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
рдкреВрд░реНрд╡рд╛рдкреЗрдХреНрд╖рд╛рдПрдБ рдФрд░ рд╕реНрдерд╛рдкрдирд╛
Node.js 18 рдпрд╛ рдирдпрд╛ред рдПрдХ рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ API рдХреБрдВрдЬреА (рдирд┐рдГрд╢реБрд▓реНрдХ рд╕реНрддрд░ рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ рд╕рдм рдХреБрдЫ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ)ред рдХреБрдЫ Puppeteer рдХреА рдкрд░рд┐рдЪрд┐рддрддрд╛ рд╕рд╣рд╛рдпрдХ рд╣реЛрддреА рд╣реИред рд╕реНрдерд╛рдиреАрдп Chrome рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ тАФ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рдХреЗ рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИред
bash
mkdir etsy-scrapeless-browserless && cd etsy-scrapeless-browserless
npm init -y
npm install puppeteer-core dotenv cheerio
npm install -D tsx typescript @types/node @types/cheerio
puppeteer-core рдХреНрд▓рд╛рдЙрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдЪрд╛рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ; cheerio рдкреНрд░рджрд░реНрд╢рд┐рдд HTML рдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреГрд╖реНрда рдХреЗ рд▓реЛрдб рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдкрд░ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред рдмреНрд░рд╛рдЙрдЬрд╝рд░-рд╕рд╛рдЗрдб рд╕реНрдХреНрд░реЛрд▓рд┐рдВрдЧ рдФрд░ Node-рд╕рд╛рдЗрдб рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╣рд░ рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░ рдХреЛ рдЯрд╛рдЗрдк рдФрд░ рд╕рд╣реЗрдЬреЗ рдЧрдП HTML рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреЗ рдЦрд┐рд▓рд╛рдл рдпреВрдирд┐рдЯ-рдЯреЗрд╕реНрдЯ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИред
.env:
SCRAPELESS_API_KEY=your_key_here
рдХрджрдо 1 тАФ рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ
рдкреВрд░реЗ рд╕реНрдХреНрд░реИрдкрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдиреЗрдХреНрд╢рди рд╕рд╣рд╛рдпрдХред рдЯреЛрдХрди, рджреЗрд╢ рдФрд░ TTL рдХреЗ рд╕рд╛рде рдПрдХ WSS рдпреВрдЖрд░рдПрд▓ рдмрдирд╛рдПрдВ, рдлрд┐рд░ рдЗрд╕реЗ puppeteer.connect рдХреЛ рд╕реМрдВрдкреЗрдВред
ts
import "dotenv/config";
import puppeteer, { type Browser, type Page } from "puppeteer-core";
import * as cheerio from "cheerio";
// рд╕рд╣рд╛рдпрдХ тАФ рдкреГрд╖реНрда рдХрд╛ рдкреВрд░рд╛ HTML рдЦреАрдВрдЪреЗрдВ рдФрд░ рдЗрд╕реЗ cheerio рдХреЗ рд╕рд╛рде рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред рдХреЙрд▓рд░
// рдХрд┐рд╕реА рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░-рд╕рд╛рдЗрдб рд╕реНрдХреНрд░реЛрд▓рд┐рдВрдЧ / waitForFunction рдХреЛ рдкрд╣рд▓реЗ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ
// рддрд╛рдХрд┐ рдЖрд▓рд╕реА рдХреНрд╖реЗрддреНрд░ рд╣рд╛рдЗрдбреНрд░реЗрдЯреЗрдб рд╣реЛ рд╕рдХреЗрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рдкрд╛рд░реНрд╕рд┐рдВрдЧ Node рдореЗрдВ рд░рд╣рддреА рд╣реИ:
// рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рд╣реБрдЖ, рдХреЛрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧрд┐рдлрд╛рдЗрдб рдореВрд▓реНрдпрд╛рдВрдХрди рдмреЙрдбреА рдирд╣реАрдВ, рдХреЛрдИ `__name` tsx рдЧрдбреНрдврд╛ рдирд╣реАрдВ, рдмрдЪрдд HTML рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреЗ рдЦрд┐рд▓рд╛рдл
// рдпреВрдирд┐рдЯ-рдЯреЗрд╕реНрдЯ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред
async function parseWithCheerio(page: Page): Promise<cheerio.CheerioAPI> {
const html = await page.content();
return cheerio.load(html);
}
type ScraperInput = {
proxyCountry: string; // рдЬреИрд╕реЗ "US", "GB", "DE"
sessionTTL: number; // рд╕реЗрдХрдВрдб, 60тАУ900 рдХреА рдЕрдиреБрдорддрд┐; 600 рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╣реИ
};
function connectionURL(sessionName: string, cfg: ScraperInput): string {
const token = process.env.SCRAPELESS_API_KEY;
if (!token) throw new Error("SCRAPELESS_API_KEY is not set in .env");
// рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рдбрд┐рдлреЙрд▓реНрдЯ рджреНрд╡рд╛рд░рд╛ рд╕рддреНрд░ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдпреА рдЖрдИрдкреА рдкрд┐рди рдХрд░рддрд╛ рд╣реИ,
// рдЗрд╕рд▓рд┐рдП рдПрдХ puppeteer.connect рдХреЗ рднреАрддрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреГрд╖реНрда рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЙрд╕реА
// рдЖрдЙрдЯрдмрд╛рдЙрдВрдб рдЖрдИрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдирдП рд╕рддреНрд░ (рдирдпрд╛ рдХрдиреЗрдХреНрд╢рди) рдХреЛ рдЦреЛрд▓рдиреЗ рд╕реЗ рдПрдХ рдирдпрд╛ рдЖрдИрдкреА рдорд┐рд▓рддрд╛ рд╣реИ,
// рдЬрд┐рд╕ рдкрд░ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдЪрдХреНрд░ рдХреЛ рдПрдХ рдлреНрд▓реИрдЧ рдХрд┐рдП рдЧрдП рдЖрдИрдкреА рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рд░реВрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрд░реЛрд╕рд╛ рд╣реЛрддрд╛ рд╣реИред
const qs = new URLSearchParams({
token,
proxyCountry: cfg.proxyCountry,
sessionTTL: String(cfg.sessionTTL),
sessionName,
sessionRecording: "true",
// рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рдХреЛ рдкреВрд░реНрдг рдбреЗрд╕реНрдХрдЯреЙрдк рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдХрд╛ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рджреЗрдВ тАФ UA, рд╕реНрдХреНрд░реАрди, рдЯрд╛рдЗрдордЬрд╝реЛрди
// рдФрд░ рднрд╛рд╖рд╛ред рдХреЛрдИ рдореИрдиреБрдЕрд▓ setViewport / setUserAgent рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВред
fingerprint: JSON.stringify({ platform: "Windows" }),
});
return `wss://browser.scrapeless.com/api/v2/browser?${qs.toString()}`;
}
async function openBrowser(sessionName: string, cfg: ScraperInput): Promise<Browser> {
return puppeteer.connect({
browserWSEndpoint: connectionURL(sessionName, cfg),
defaultViewport: null,
});
}
рдпрд╣ рдкреВрд░реА Scrapeless-рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рддрд╣ рдХреНрд╖реЗрддреНрд░ рд╣реИ - рдПрдХ WSS URL рдФрд░ рдПрдХ puppeteer.connectред рдЗрд╕реЗ рд╕реНрдХреЗрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рдд рдпрд╣ рд╣реИ: рдПрдХ puppeteer.connect рд╕рддреНрд░ рдЕрдкрдиреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдирд┐рд╡рд╛рд╕реА IP рд╕реЗ рдмрдВрдзрд╛ рд╣реЛрддрд╛ рд╣реИ (рдПрдХ рд╣реА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣реИрдВрдбрд▓ рдкрд░ api.ipify.org рдХреЛ рд▓рдЧрд╛рддрд╛рд░ рддреАрди рдмрд╛рд░ рд╣рд┐рдЯ рдХрд░рдХреЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ - рд╣рд░ рдмрд╛рд░ рд╡рд╣реА IP)ред рдПрдХ рддрд╛рдЬрд╛ рд╕рддреНрд░ рдЦреЛрд▓рдиреЗ рд╕реЗ рдПрдХ рдирдпрд╛ IP рдорд┐рд▓рддрд╛ рд╣реИред рдпрд╣ рд╡рд╣реА рдЖрдзрд╛рд░ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдЪрд░рдг 8 рдореЗрдВ_retry рд▓реВрдк рдмрдирддрд╛ рд╣реИ - рдпрджрд┐ рдЗрд╕ рд╕рддреНрд░ рдХреЗ IP рдкрд░ рдПрдХ рдЕрдиреБрд░реЛрдз рдЕрд╡рд░реБрджреНрдз рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╕рддреНрд░ рдХреЛ рдмрдВрдж рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рдирдпрд╛ рдЦреЛрд▓рддреЗ рд╣реИрдВ, рдПрдХ рдирдпрд╛ IP рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
Scrapeless Scraping Browser рдХрдиреЗрдХреНрд╢рди рдкрд░рдд рдкрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рд░рдЦрддрд╛ рд╣реИ - UA, рд╕реНрдХреНрд░реАрди рдЖрдХрд╛рд░, рдЯрд╛рдЗрдордЬрд╝реЛрди рдФрд░ рднрд╛рд╖рд╛ рд╕рднреА fingerprint: { platform: "Windows" } WSS URL рдкрд░ рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрднрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдиреБрдЕрд▓ setViewport рдпрд╛ setUserAgent рдХреЙрд▓реНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЪрд░рдг 8 рдореЗрдВ_retry рд▓реВрдк рдКрдкрд░ рдХрд┐рд╕реНрдордд рдмреНрд▓реЙрдХреНрд╕ рдХреЛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдмреНрд░рд╛рдЙрдЬрд╝рд░-рдкрдХреНрд╖ рдХреА рд╕реЗрдЯрдЕрдк рдПрдХ-рд▓рд╛рдЗрди tsx рд╕рдВрдЧрддрддрд╛ рд╕реНрдЯрдм рд╣реИ:
ts
async function prepPage(page: Page): Promise<void> {
// рдкреГрд╖реНрда.evaluate рдлрд╝рдВрдХреНрд╢рди рдирд┐рдХрд╛рдпреЛрдВ рдХреЗ рд╕рд╛рде "__name is not defined" рдХреЗ рдЕрдВрджрд░ рдХреНрд░реИрд╢ рди рд╣реЛрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП tsx-рдЗрдирдЬреЗрдХреНрдЯреЗрдб __name рд╣реЗрд▓реНрдкрд░ рдХреЛ рд╕реНрдЯрдм рдХрд░реЗрдВред
await page.evaluateOnNewDocument(
"(function(){ globalThis.__name = function(f){ return f; }; })()",
);
}
рд╕рддреНрд░ рд╡рд╛рд░реНрдо-рдЕрдк
рдЦреЛрдЬ рдпрд╛ рджреБрдХрд╛рди рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╕реНрдХреНрд░реИрдкрд░ рдкрд╣рд▓реЗ рдПрдХ рдмрд╛рд░ Etsy рдХреА рд╣реЛрдордкреЗрдЬ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдПрдХ рд╡реИрдз рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рддреНрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЗрд╕ рдХрджрдо рдХреЗ рдмрд┐рдирд╛, /search рдФрд░ /shop рдПрдВрдбрдкреЙрдЗрдВрдЯреНрд╕ рдПрдХ рдардВрдбреЗ рд╕рддреНрд░ рдкрд░ 403 рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ:
ts
const ETSY_COUNTRY_PATHS: Record<string, string> = {
US: "", DE: "de/", GB: "uk/", FR: "fr/", IT: "it/", ES: "es/",
NL: "nl/", CA: "ca/", AU: "au/", JP: "jp/", IN: "in/",
};
async function warmUpSession(page: Page, proxyCountry: string): Promise<void> {
const path = ETSY_COUNTRY_PATHS[proxyCountry] ?? "";
try {
await page.goto(`https://www.etsy.com/${path}`, {
waitUntil: "domcontentloaded",
timeout: 30000,
});
} catch {
// рдЯрд╛рдЗрдордЖрдЙрдЯ рдпрд╛ рдиреЗрдЯрд╡рд░реНрдХ рддреНрд░реБрдЯрд┐ рдареАрдХ рд╣реИ тАФ рддрдм рддрдХ рдХреБрдХреАрдЬрд╝ рд╕реЗрдЯ рдХреА рдЬрд╛рддреА рд╣реИрдВред
}
await dismissEtsyConsent(page);
await delay(1500);
}
рджреЗрд╢-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрде рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ: рдПрдХ DE рдкреНрд░реЙрдХреНрд╕реА etsy.com/de/ рдХреЛ рд╣рд┐рдЯ рдХрд░рдиреЗ рдкрд░ 200 рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдФрд░ рд╕рд╣реА рдХреНрд╖реЗрддреНрд░реАрдп рд╕рддреНрд░ рдХреБрдХреАрдЬрд╝ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ DE рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рд╕рд╛рде etsy.com/ 403 рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдФрд░ рд╕рддреНрд░ рдмрдВрдж рд░рд╣рддрд╛ рд╣реИред US (64 рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ), DE (60 рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ) рдФрд░ GB (61 рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ) рдореЗрдВ рд╕рддреНрдпрд╛рдкрд┐рдд тАФ рддреАрдиреЛрдВ рдкрд╣рд▓реЗ рдкреНрд░рдпрд╛рд╕ рдореЗрдВ рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ рдЬрдм рд╡рд╛рд░реНрдордЕрдк рдкреНрд░реЙрдХреНрд╕реА рджреЗрд╢ рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рд╕реНрдХреНрд░реИрдкрд░ рдкрд╣рд▓реЗ collectSearchResults рдХреЙрд▓ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рддреНрд░ рдореЗрдВ рдПрдХ рдмрд╛рд░ warmUpSession рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
рдЪрд░рдг 2 тАФ рдЪрд╛рд░ рдЦреЛрдЬ рдореЛрдб
рд╕реНрдХреНрд░реИрдкрд░ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд╛рд░ рд╕реНрд╡рддрдВрддреНрд░ рддрд░реАрдХреЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдпреЗ рд╕рднреА рдПрдХ рд╣реА CONFIG рдмреНрд▓реЙрдХ рдореЗрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЙрд╕ рдПрдХ рдХреЛ рдЪреБрдиреЗрдВ рдЬреЛ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдкреНрд░рд╢реНрди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ рдФрд░ startUrls, shopUrl, categoryUrl, рдпрд╛ searchQuery рдореЗрдВ рд╕реЗ рдПрдХ рд╣реА рд╕реЗрдЯ рдХрд░реЗрдВред рдпрджрд┐ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕реЗрдЯ рд╣реИрдВ, рддреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╣реИ shopUrl тЖТ categoryUrl тЖТ searchQuery тЖТ startUrlsред
рдЙрддреНрдкрд╛рдж URL рдореЛрдб (рдкреНрд░рддреНрдпрдХреНрд╖-URL) тАФ рдЬреНрдЮрд╛рдд рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ, рд░рд╛рдд рдХреА рджреЛрдмрд╛рд░рд╛-рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ, рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рд╕реНрдиреИрдкрд╢реЙрдЯ:
ts
const CONFIG: ScraperInput = {
startUrls: [
"https://www.etsy.com/listing/547491922/leather-walletwalletman-leather",
"https://www.etsy.com/listing/1022283131/personalized-slim-wallet-fathers-day",
],
maxProducts: 2,
// ...рдЕрдиреНрдп рдбрд┐рдлрд╝реЙрд▓реНрдЯ
};
рд╢реНрд░реЗрдгреА URL рдореЛрдб тАФ рд╕рдВрд░рдЪрд┐рдд рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рд╕рдВрдкреВрд░реНрдг рд╢реНрд░реЗрдгреА рдХреНрд░реЙрд▓:
ts
const CONFIG: ScraperInput = {
categoryUrl: "https://www.etsy.com/c/bags-and-purses/wallets-and-money-clips/wallets",
filters: {
onSale: true,
freeShipping: true,
minPrice: 20,
maxPrice: 60,
orderBy: "most_relevant",
},
maxPagesPerQuery: 2,
maxProducts: 20,
};
рдХреАрд╡рд░реНрдб рдЦреЛрдЬ рдореЛрдб тАФ рд╡рд┐рд╢реЗрд╖ рдЦреЛрдЬ, рдкреНрд░рд╡реГрддреНрддрд┐ рдЕрдиреБрд╕рдВрдзрд╛рди, рдорд╛рддреНрд░рд╛ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкреБрд▓:
ts
const CONFIG: ScraperInput = {
searchQuery: "leather wallet",
expandStrategy: "keywords", // "none" | "keywords" | "prices"
expandKeywords: ["mens", "womens", "vintage"], // рдЬрдм рд╡рд┐рд╕реНрддрд╛рд░ = рдХреАрд╡рд░реНрдб рд╣реЛ рддрдм рдмреЗрд╕ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ
maxProducts: 20,
};
рджреБрдХрд╛рди URL рдореЛрдб тАФ рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ / рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рджреБрдХрд╛рди рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ:
ts
const CONFIG: ScraperInput = {
shopUrl: "https://www.etsy.com/shop/TexasValleyLeather",
maxPagesPerQuery: 5,
maxProducts: 40,
};
рдЪрд╛рд░реЛрдВ рдореЛрдб рдЪрд░рдг 4тАУ6 рдореЗрдВ рдПрдХ рд╣реА рдкреНрд░рддрд┐-рд╕реВрдЪреА рд╕рдВрдкрддреНрддрд┐ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреЛ рдЦрд┐рд▓рд╛рддреЗ рд╣реИрдВ рдФрд░ рдЪрд░рдг 8 рдореЗрдВ рдПрдХ рд╕рдорд╛рди 30-рдХреНрд╖реЗрддреНрд░ рд╕реНрдХреАрдорд╛ рдЬрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВред
рд╕рдВрд░рдЪрд┐рдд рдлрд╝рд┐рд▓реНрдЯрд░
рдЖрда рд╡реИрдХрд▓реНрдкрд┐рдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреБрдВрдЬреА searchQuery рдпрд╛ categoryUrl рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрд┐рдд рд╣реЛрддреА рд╣реИрдВред рдЬрд┐рдирдореЗрдВ рд╕реЗ рднреА рд▓рд╛рдЧреВ рд╣реЛрдВ, рдЙрдиреНрд╣реЗрдВ рд╕реЗрдЯ рдХрд░реЗрдВ, рдмрд╛рдХреА рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ:
| рдХреБрдВрдЬреА | рдорд╛рди | рдкреНрд░рднрд╛рд╡ |
|---|---|---|
onSale |
true |
рдХреЗрд╡рд▓ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдмрд┐рдХреНрд░реА рдкрд░ рд╕реВрдЪреАрдмрджреНрдз рд╡рд╕реНрддреБрдПрдВ |
freeShipping |
true |
рдХреЗрд╡рд▓ рдкреНрд░реЙрдХреНрд╕реА рджреЗрд╢ рдореЗрдВ рдореБрдлреНрдд рд╢рд┐рдкрд┐рдВрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╕реВрдЪреА |
customizable |
true |
рдХреЗрд╡рд▓ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ |
shipsTo |
ISO рдХреЛрдб рдЬреИрд╕реЗ "US" |
рдЙрд╕ рджреЗрд╢ рдореЗрдВ рднреЗрдЬрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ |
minPrice / maxPrice |
рд╕рдВрдЦреНрдпрд╛ | рдореВрд▓реНрдп рд╕реАрдорд╛ (Etsy рдХрд╛ рд╕реНрд╡рджреЗрд╢реА рдлрд╝рд┐рд▓реНрдЯрд░) |
condition |
"new" | "vintage" |
Etsy рд╕реНрдерд┐рддрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ |
orderBy |
"рд╕рдмрд╕реЗ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ" | "рддрд╛рд░реАрдЦ_desc" | "рдХреАрдордд_рдХрдо" | "рдХреАрдордд_рдЬреНрдпрд╛рджрд╛" | "рдЙрдЪреНрдЪрддрдо рд╕рдореАрдХреНрд╖рд╛рдПрдБ" |
рдкрд░рд┐рдгрд╛рдо рдХреНрд░рдордмрджреНрдзрддрд╛ |
рдкреЗрдЬрд┐рдиреЗрд╢рди рдирд┐рдпрдВрддреНрд░рдг
maxPagesPerQuery: N рд╕реЗрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдбрд┐рд╕реНрдХрд╡рд░реА URL рдкрд░ ?page=1..N рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЗрд╕рдХреЗ рдмрд┐рдирд╛, рд╕реНрдХреНрд░реИрдкрд░ рд▓рдХреНрд╖рд┐рдд рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкреГрд╖реНрда рдХреЛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЬрдм maxProducts рдЕрджреНрд╡рд┐рддреАрдп рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдПрдХрддреНрд░ рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ, рддреЛ рд░реБрдХ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рдЖрдк рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рдирд┐рдд рдмрдбрд╝реЗ рд╕реНрдХреНрд░реИрдк рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдЬреИрд╕реЗ "рдЗрд╕ рд╢реНрд░реЗрдгреА рдХреЗ рдкрд╣рд▓реЗ 5 рдкреГрд╖реНрдареЛрдВ рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░реЗрдВ, рднрд▓реЗ рд╣реА рд╡рд╣ 200+ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рд╣реЛ"), рддрдм рд╕реНрдкрд╖реНрдЯ рдкреЗрдЬрд┐рдиреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдЪрд░рдг 3 тАФ рдорд▓реНрдЯреА-рдХреНрд╡реЗрд░реА рд╡рд┐рд╕реНрддрд╛рд░ (Etsy "рдкрд░рд┐рдгрд╛рдо рд╕реАрдорд╛" рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╣рд▓)
Etsy рдХрд╛ рдЙрдкрднреЛрдХреНрддрд╛ UI рдкреЗрдЬрд┐рдиреЗрд╢рди рдХреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ niches рдЦрддреНрдо рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддрд┐-IP рджрд░ рд╕реАрдорд╛ рдЙрдЪреНрдЪ рдЕрдиреБрд░реЛрдз рдорд╛рддреНрд░рд╛ рдХреЗ рддрд╣рдд рдЬрд▓реНрджреА рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИ тАФ рдХреЛрдИ рднреА рдПрдХрд▓ рдХреАрд╡рд░реНрдб рдХреЗрд╡рд▓ рдПрдХ рд░реИрдВрдХрд┐рдВрдЧ рд╕реНрд▓рд╛рдЗрд╕ рдХреЛ рд╣реА рд╕рддрд╣ рдкрд░ рд▓рд╛рддрд╛ рд╣реИред рдПрдХ рдирд┐рдЪ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдзрд╛рд░ рдХреНрд╡реЗрд░реА рдХреЛ рдПрдХ рдзреБрд░реА (рдХреАрд╡рд░реНрдб рдпрд╛ рдХреАрдордд рдмрдХреЗрдЯ) рдХреЗ рд╕рд╛рде рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ listingId рджреНрд╡рд╛рд░рд╛ рдбреЗрдбреБрдк рдХрд░реЗрдВред
"рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯ" рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреАрд╡рд░реНрдб рд╡рд┐рд╕реНрддрд╛рд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рджрд┐рдЦрддрд╛ рд╣реИ:
ts
function searchUrlForQuery(query: string, page = 1, priceMin?: number, priceMax?: number) {
const params = new URLSearchParams({ q: query });
if (page > 1) params.set("page", String(page));
if (priceMin !== undefined) params.set("min", String(priceMin));
if (priceMax !== undefined) params.set("max", String(priceMax));
return `https://www.etsy.com/search?${params.toString()}`;
}
type ExpandStrategy = "keywords" | "prices" | "none";
function multiQueryExpand(
base: string,
cfg: { expandStrategy: ExpandStrategy; expandKeywords: string[]; priceBuckets: [number, number][] }
) {
if (cfg.expandStrategy === "keywords") {
const queries = [base, ...cfg.expandKeywords.map((k) => `${k} ${base}`)];
return queries.map((q) => searchUrlForQuery(q));
}
if (cfg.expandStrategy === "prices") {
return cfg.priceBuckets.map(([min, max]) => searchUrlForQuery(base, 1, min, max));
}
return [searchUrlForQuery(base)];
}
["рдкреБрд░реБрд╖реЛрдВ", "рдорд╣рд┐рд▓рд╛рдУрдВ", "рд╡рд┐рдВрдЯреЗрдЬ"] рдХреЗ рдЦрд┐рд▓рд╛рдл "рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯ" рдЪрд╛рд░ рдЦреЛрдЬреЗрдВ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдЙрдиреНрд╣реЗрдВ рдЪрд▓рд╛рдПрдБ, рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ URLs рдПрдХрддреНрд░ рдХрд░реЗрдВ, URL рдореЗрдВ рдирд┐рд╣рд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ ID рджреНрд╡рд╛рд░рд╛ рдбреЗрдбреБрдк рдХрд░реЗрдВ (/listing/1051861316/...)ред maxProducts рдХреЛ рдкрд░реНрдпрд╛рдкреНрдд рдКрдБрдЪрд╛ рд╕реЗрдЯ рдХрд░реЗрдВ (рдЕрдзрд┐рдХрд╛рдВрд╢рддрдГ рдХреБрдЫ рджрд░реНрдЬрди рд╕реЗ рд▓реЗрдХрд░ рдХреБрдЫ рд╕реМ рддрдХ) рддрд╛рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рднреА рд╡реЗрд░рд┐рдПрдВрдЯреНрд╕ рдореЗрдВ рдлреИрд▓ рд╕рдХреЗ тАФ рдпрджрд┐ рд▓рдХреНрд╖реНрдп рдЫреЛрдЯрд╛ рд╣реИ рддреЛ рд╕реНрдХреНрд░реИрдкрд░ рдкрд╣рд▓реЗ рдХреНрд╡реЗрд░реА рдХреЗ рдмрд╛рдж рдЬреЛ рдкрд░рд┐рдгрд╛рдо рд╣реИ, рдЙрд╕рдХреЗ рдмрд╛рдж рд╕реАрдзреЗ рд░реБрдХ рдЬрд╛рдПрдЧрд╛, рдбреЗрдбреБрдк рдмрдирд╛рдиреЗ рдХреЗ рдХрд╛рдо рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЫреЛрдбрд╝ рджреЗрдЧрд╛ред
рдХреАрдордд рдмрдХреЗрдЯрд┐рдВрдЧ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреА рд╣реИ тАФ рд╡рд┐рднрд┐рдиреНрди рдмрдХреЗрдЯ рд╡рд┐рднрд┐рдиреНрди рд░реИрдВрдХрд┐рдВрдЧ рд╕реНрд▓рд╛рдЗрд╕ рдХреЛ рд╕рддрд╣ рдкрд░ рд▓рд╛рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ Etsy рдХрд╛ "рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдореЗрд▓" рдХреАрдордд рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдкрд░рд┐рдгрд╛рдо рд╕реЗрдЯ рдореЗрдВ рдЕрдиреНрдп рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╣реИред
рдЪрд░рдг 4 тАФ рдкреНрд░рддреНрдпреЗрдХ рдЦреЛрдЬ рд╕реЗ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ URLs рдПрдХрддреНрд░ рдХрд░реЗрдВ
рдкрд░рд┐рдгрд╛рдо рд╕рд╛рдЗрдбрдмрд╛рд░ рдХреЛ рдЗрддрдирд╛ рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВ рдХрд┐ рд▓реЗрдЬрд╝реА-рд▓реЛрдбреЗрдб рдХрд╛рд░реНрдбреНрд╕ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдлрд┐рд░ рд╣рд░ a[href*="/listing/"] рд▓рд┐рдВрдХ рдХреЛ div.listing-link рдХреЗ рдЕрдВрджрд░ рдкрдХрдбрд╝реЗрдВ (рдЬрдм Etsy A/B-рдЯреЗрд╕реНрдЯ рдХреНрд▓рд╛рд╕ рдирд╛рдо рдХрд░рддрд╛ рд╣реИ рддреЛ [data-listing-id] рдХреЗ рд░реВрдк рдореЗрдВ рдмреИрдХрдЕрдк рдкрд░)ред
ts
type SearchHit = { listingId: string | null; url: string; title: string | null; rank: number };
const delay = (ms: number) => new Promise((r) => setTimeout(r, ms));
async function collectSearchResults(page: Page, searchUrl: string, target: number, pageTimeoutMs = 60000): Promise<SearchHit[]> {
await page.goto(searchUrl, { waitUntil: "domcontentloaded", timeout: 60000 });
await dismissEtsyConsent(page);
await delay(2000);
// Lazy-loaded рдХрд╛рд░реНрдбреНрд╕ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдмрд╛рд░ рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВред рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рд╕
// рд╡рд░реНрддрдорд╛рди DOM рдХрд╛ рдПрдХ cheerio рд╕реНрдиреИрдкрд╢реЙрдЯ рд▓реЗрддрд╛ рд╣реИ тАФ рдЬреИрд╕реЗ рд╣реА рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ,
// рд╣рдо рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВред
for (let i = 0; i < 6; i++) {
const $peek = await parseWithCheerio(page);
if ($peek("[data-listing-id], div.listing-link").length >= target) break;
await page.evaluate(() => window.scrollBy(0, 1200));
await delay(900);
}
// Cheeriod рдХреЗ рд╕рд╛рде рд╕реНрдерд┐рд░ DOM рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВ тАФ рдХреЛрдИ `page.evaluate` рд░рд╛рдЙрдВрдб-рдЯреНрд░рд┐рдк рдирд╣реАрдВ,
// рдХреЛрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧрд┐рдлрд╛рдЗрдб рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреАрдЬрд╝ рдирд╣реАрдВ, рдмрд╕ рд╕реАрдзреЗ рд╕реЗрд▓реЗрдХреНрдЯрд░ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ред
const $ = await parseWithCheerio(page);
let cards = $("div.listing-link");
if (cards.length === 0) cards = $("[data-listing-id]");
const hits: SearchHit[] = [];
const seen = new Set<string>();
cards.each((_, card) => {
const link = $(card).find('a[href*="/listing/"]').first();
if (!link.length) return;
const href = link.attr("href") || "";
const absolute = href.startsWith("http") ? href : `https://www.etsy.com${href.startsWith("/") ? "" : "/"}${href}`;
const url = absolute.split("?")[0];
if (!url || seen.has(url)) return;
seen.add(url);
const titleEl = $(card).find("h3").first();
const title = titleEl.length ? titleEl.text().trim() : (link.attr("title") || null);
const idMatch = url.match(/\/listing\/(\d+)/);
const listingId = idMatch ? idMatch[1] : null;
hits.push({ listingId, url, title, rank: hits.length + 1 });
});
return hits;
}
рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ page.evaluate рдкрд░ рд░рд╣рддреА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рд╕рдХреНрд░рд┐рдп DOM рдХреНрд░рд┐рдпрд╛ рд╣реИ (Etsy рдХреА рд▓реЗрдЬрд╝реА-рд▓реЛрдб рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдирд╛), рд▓реЗрдХрд┐рди рд╣рд░ рдЯреБрдХрдбрд╝рд╛ рдкрд╛рд░реНрд╕рд┐рдВрдЧ Cheeriod рдкрд░ page.content() рд╕реНрдиреИрдкрд╢реЙрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддрд╛ рд╣реИред рдпрд╣реА рдкреИрдЯрд░реНрди рд╕рднреА рдЫрд╣ рд╕рдореГрджреНрдзрд┐ рдирд┐рд╖реНрдХрд░реНрд╖рдгрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдЪрд░рдг 6-7 рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
dismissEtsyConsent рдХреЙрд▓ рдЙрди рдЧреИрд░-рдЕрдореЗрд░рд┐рдХреА рд╕рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬрд╣рд╛рдБ Etsy рдПрдХ "рдХреБрдХреАрдЬрд╝ рдФрд░ рдЧреЛрдкрдиреАрдпрддрд╛" рдЧреЗрдЯ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдкреГрд╖реНрда рдкреНрд░рд╕реНрддреБрдд рд╣реЛред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рднреА рдмрдЯрди рдХреА рддрд▓рд╛рд╢ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ "рд╕рднреА рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ" / "рд╕рднреА рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ" / рдХреБрдЫ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕рдордХрдХреНрд╖ рд▓рд┐рдЦрд╛ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИред
рдЪрд░рдг 5 тАФ рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░реЗрдВ
Google Maps рдХреЗ рд╡рд┐рдкрд░реАрдд, Etsy рдХреЗ /listing/<id>/ рдпреВрдЖрд░рдПрд▓ рд╕реАрдзреЗ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдкрд░ рднреА рдкреВрд░рд╛ рдкреИрдирд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдХрд┐рд╕реА рдХреНрд▓рд┐рдХ-рдереНрд░реВ рдЪрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ тАФ рд╕реНрдХреНрд░реИрдкрд░ рд╕реАрдзреЗ page.goto(listingUrl) рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, DataDome рдЗрд╕ рдЙрдкрдкрд░реНрдг рдкрд░ рддрд╛рдЬрд╝рд╛ рдкреНрд░реЙрдХреНрд╕реА рдЖрдИрдкреА рдХреЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕реЗ рдкрд░ HTTP 403 рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЪреЗрд╣рд░рд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ, 403/429 рдкрд░ рддреЗрдЬреА рд╕реЗ рд╡рд┐рдлрд▓ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдлреЗрдВрдХрддрд╛ рд╣реИ рдпрджрд┐ h1 рдХрднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ тАФ рдЗрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд┐рддрд┐ рдмрд╛рд╣рд░реА рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рд▓реВрдк рдХреЛ рдирдпрд╛ рдЖрд╡рд╛рд╕реАрдп рдЖрдИрдкреА рдкрд░ рддрд╛рдЬрд╛ рд╕рддреНрд░ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреНрд░рд┐рдЧрд░ рдХрд░рддреА рд╣реИред
ts
const resp = await page.goto(hit.url, { waitUntil: "domcontentloaded", timeout: 60000 });
const status = resp?.status() ?? 0;
if (status === 403 || status === 429) {
throw new Error(`blocked: HTTP ${status} on ${hit.url}`);
}
await dismissEtsyConsent(page);
try {
await page.waitForSelector("h1", { timeout: 15000 });
} catch {
// 15 рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдХреЛрдИ h1 рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ DataDome рдЪреБрдиреМрддреА рдпрд╛ рдкреБрдирдГрдирд┐рд░реНрджреЗрд╢рди рдкреГрд╖реНрда рдХрд╛ рдЕрд░реНрде рд╣реИред
// рдлреЗрдВрдХреЗрдВ рддрд╛рдХрд┐ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рд▓реВрдк рдПрдХ рдирдП рд╕рддреНрд░ рдХреЛ рдЦреЛрд▓реЗ (= рдирдпрд╛ рдЖрд╡рд╛рд╕реАрдп рдЖрдИрдкреА)ред
throw new Error(`no h1 on ${hit.url} тАФ likely bot-challenge page`);
}
await delay(1500);
рдлрд┐рд░ рдкреВрд░реЗ рдкреГрд╖реНрда рдХреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдХреЗ рд▓реЗрдЬреА рд▓реЛрдбрд┐рдВрдЧ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдВред рд╡рд┐рд╡рд░рдг, рд╕рд╛рдордЧреНрд░реА рдФрд░ рд╢рд┐рдкрд┐рдВрдЧ рдЕрдиреБрднрд╛рдЧ рд╕рднреА рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдкрд░ рд▓реЛрдб рд╣реЛрддреЗ рд╣реИрдВред
рдЪрд░рдг 6 тАФ рдЕрд╡рд▓реЛрдХрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓реЗрдВ
Extractor рдХреА рдПрдХ рджреЛ-рдЪрд░рдгреАрдп рд╕рдВрд░рдЪрдирд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рдиреАрдЪреЗ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ extractor рдореЗрдВ рджреЛрд╣рд░рд╛рдИ рдЬрд╛рддреА рд╣реИ: рдмреНрд░рд╛рдЙрдЬрд░-рд╕рд╛рдЗрдб (рд╕реНрдХреНрд░реЙрд▓ + waitForFunction рддрд╛рдХрд┐ рд▓реЗрдЬреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рд╣рд╛рдЗрдбреНрд░реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ) тЖТ рдиреЛрдб-рд╕рд╛рдЗрдб (рдПрдХ рдмрд╛рд░ page.content() рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреГрд╖реНрда рдХрд╛ HTML рдЦреАрдВрдЪреЗрдВ рдФрд░ рдлрд┐рд░ cheerio рдХреЗ рд╕рд╛рде рдкрд╛рд░реНрд╕ рдХрд░реЗрдВ)ред рдпрд╣ рд╡рд┐рднрд╛рдЬрди рд╣рдореЗрдВ рдЬрдм рдЬрд░реВрд░рдд рд╣реЛ рддреЛ рд▓рд╛рдЗрд╡-DOM рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░ рдЬрдм рди рд╣реЛ рддреЛ рдЯрд╛рдЗрдк рдХреА рдЧрдИ, рдкрд░реАрдХреНрд╖рдг рдпреЛрдЧреНрдп рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
ts
async function extractOverview(page: Page): Promise<Partial<EtsyProduct>> {
// рдмреНрд░рд╛рдЙрдЬрд░-рд╕рд╛рдЗрдб: рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╡рд┐рд╡рд░рдг / рд╕рд╛рдордЧреНрд░реА / рд╢рд┐рдкрд┐рдВрдЧ
// рд▓реЗрдЬреА-рд▓реЛрдб рд╣реЛ рдЬрд╛рдП, рдлрд┐рд░ рдЦрд░реАрдж-рдмреЙрдХреНрд╕ рдХреЗ "рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ"
// рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░ рдХреЗ рдЖрдЧреЗ рд╣рд╛рдЗрдбреНрд░реЗрдЯ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред
await page.evaluate(`(function() {
var step = 500, total = document.body.scrollHeight, current = 0;
var iv = setInterval(function() {
current += step;
window.scrollTo(0, current);
if (current >= total) clearInterval(iv);
}, 200);
})()`);
await delay(3500);
try {
await page.waitForFunction(
// рддрдм рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ рдЬрдм рддрдХ рдХреЛрдИ рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдореВрд▓реНрдпwrapper рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдорд╛рди рди рд╣реЛ
// (рди рдХрд┐ "рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ" рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░ рдЬрд┐рд╕реЗ Etsy рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдП рджрд┐рдЦрд╛рддрд╛ рд╣реИ)ред
// рдЦрд░реАрдж-рдмреЙрдХреНрд╕ wrapper рдкрд░ рдХреЗрд╡рд▓ рдХреИрд╕рд┐рдВрдЧ рд╕реЗ рд╡реНрдпрд╛рдкрдХ рдЬрд╛рд▓ рдбрд╛рд▓рдиреЗ рд╕реЗ рдзреАрдореЗ
// рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░ рд╣рд┐рдЯ рджрд░ рдореЗрдВ рд╕реБрдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдЬрд╣рд╛рдБ рдореВрд▓реНрдп рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ .currency-value рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддрд╛ рд╣реИред
`(function(){
var sels = [
"[data-selector='price-only'] span.currency-value",
"div[data-buy-box-region='price'] span.currency-value",
"p[class*='price'] span.currency-value",
"span.currency-value"
];
for (var i = 0; i < sels.length; i++) {
var el = document.querySelector(sels[i]);
if (el && /^\\s*\\$?\\d/.test((el.textContent || '').trim())) return true;
}
return false;
})()`,
{ timeout: 15000 },
);
} catch { /* extractor рдЗрд╕рдХреЗ рдиреАрдЪреЗ рдЕрдкрдирд╛ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ */ }
// рдиреЛрдб-рд╕рд╛рдЗрдб: рдПрдХ рдмрд╛рд░ рдкреНрд░рд╕реНрддреБрдд HTML рдЦреАрдВрдЪреЗрдВ рдФрд░ cheerio рдХреЗ рд╕рд╛рде рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред
const $ = await parseWithCheerio(page);
const title = $("h1").first().text().trim() || null;
// рдореВрд▓реНрдп тАФ рддреАрди-рдЪрд░рдгреАрдп рд╢реНрд░реГрдВрдЦрд▓рд╛ред (1) рд╕реНрдкрд╖реНрдЯ `[data-selector='price-only']`
// рдЙрдкрдкрд░реНрдг рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрдВ рдЬрд┐рд╕реЗ Etsy рд╡рд░реНрддрдорд╛рди рдореВрд▓реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ; (2) рдкрд╣рд▓реЗ
// `span.currency-value` рдкрд░ рд╡рд╛рдкрд╕ рдЧрд┐рд░реЗрдВ рдЬрд┐рд╕рдХрд╛ рдкреВрд░реНрд╡рдЬ рд╕реНрдЯреНрд░рд╛рдЗрдХрдереНрд░реВ / рдореВрд▓-рдореВрд▓реНрдп
// wrappers рдирд╣реАрдВ рд╣реИ; (3) рдЕрдВрддрд┐рдо рдЙрдкрд╛рдп рд╢рд░реАрд░-рдЯреЗрдХреНрд╕реНрдЯ regexред
const isOriginalPriceWrapper = (el: any) =>
$(el).closest("[class*='strikethrough'], [class*='original'], s, .wt-text-strikethrough").length > 0;
let price: string | null = null;
const priceOnly = $("[data-selector='price-only'] span.currency-value").first();
if (priceOnly.length && /^\d/.test(priceOnly.text().trim())) {
price = priceOnly.text().trim();
}
if (!price) {
$("span.currency-value").each((_, el) => {
if (price) return false;
if (isOriginalPriceWrapper(el)) return;
const t = $(el).text().trim();
if (t && /^\d/.test(t)) price = t;
});
}
if (!price) {
const bodyPriceMatch = $("body").text().match(/(?:рдЕрдм\s+)?рдХреАрдордд:?\s*([$┬гтВм]?[\d.,]+)/i);
if (bodyPriceMatch) price = bodyPriceMatch[1].trim();
}
// рд░реЗрдЯрд┐рдВрдЧ тАФ рдХреЛрдИ рднреА aria-label рдЬреЛ "рд╕рд┐рддрд╛рд░рд╛", "рд░реЗрдЯрд┐рдВрдЧ", рдпрд╛ "рдХрд┐рддрдирд╛" рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддрд╛ рд╣реИред
let rating: number | null = null;
$("[aria-label*='star' i], [aria-label*='rating' i]").each((_, n) => {
if (rating !== null) return false;
const a = $(n).attr("aria-label") || "";
const rm = a.match(/(\d+(?:\.\d+)?)\s*(?:рдмрд╛рд╣рд░|рд╕рд┐рддрд╛рд░рд╛|рд░реЗрдЯрд┐рдВрдЧ)/i);
if (rm) rating = parseFloat(rm[1]);
});
Here is the translation of the provided English text into Hindi:
// рд╕реНрдерд┐рддрд┐ рдмреИрдЬ тАФ рдкреГрд╖реНрда рд╢рд░реАрд░ рдХреЛ regex рдХрд░реЗрдВред
const bodyText = $("body").text();
const isBestseller = /Bestseller/i.test(bodyText);
const isFreeShipping = /free shipping/i.test(bodyText);
const isStarSeller = /Star Seller/i.test(bodyText);
const inStock = !/out of stock|sold out/i.test(bodyText);
// рджреБрдХрд╛рди рд╕рд╛рдЗрдбрдХрд╛рд░ред
const shopLink = $("a[href*='/shop/']").first();
const shopName = shopLink.text().trim() || null;
const shopUrl = (shopLink.attr("href") || "").split("?")[0] || null;
return { title, _price_raw: price, rating, isBestseller, isFreeShipping, isStarSeller, inStock,
shop: { name: shopName, url: shopUrl } } as Partial<EtsyProduct>;
}
_price_raw рдЙрдкрд╕рд░реНрдЧ рдПрдХ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╣реИ: рдиреАрдЪреЗ рдХреА enrichProduct рдЗрд╕реЗ extractNumber рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЕрдВрддрд┐рдо JSON рдЬрд╛рд░реА рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрдЪреНрдЪреЗ-рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлрд╝реАрд▓реНрдб рдХреЛ рдорд┐рдЯрд╛ рджреЗрддрд╛ рд╣реИред рд╕реНрдирд┐рдкреЗрдЯ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реИ тАФ рдкреВрд░реНрдг extractOverview рдХреЛ index.ts рдореЗрдВ currency, discountPercent, reviewsCount, favoritesCount, description, materials, itemDetails, shippingFrom, processingTime, tags, listedDate рдФрд░ рдмрд╛рдХреА рджреБрдХрд╛рди рдлрд╝реАрд▓реНрдб рдХреЛ рднреА рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдкреВрд░реЗ рдкреГрд╖реНрда рдореЗрдВ рд╡рд╣реА cheerio-рдкреНрд░рдердо рдкреИрдЯрд░реНрди рд╣реИ, рдХреЗрд╡рд▓ рдЕрдзрд┐рдХ рдЪрдпрдирдХрд░реНрддрд╛ рд╣реИрдВред
рдПрдХ рдЫреЛрдЯрд╛ рдореБрджреНрд░рд╛-рдЯреЙрд▓рд░реЗрдВрдЯ extractNumber рд╕рд╣рд╛рдпрдХ "$24.99", "24,99 тВм", рдпрд╛ "1,234" рдХреЛ рдПрдХ рд╕рд╛рдл рдирдВрдмрд░ рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ тАФ Etsy рдореВрд▓реНрдп рд╕реНрдерд╛рдиреАрдп рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реЛрдХреНрд╕реА рджреЗрд╢ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдк рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рдХрд┐ рдЖрдкрдХреЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдХреНрд╖реЗрддреНрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рд╣реЛрдВред
рдЪрд░рдг 7 тАФ рд╕рдореАрдХреНрд╖рд╛рдПрдВ, рдЫрд╡рд┐рдпрд╛рдВ, рджреБрдХрд╛рди рд╕рд╛рдЗрдбрдХрд╛рд░, рд╡рд┐рд╡рд┐рдзрддрд╛рдПрдВ, рдмреНрд░реЗрдбрдХреНрд░рдВрдм, рд╕рдВрдмрдВрдзрд┐рдд рдЦреЛрдЬреЗрдВ
рд╕рдореАрдХреНрд╖рд╛рдПрдВред Etsy рдХреЗ рд╕рдореАрдХреНрд╖рд╛ рдХрд╛рд░реНрдб div[data-review-region] рдореЗрдВ рд░рд╣рддреЗ рд╣реИрдВ (DOM рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреЗ рд▓рд┐рдП div[class*='review-card'] рдФрд░ div[class*='review-item'] рдмреИрдХрдЕрдк рдХреЗ рд░реВрдк рдореЗрдВ)ред рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВ, рдлрд┐рд░ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдб рдХреЛ рд▓реЗрдЦрдХ / рд░реЗрдЯрд┐рдВрдЧ / рдкрд╛рда / рддрд┐рдерд┐ plus рддреАрди рд╕рдм-рд░реЗрдЯрд┐рдВрдЧ рдореЗрдВ рдореИрдк рдХрд░реЗрдВред
ts
async function extractReviews(page: Page, max: number): Promise<EtsyReview[]> {
// рдмреНрд░рд╛рдЙрдЬрд╝рд░-рдкрдХреНрд╖: рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╕реБрд╕реНрдд рд╕рдореАрдХреНрд╖рд╛ рдХрд╛рд░реНрдб рд░реЗрдВрдбрд░ рд╣реЛрдВред
for (let i = 0; i < 8; i++) {
const found = await page.evaluate(
`!!document.querySelector('[data-reviews-section], div#reviews, div[class*="reviews"]')`,
);
if (found) break;
await page.evaluate(() => window.scrollBy(0, 700));
await delay(700);
}
await delay(1500);
// рдиреЛрдб-рдкрдХреНрд╖: рдЕрдм рд╣рд╛рдЗрдбреНрд░реЗрдЯреЗрдб рдкреГрд╖реНрда рдХреЛ cheerio рдХреЗ рд╕рд╛рде рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред
const $ = await parseWithCheerio(page);
const out: EtsyReview[] = [];
$(
"div[data-review-region], div[class*='review-card'], div[class*='review-item'], li[class*='review']",
).each((_, card) => {
if (out.length >= max) return false;
const $card = $(card);
const cardText = $card.text();
// рдХрдИ рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд╕рдордЧреНрд░ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдЫреЛрдбрд╝реЗрдВред
if (cardText.length > 6000) return;
const author = $card.find("a[href*='/people/'], strong, p[class*='name']").first().text().trim() || null;
// рд░реЗрдЯрд┐рдВрдЧ: рдкрд╣рд▓реЗ `data-rating` рд╡рд┐рд╢реЗрд╖рддрд╛, рдлрд┐рд░ aria-labelред
let rating: number | null = null;
const $starEl = $card.find("[aria-label*='star' i], [data-rating]").first();
if ($starEl.length) {
const dr = $starEl.attr("data-rating");
if (dr) rating = parseFloat(dr);
else {
const rm = ($starEl.attr("aria-label") || "").match(/(\d+(?:\.\d+)?)/);
if (rm) rating = parseFloat(rm[1]);
}
}
// рдкрд╛рда: рд╕рдорд░реНрдкрд┐рдд рдЪрдпрдирдХрд░реНрддрд╛, рдлрд┐рд░ рдХрд╛рд░реНрдб рдореЗрдВ рд╕рдмрд╕реЗ рд▓рдВрдмрд╛ рдкреИрд░рд╛рдЧреНрд░рд╛рдлред
let text: string | null =
$card.find("p[class*='review-text'], div[class*='review-text'], div[id*='review-content']")
.first().text().trim() || null;
if (!text) {
let longest = "";
$card.find("p").each((_, p) => {
const pt = $(p).text().trim();
if (pt.length > longest.length && pt.length > 20) longest = pt;
});
text = longest || null;
}
// рддрд╛рд░реАрдЦ: рдкрд╣рд▓реЗ рд╕рдорд░реНрдкрд┐рдд рддрддреНрд╡, рдлрд┐рд░ рдПрдХ рдорд╣реАрдиреЗ рдХрд╛ рдирд╛рдо рдпрд╛ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ regexред
let date: string | null =
$card.find("span[class*='date'], time, p[class*='date']").first().text().trim() || null;
if (!date) {
const dm = cardText.match(/(\w{3,9}\s+\d{1,2},?\s+\d{4}|\d{1,2}\/\d{1,2}\/\d{2,4})/);
if (dm) date = dm[1];
}
// рд╕рдм-рд░реЗрдЯрд┐рдВрдЧ - рдХрд╛рд░реНрдб рдХреЗ рдЕрдВрджрд░ рд▓реЗрдмрд▓ рдХрд┐рдП рдЧрдП рдкрдВрдХреНрддрд┐рдпрд╛рдБред рд▓реЗрдмрд▓ рдореЗрд▓ рдЦрд╛рдПрдВ, рдмрдЧрд▓ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВред
const subRating = (label: string): number | null => {
let val: number | null = null;
$card.find("span, div, li").each((_, row) => {
if (val !== null) return false;
const t = $(row).text().toLowerCase();
if (t.includes(label) && t.length < 60) {
const sm = t.match(/(\d+(?:\.\d+)?)/);
if (sm) val = parseFloat(sm[1]);
}
});
return val;
};
// рд╕рдореАрдХреНрд╖рдХ-рджреНрд╡рд╛рд░рд╛ рдЕрдкрд▓реЛрдб рдХреА рдЧрдИ рддрд╕реНрд╡реАрд░реЗрдВ тАФ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд╕рдорд╛рди `il_fullxfull` рдЙрдиреНрдирдпрдиред
const photos: string[] = [];
const photoSeen = new Set<string>();
$card.find("img[src*='etsystatic'], img[data-src*='etsystatic']").each((_, img) => {
if (photos.length >= 6) return false;
let psrc = $(img).attr("src") || $(img).attr("data-src") || "";
if (!psrc) return;
This translation keeps the technical context intact while converting the content into Hindi.
hi
psrc = psrc.replace(/il_\d+xN/, "il_fullxfull").replace(/_\d+x\d+\./, "_1024x1024.");
if (!photoSeen.has(psrc)) { photoSeen.add(psrc); photos.push(psrc); }
});
out.push({
author, rating, text, date,
itemQuality: subRating("рдЖрдЗрдЯрдо рдЧреБрдгрд╡рддреНрддрд╛"),
shipping: subRating("рд╢рд┐рдкрд┐рдВрдЧ"),
customerService: subRating("рдЧреНрд░рд╛рд╣рдХ рд╕реЗрд╡рд╛"),
photos,
});
});
return out;
}
рдЪрд╛рд░ рдХрд╛рд░реНрдб-рдЪрдпрдирдХрд░реНрддрд╛ рд╡рд┐рдХрд▓реНрдк Etsy рдХреЗ рдЪрд▓ рд░рд╣реЗ A/B рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ - [data-review-region] рд╡рд░реНрддрдорд╛рди рд╣реЙрдЯ рдЪрдпрдирдХрд░реНрддрд╛ рд╣реИ; [class*='review-card'], [class*='review-item'] рдФрд░ li[class*='review'] рдкреБрд░рд╛рдиреЗ рдФрд░ рдирдП рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ рдЬреЛ рдЦрд╛рддреЗ рдФрд░ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЕрднреА рднреА рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред рд╢реАрд░реНрд╖ рдкрд░ рдХрд╛рд░реНрдбрдЯреЗрдХреНрд╕реНрдЯ рд▓рдВрдмрд╛рдИ рдЧрд╛рд░реНрдб рдЙрд╕ рдЕрдиреБрдкреНрд░рд╛рд╕рдХ рддрддреНрд╡реЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдЧрд▓рддреА рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рд╕рд╛рде рдХрдИ рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред
рдЪрд┐рддреНрд░ред Etsy рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдердВрдмрдиреЗрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЙрдиреНрд╣реЗрдВ рдкреВрд░реНрдг-рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП URL рдореЗрдВ рдЖрдХрд╛рд░ рдкреНрд░рддреНрдпрдп рдХреЛ рдмрджрд▓реЗрдВ: il_75x75 тЖТ il_fullxfull, рдпрд╛ _300x300.jpg тЖТ _1024x1024.jpgред рд╡рд╣реА рдЪрд┐рддреНрд░, рд▓реЗрдХрд┐рди рдЙрдЪреНрдЪ рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди, рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрдиреБрд░реЛрдз рдирд╣реАрдВред
ts
async function extractImages(page: Page, max: number): Promise<string[]> {
const $ = await parseWithCheerio(page);
const urls: string[] = [];
const seen = new Set<string>();
$("img[src*='etsystatic'], img[data-src*='etsystatic']").each((_, img) => {
if (urls.length >= max) return false;
let src = $(img).attr("src") || $(img).attr("data-src") || "";
if (!src) return;
// рдердВрдмрдиреЗрд▓ рдЖрдХрд╛рд░ рдкреНрд░рддреНрдпрдп рдХреЛ рд╕рдВрднрд╡ рд╣реЛ рддреЛ рдкреВрд░реНрдг рд░рд┐рдЬрд╝реЙрд▓реНрдпреВрд╢рди рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░реЗрдВред
src = src.replace(/il_\d+xN/, "il_fullxfull").replace(/_\d+x\d+\./, "_1024x1024.");
if (!seen.has(src)) { seen.add(src); urls.push(src); }
});
return urls;
}
img[data-src*='etsystatic'] рдкреИрдЯрд░реНрди рдЪрдпрдирдХрд░реНрддрд╛ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ - Etsy рд▓рд╛рдЬрд╝реА-рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ рдЧреИрд▓рд░реА рдердВрдмрдиреЗрд▓ рдХреЛ data-src рдХреЗ рдкреАрдЫреЗ рдФрд░ рдпрд╣ src рдХреЛ рддрдм рддрдХ рднрд░рддрд╛ рдирд╣реАрдВ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рд╡реЗ рджреГрд╢реНрдп рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдирд╣реАрдВ рдЖрддреЗред
рднрд┐рдиреНрдирддрд╛рдПрдВ, рдмреНрд░реЗрдбрдХреНрд░рдВрдм, рд╕рдВрдмрдВрдзрд┐рдд рдЦреЛрдЬреЗрдВред рддреАрди рдЕрддрд┐рд░рд┐рдХреНрдд рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░реНрд╕ рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдФрд░ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рдмрд╛рдж рдЪрд▓рддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ try/catch рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдПрдХ рдЫреВрдЯреЗ рд╣реБрдП рдЪрдпрдирдХрд░реНрддрд╛ рдПрдХ рдЦрд╛рд▓реА рд╕реВрдЪреА рдореЗрдВ рдШрдЯрд┐рдд рд╣реЛ рдЬрд╛рдП рдмрдЬрд╛рдп рдХрд┐ рдкрдВрдХреНрддрд┐ рдХреЛ рддреЛрдбрд╝рдиреЗ рдХреЗ:
extractVariations(page)тАФ рдЖрдХрд╛рд░ / рд░рдВрдЧ / рд╡реИрдпрдХреНрддрд┐рдХрд░рдг рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рдЦреАрдВрдЪрддрд╛ рд╣реИ рдЬреЛ рд╡рд┐рдХреНрд░реЗрддрд╛ рдЙрдЬрд╛рдЧрд░ рдХрд░рддрд╛ рд╣реИ, рдХреЗ рд░реВрдк рдореЗрдВ{name, options[]}[]рд╕реВрдЪреАред[data-selector*='variation']рдЙрдк-рдЯреНрд░реА рдореЗрдВ<select>рддрддреНрд╡реЛрдВ рд╕реЗ рднрд░рддрд╛ рд╣реИредextractBreadcrumbs(page)тАФ рд╢реНрд░реЗрдгреА рдорд╛рд░реНрдЧ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ (рдЬреИрд╕реЗ["Homepage", "Bags & Purses", "Wallets & Money Clips", "Wallets"]) рдПрдВрдХрд░ рдЯреИрдЧ рд╕реЗ рдЬреЛref=breadcrumb_listingрд▓рд╛рддреЗ рд╣реИрдВ рдЙрдирдХреЗ href рдореЗрдВред Etsy рдЗрдирдХреА рд▓рд┐рдкрдЯрдиреЗ рдореЗрдВ<nav aria-label="breadcrumb">рдирд╣реАрдВ рд▓рдЧрд╛рддреА - рдпреЗ рд╕рд╛рдорд╛рдиреНрдп рд▓рд┐рдВрдХ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдПрдХ рд╕рдВрджрд░реНрдн рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрддрд╛ рд╣реИредextractRelatedSearches(page)тАФ "рд╕рдВрдмрдВрдзрд┐рдд рдЦреЛрдЬреЛрдВ рдХрд╛ рдЕрдиреНрд╡реЗрд╖рдг рдХрд░реЗрдВ" рд▓рд┐рдВрдХ рдЬреЛ Etsy рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдиреАрдЪреЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреА рд╣реИред рдПрдХреНрд╕рдЯреНрд░реИрдХреНрдЯрд░ рдкреГрд╖реНрда рдХреЗ рдкреИрд░ рдкрд░ рд╡рд╛рдкрд╕ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд▓реЗрдЬрд╝реА-рд▓реЛрдбреЗрдб рдЯреИрдЧ рдЕрдиреБрднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ, рд▓рд┐рдВрдХ рдкрд╛рда рдХреЛ рдкрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗред Etsy A/B-рдЯреЗрд╕реНрдЯ рдЫрд╡рд┐-рдХреЗрд╡рд▓ рдЪрд┐рдкреНрд╕ (рдХреЛрдИ рдкрд╛рда рдирд╣реАрдВ) рдмрдирд╛рдо рдкрд╛рда-рд▓реЗрдмрд▓ рд╡рд╛рд▓реЗ рдЪрд┐рдкреНрд╕, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдлрд╝реАрд▓реНрдб рдХреЛ рд▓рдЧрднрдЧ рдЖрдзреЗ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░ рднрд░рдиреЗ рдХрд╛ рдЕрдиреБрдорд╛рди рдХрд░реЗрдВред
рд▓рд┐рд╕реНрдЯ рдХреА рдЧрдИ рддрд┐рдерд┐ рдФрд░ рджреБрдХрд╛рди рд╕реНрддрд░ рдХреБрд▓ extractOverview рдХреЗ рднреАрддрд░ рдЦреАрдВрдЪреА рдЬрд╛рддреА рд╣реИрдВ рдмреБрдирд┐рдпрд╛рджреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рдеред listedDate "Mon DD, YYYY" рдХреА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ Etsy рдЖрдЗрдЯрдо рд╡рд┐рд╡рд░рдг рдХреЗ рдкрд╛рд╕ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ - рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рд╣рд╛рд▓рд┐рдпрд╛ рдкреБрдирдГ рд╕реВрдЪреАрдмрджреНрдз/рд╕реНрд╡рдд: рдирд╡реАрдиреАрдХрд░рдг рдХреА рддрд┐рдерд┐ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рди рдХрд┐ рдореВрд▓ рдирд┐рд░реНрдорд╛рдг рддрд┐рдерд┐ред shop.reviewsCountShop рдХреЗрд╡рд▓ рддрдм рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм Etsy рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рджреБрдХрд╛рди рд╕реНрддрд░ рдкрд░ рднреЗрджрд┐рдд рдХрд░рддрд╛ рд╣реИ (рдХрдИ рд╕реВрдЪреА рд▓реЗрдЖрдЙрдЯ рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ - рд╡рд╣рд╛рдБ рдИрдорд╛рдирджрд╛рд░ рдЙрддреНрддрд░ рд╣реИ 'null')ред
рд╕рдореАрдХреНрд╖рдХ-рдЕрдкрд▓реЛрдб рдХреА рдЧрдИ рддрд╕реНрд╡реАрд░реЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореАрдХреНрд╖рд╛ рдХрд╛рд░реНрдб рдХреЗ рднреАрддрд░ рд╣реЛрддреА рд╣реИрдВред extractReviews рдЕрдм рдкреНрд░рддрд┐ рд╕рдореАрдХреНрд╖рд╛ 6 рддрд╕реНрд╡реАрд░реЗрдВ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрд╕реА il_fullxfull рдЕрдкрдЧреНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдЫрд╡рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдХреЛрдб рдХреЗ рд▓рд┐рдП рджреГрд╢реНрдп рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдпрд╛ рд╕рдореАрдХреНрд╖рд╛ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдЫрд╡рд┐ рдХреЙрд░реНрдкрд╕ рдорд┐рд▓рддрд╛ рд╣реИред
рдЪрд░рдг 8 - рдкреНрд░рддрд┐ рдЙрддреНрдкрд╛рдж рд╕рдореГрджреНрдзрд┐ рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ
рдПрдХ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░рдирд╛ рд╕реАрдзрд╛ рд╣реИред рдПрдХ рд╕реМ рдПрдХ рдХреЗ рдмрд╛рдж рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рддрдм рд╣реИ рдЬрдм рдЕрд╕реНрдерд╛рдпреА рд╡рд┐рдлрд▓рддрд╛рдПрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд▓рдЧрддреА рд╣реИрдВ - Etsy рдХрднреА-рдХрднреА рдПрдХ рдкреБрд░рд╛рдирд╛ рдХреИрд╢ рджреЗрддрд╛ рд╣реИ, h1 рдкреВрд░реА рдирд╣реАрдВ рд╣реЛрддреА, рдПрдХрд▓ рдкреНрд░реЙрдХреНрд╕реА рдЕрдиреБрд░реЛрдз рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпреЗ рд╕рднреА рдХреЛ рдкреИрдорд╛рдиреЗ рдкрд░ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рд╕реБрд░рдХреНрд╖рд╛рддреНрдордХ рдкрд░рддреЗрдВ рд╣реИрдВ:
рдкреНрд░рддреНрдпреЗрдХ рдЙрддреНрдкрд╛рдж рдХреЗ рд▓рд┐рдП рддрд╛рдЬрд╝рд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ред рдЬрдм рдЦреЛрдЬ рд╣рд┐рдЯ рдПрдХрддреНрд░рд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рд╕рдореГрджреНрдзрд┐ рдХреЗ рд▓рд┐рдП рдирдП Scrapeless рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рддреНрд░ рдХреЛ рдЦреЛрд▓реЗрдВред рд░рд╛рдЬреНрдп рдЙрддреНрдкрд╛рджреЛрдВ рдХреЗ рдмреАрдЪ рд▓реАрдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рддреНрд░-рд╕реНрддрд░реАрдп рддреНрд░реБрдЯрд┐ рджреМрдбрд╝ рдХреЗ рдмрд╛рдХреА рдХреЛ рдЦрд░рд╛рдм рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рддрд╛рдЬрд╝рд╛ рд╕рддреНрд░ рдПрдХ рдирдпрд╛ рдирд┐рд╡рд╛рд╕ IP рдШреБрдорд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм DataDome рдПрдХ IP рдкрд░ 403 рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрдЧрд▓реА рдХреЛрд╢рд┐рд╢ рдПрдХ рдЕрд▓рдЧ рдкрд░ рдмреИрдарддреА рд╣реИред
cfg.maxRetries рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдкреНрд░рдпрд╛рд╕реЛрдВ рддрдХ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ 10) рдмрдврд╝рддреА рд╣реБрдИ рдмреИрдХрдСрдл рдХреЗ рд╕рд╛рдеред рдПрдХ рд╕реНрд╡рдЪреНрдЫ рд░рди рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрддреНрдкрд╛рдж рдкрд╣рд▓реЗ рдкреНрд░рдпрд╛рд╕ рдкрд░ рд╕рдлрд▓ рд╣реЛрддреЗ рд╣реИрдВ; рдПрдХ рдЦрд░рд╛рдм-IP рд░рди рдкрд░, рд╕рддреНрд░ рдХреЛ рдПрдХ рд╕рд╛рдл рдирд┐рд╡рд╛рд╕реА IP рдкрд░ рдмреИрдардиреЗ рдореЗрдВ 3тАУ6 рдкреНрд░рдпрд╛рд╕ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВред рдЙрдЪреНрдЪ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдмрдЬрдЯ 50% рд╣рд┐рдЯ рджрд░ рдФрд░ 100% рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рд╣реИред
**рд╢реНрд░реЗрдгреАрдмрджреНрдз рддреНрд░реБрдЯрд┐ рд╡рд░реНрдЧреАрдХрд░рдгред** `categorizeError(err)` рд╣рд░ рдХрдЪреНрдЪреА рд╡рд┐рдлрд▓рддрд╛ (HTTP 403/404/429, `ERR_SSL_*`, `ERR_TUNNEL_*`, h1-рдорд┐рд╕рд┐рдВрдЧ, рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЯрд╛рдЗрдордЖрдЙрдЯ, WSS рд╣реИрдВрдбрд╢реЗрдХ) рдХреЛ рдЖрда `ScrapeErrorKind` рдорд╛рдиреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ `retryable: boolean` рдлреНрд▓реИрдЧ рд╣реЛрддрд╛ рд╣реИред рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдпреЛрдЧреНрдп рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдмреИрдХрдСрдл рд▓реВрдк рдХреЛ рдлреАрдб рдХрд░рддреА рд╣реИрдВ; рдЧреИрд░-рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдпреЛрдЧреНрдп рддреНрд░реБрдЯрд┐рдпрд╛рдБ (рдЬреИрд╕реЗ рдХрд┐ рд╕реНрдЯреЗрд▓ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░ HTTP 404) рддреБрд░рдВрдд рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИрдВред рдЬрдм рд╕рднреА рдкреНрд░рдпрд╛рд╕ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЙрддреНрдкрд╛рдж `error: { kind, message, attempts }` рдХреЗ рд╕рд╛рде рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдХреЛрдб рдпрд╣ рдЬрд╛рди рд╕рдХреЗ рдХрд┐ рдПрдХ рдкрдВрдХреНрддрд┐ рдЕрдЪрд╛рдирдХ рдЦрд╛рд▓реА рдХреНрдпреЛрдВ рдЖрдИред
```ts
// рдореБрдЦреНрдп рд▓реВрдк рдХреЗ рдЕрдВрджрд░, рдкреНрд░рддреНрдпреЗрдХ рдЦреЛрдЬ рд╣рд┐рдЯ h рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ (i рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд):
const MAX_ATTEMPTS = cfg.maxRetries; // рдбрд┐рдлрд╝реЙрд▓реНрдЯ 10
let p: EtsyProduct | null = null;
let lastError: ScrapeErrorInfo | null = null;
let attemptsUsed = 0;
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
attemptsUsed = attempt;
let eb;
try {
eb = await openBrowser(`etsy-enrich-${i}-${attempt}-${Date.now()}`, cfg);
} catch (e: any) {
lastError = categorizeError(new Error(`openBrowser рд╡рд┐рдлрд▓: ${e?.message ?? e}`));
log(` рдкреНрд░рдпрд╛рд╕ ${attempt}/${MAX_ATTEMPTS} тАФ ${lastError.kind}: ${lastError.message.slice(0, 120)}`);
if (!lastError.retryable) break;
if (attempt < MAX_ATTEMPTS) await delay(Math.max(cfg.retryInitialBackoffMs, 3000));
continue;
}
try {
p = await enrichProduct(eb, h, cfg);
if (p.title) { lastError = null; break; }
lastError = categorizeError(new Error(`no h1 on ${h.url} тАФ title was null`));
} catch (e: any) {
lastError = categorizeError(e);
log(` рдкреНрд░рдпрд╛рд╕ ${attempt}/${MAX_ATTEMPTS} тАФ ${lastError.kind}: ${lastError.message.slice(0, 120)}`);
if (!lastError.retryable) break; // рдЧреИрд░-рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдпреЛрдЧреНрдп: 404, рдЖрджрд┐ред рдЬрд▓реНрджреА рд╡рд┐рдлрд▓ред
} finally {
await eb.close().catch(() => {});
}
if (attempt < MAX_ATTEMPTS) {
// рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдмрдврд╝рддреА рдмреИрдХрдСрдлред рдбрд┐рдлрд╝реЙрд▓реНрдЯ (3000, 1500, 500) рдХрд╛ рдкрд░рд┐рдгрд╛рдо
// 5s, 8s, 12s, 17s, 23s, 30s, 38s, 47s, 57s рдХреЗ рдмреАрдЪ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХрд╛ рд╣реЛрддрд╛ рд╣реИред
const backoff = cfg.retryInitialBackoffMs
+ attempt * (cfg.retryBackoffLinearMs + attempt * cfg.retryBackoffQuadraticMs);
await delay(backoff);
}
}
if (!p || !p.title) {
p = emptyProduct(h.url);
p.rank = h.rank;
if (lastError) {
p.error = { kind: lastError.kind, message: lastError.message.slice(0, 200), attempts: attemptsUsed };
}
}
products.push(p);
// рдЙрддреНрдкрд╛рджреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░рд╛рд▓ (рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп) тАФ рд▓рдЧрд╛рддрд╛рд░ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреЛ рддреЛрдбрд╝рддрд╛ рд╣реИ
// рдиреЗрд╡рд┐рдЧреЗрд╢рдиреЛрдВ рдХреЛ рддрд╛рдХрд┐ рд╕рддреНрд░ рдХрд╛ рдкреИрдЯрд░реНрди DataDome рдХреЗ рд▓рд┐рдП рдмреЛрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХрд╛ рди рджрд┐рдЦреЗред
if (i < hits.length - 1) await delay(cfg.interProductDelayMs);
рдХреБрдЫ рд╡рд┐рд╡рд░рдг рдЬреЛ рдкреИрдорд╛рдиреЗ рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВ: рд╕рддреНрд░ рдХрд╛ рдирд╛рдо рдЙрддреНрдкрд╛рдж рдЕрдиреБрдХреНрд░рдорд╛рдВрдХ i рдФрд░ Date.now() рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рддрд╛рдЬрд╝рд╛ рд╕рддреНрд░реЛрдВ рдХреЗ рдмреАрдЪ рдЯрдХрд░рд╛рд╡ рди рд╣реЛ; openBrowser рдХреЛ рдЕрдкрдиреА рдЦреБрдж рдХреА try/catch рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рд╡рд┐рдлрд▓ WSS рд╣реИрдВрдбрд╢реЗрдХ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХреЛ рди рдЫреЛрдбрд╝ рджреЗ; eb.close() рдХреЛ .catch(() => {}) рдХреЗ рд╕рд╛рде рд╕рдорд╛рд╣рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рддреНрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдорд░ рдЪреБрдХрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрдк рдЗрд╕реЗ рдмрдВрдж рдХрд░ рд░рд╣реЗ рд╣реЛрддреЗ рд╣реИрдВ; рдмрдврд╝рддреА рдмреИрдХрдСрдл рдЗрддрдиреА рдзреАрд░реЗ-рдзреАрд░реЗ рдмрдврд╝рддреА рд╣реИ рдХрд┐ рдЖрд╕рд╛рди рдЙрддреНрдкрд╛рдж рддреЗрдЬреА рд╕реЗ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рдХрдард┐рди рдЙрддреНрдкрд╛рджреЛрдВ рдХреЛ DataDome рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрдИ рд╕реЗрдХрдВрдб рдХрд╛ рд╡рд┐рдВрдбреЛ рдорд┐рд▓рддрд╛ рд╣реИ; рдФрд░ рдЙрддреНрдкрд╛рджреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░рд╛рд▓ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рдЕрд╡рд╕рд░ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИред
рдЖрда рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░
рд╣рд░ рд╡рд┐рдлрд▓ рдЙрддреНрдкрд╛рдж рдПрдХ error: { kind, message, attempts } рдСрдмреНрдЬреЗрдХреНрдЯ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред kind рдлрд╝реАрд▓реНрдб рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдХреЛрдб рдХреЛ рдпрд╣ рдмрддрд╛рддреА рд╣реИ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреИрд╕реЗ рджреЗрдиреА рд╣реИ рдмрд┐рдирд╛ рдореБрдХреНрдд-рдлреЙрд░реНрдо рд╕рдВрджреЗрд╢ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд┐рдП:
kind |
рдЯреНрд░рд┐рдЧрд░ | рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдпреЛрдЧреНрдп |
|---|---|---|
blocked |
HTTP 403 рдпрд╛ 429 тАФ DataDome рдпрд╛ рджрд░ рд╕реАрдорд╛ | тЬЕ рд╣рд╛рдБ |
not-found |
HTTP 404 тАФ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рд╣рдЯрд╛ рджреА рдЧрдИ рдпрд╛ рдХрднреА рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рдирд╣реАрдВ рдереА | тЭМ рдирд╣реАрдВ (рдЬрд▓реНрджреА рд╡рд┐рдлрд▓) |
tls |
ERR_SSL_* / ERR_CERT_* тАФ рдЕрд╕реНрдерд╛рдпреА рдкреНрд░реЙрдХреНрд╕реА рд╣рд┐рдХрдк |
тЬЕ рд╣рд╛рдБ |
network |
ERR_TUNNEL / ERR_CONNECTION_* / ERR_ABORTED |
тЬЕ рд╣рд╛рдБ |
no-h1 |
рдкреГрд╖реНрда рд▓реЛрдб рд╣реБрдЖ рд▓реЗрдХрд┐рди <h1> рдХрднреА рдирд╣реАрдВ рдЖрдпрд╛ тАФ рд╕реЙрдлреНрдЯ рдЪреИрд▓реЗрдВрдЬ рдкреГрд╖реНрда |
тЬЕ рд╣рд╛рдБ |
timeout |
рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЯрд╛рдЗрдордЖрдЙрдЯ pageTimeoutMs рд╕реЗ рдЕрдзрд┐рдХ |
тЬЕ рд╣рд╛рдБ |
open-browser |
Scrapeless рдХреЗ рд▓рд┐рдП WSS рд╣реИрдВрдбрд╢реЗрдХ рд╡рд┐рдлрд▓ | тЬЕ рд╣рд╛рдБ |
unknown |
рдХреБрдЫ рдФрд░ | тЬЕ рд╣рд╛рдБ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ) |
рд╣рд░ рдЯрди рдХреЗ рдХреЛрдг рдХреЛ рдЯреНрдпреВрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
рд╕рднреА рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдФрд░ рддрд╛рд▓рд┐рдХрд╛ рдорд╛рди ScraperInput рдкрд░ рд░рд╣рддреЗ рд╣реИрдВ тАФ рдХреБрдЫ рднреА рд╣рд╛рд░реНрдб-рдХреЛрдбреЗрдб рдирд╣реАрдВ рд╣реИред рдЬрдм рдЖрдкрдХреЛ рд╕рдЦреНрдд рдпреЛрдЬрдирд╛ рдкрд░ рдкреВрд░реНрд╡рд╛рдиреБрдореЗрдп рдереНрд░реВрдкреБрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рдпрд╛ рдХрдард┐рди рд▓рдХреНрд╖реНрдп рдкрд░ рдЕрдзрд┐рдХ рдЖрдХреНрд░рд╛рдордХ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ, рддрдм рдЗрдиреНрд╣реЗрдВ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░реЗрдВ:
| CONFIG рдлрд╝реАрд▓реНрдб | рдбрд┐рдлрд╝реЙрд▓реНрдЯ | рднреВрдорд┐рдХрд╛ |
|---|---|---|
maxRetries |
10 |
рдЙрддреНрдкрд╛рдж рдкрд░ рдХреБрд▓ рдкреНрд░рдпрд╛рд╕ рдЬреЛ рд╣рд╛рд░ рдорд╛рдирдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реЛрддреЗ рд╣реИрдВ |
retryInitialBackoffMs |
3000 |
рдмрдврд╝рддреЗ-рдмреИрдХрдСрдл рдлрд╝рд╛рд░реНрдореВрд▓реЗ рдХрд╛ рдЖрдзрд╛рд░ |
retryBackoffLinearMs |
1500 |
рд░реИрдЦрд┐рдХ рд╢рдмреНрдж |
retryBackoffQuadraticMs |
500 |
рджреНрд╡рд┐рдШрд╛рддреАрдп рд╢рдмреНрдж |
interProductDelayMs |
3000 |
рд▓рдЧрд╛рддрд╛рд░ рдЙрддреНрдкрд╛рдж рд╕рдВрд╡рд░реНрджреНрдзрдиреЛрдВ рдХреЗ рдмреАрдЪ рд░реБрдХрд╛ рд╣реБрдЖ |
pageTimeoutMs |
60000 |
page.goto рдЯрд╛рдЗрдордЖрдЙрдЯ |
h1TimeoutMs |
15000 |
waitForSelector("h1") рдЯрд╛рдЗрдордЖрдЙрдЯ |
postLoadDelayMs |
1500 |
h1 рджрд┐рдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдирд┐рд╖реНрдХрд░реНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ рдХреА рджреЗрд░реА |
рдЖрдкрдХреЛ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ
рдкреНрд░рддреНрдпреЗрдХ рдЙрддреНрдкрд╛рдж рдХреЗ рд▓рд┐рдП рдПрдХ рдлреНрд▓реИрдЯ JSON рдСрдмреНрдЬреЗрдХреНрдЯред рдЬрд╛рдирдмреВрдЭрдХрд░ рдЪреМрдбрд╝рд╛, рддрд╛рдХрд┐ рд╡рд╣реА рд╕реНрдХреНрд░реИрдкрд░ рдмрд┐рдирд╛ рджреВрд╕рд░реЗ рдЪрд░рдг рдХреЗ рд╣рд░ рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЗ рдХреЛ рдлреАрдб рдХрд░ рд╕рдХреЗред
"рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯ" рдЦреЛрдЬ рдкрд░ рдЗрд╕ рд╕рдЯреАрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗ рдЪрд▓рдиреЗ рд╡рд╛рд▓рд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд╣рд▓рд╛ рдкрд░рд┐рдгрд╛рдо:
json
{
"listingId": "547491922",
json
{
"title": "рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯтАврд╡реЙрд▓реЗрдЯтАврдкреБрд░реБрд╖ рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯтАврдорд┐рдирд┐рдорд▓рд┐рд╕реНрдЯ рд╡реЙрд▓реЗрдЯтАврд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡реЙрд▓реЗрдЯтАврд▓реЗрджрд░ рдПрдирд┐рд╡рд░реНрд╕рд░реАтАврд╕реНрд▓рд┐рдо рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯтАврдкреБрд░реБрд╖ рд╡реЙрд▓реЗрдЯ",
"url": "https://www.etsy.com/listing/547491922/leather-walletwalletman-leather",
"rank": 1,
"price": 5.52,
"originalPrice": 68.99,
"currency": "$",
"discountPercent": 92,
"inStock": false,
"rating": 4.9,
"reviewsCount": 929,
"favoritesCount": 850,
"isBestseller": false,
"isFreeShipping": false,
"isStarSeller": true,
"tags": ["рдмреНрд░рд╛рдЗрдбреНрд╕рдореЗрдб рдЙрдкрд╣рд╛рд░", "рдЧroomsmen рдЙрдкрд╣рд╛рд░", "рд╢рд╛рджреА рдХреЗ рдЙрдкрд╣рд╛рд░", "рдПрдВрдЧреЗрдЬрдореЗрдВрдЯ рдЙрдкрд╣рд╛рд░"],
"materials": [],
"shop": {
"name": "TexasValleyLeather",
"url": "https://www.etsy.com/shop/TexasValleyLeather",
"location": null,
"totalSales": null,
"openedYear": null,
"reviewsCountShop": null
},
"images": [
"https://i.etsystatic.com/15980284/r/il/2456a5/3164786673/il_fullxfull.3164786673_roeh.jpg",
"... 4 рдФрд░ рдпреВрдЖрд░рдПрд▓"
],
"variations": [
{ "name": "рд╡реНрдпрдХреНрддрд┐рдЧрддрдХрд░рдг", "options": ["рд╣рд╛рдБ, рдЙрддреНрдХреАрд░реНрдгрди рдЬреЛрдбрд╝реЗрдВ", "рдирд╣реАрдВ, рдзрдиреНрдпрд╡рд╛рдж"] },
{ "name": "рд░рдВрдЧ рд╡рд┐рдХрд▓реНрдк", "options": ["рдЪреЗрд╕реНрдЯрдирдЯ", "рдХрд╛рд▓рд╛", "рдЯреИрди"] }
],
"breadcrumbs": ["рдореБрдЦрдкреГрд╖реНрда", "рдмреИрдЧ рдФрд░ рдкрд░реНрд╕", "рд╡реЙрд▓реЗрдЯ рдФрд░ рдкреИрд╕реЗ рдХреНрд▓рд┐рдк", "рд╡реЙрд▓реЗрдЯ"],
"relatedSearches": ["рдкреБрд░реБрд╖реЛрдВ рдХреЗ рд▓рд┐рдП рд▓реЗрджрд░ рд╡реЙрд▓реЗрдЯ", "рд╕реНрд▓реАрдХ рдкреБрд░реБрд╖ рд╡реЙрд▓реЗрдЯ", "рдХрд╕реНрдЯрдо рд╕реНрд▓рд┐рдо рд▓реЗрджрд░ рдмрд┐рдлреЛрд▓реНрдб рд╡реЙрд▓реЗрдЯ"],
"listedDate": "15 рдЕрдкреНрд░реИрд▓, 2026",
"priceBucket": null,
"reviews": [
{
"author": "рд▓рд┐рдЬ",
"rating": 0,
"text": "рдЬреИрд╕рд╛ рд╡рд░реНрдгрд┐рдд рдерд╛ рдФрд░ рддреЗрдЬреА рд╕реЗ рднреЗрдЬрд╛ рдЧрдпрд╛ред рдзрдиреНрдпрд╡рд╛рдж!",
"date": "12 рдЕрдкреНрд░реИрд▓, 2026",
"itemQuality": null,
"shipping": null,
"customerService": null,
"photos": []
},
"... 9 рдФрд░ рд╕рдореАрдХреНрд╖рд╛рдПрдБ"
],
"error": null,
"scrapedAt": "2026-04-16T17:09:48.919Z"
}
рдПрдХ рд╕рдорд╛рди рдХрдиреЗрдХреНрд╢рди рд╣реЗрд▓реНрдкрд░, рд░рд┐рдЯреНрд░рд╛рдИ рдЯреИрдХреНрд╕реЛрдиреЛрдореА рдФрд░ рд╕рддреНрд░-рдкреНрд░рддрд┐-рд▓рдХреНрд╖реНрдп рдкреИрдЯрд░реНрди рд╡реНрдпрд╛рдкрдХ Scrapeless рдХреИрдЯрд╛рд▓реЙрдЧ рдореЗрдВ рдлреИрд▓рд╛ рд╣реБрдЖ рд╣реИ: рдЗрд╕ рдЧрд╛рдЗрдб рдХреЛ Scrapeless MCP Server рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реЗрдВ рддрд╛рдХрд┐ Etsy рдбреЗрдЯрд╛ рдХреЛ рд╕реАрдзреЗ рдПрдХ AI рдПрдЬреЗрдВрдЯ рдХреЗ рдЯреВрд▓ рд╕рд░рдлреЗрд╕ рдореЗрдВ рд╡рд╛рдпрд░реНрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдпрд╛ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда AI рдПрдЬреЗрдВрдЯреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╡реНрдпрд╛рдкрдХ рд╕реНрд╡рдЪрд╛рд▓рди рдХрд╛рд░реНрдпрдкреНрд░рд╡рд╛рд╣реЛрдВ рдореЗрдВ рдХреИрд╕реЗ рдкреНрд▓рдЧ рд╣реЛрддреА рд╣реИред
proxyCountry рдХреЛ рдЙрд╕ рдорд╛рд░реНрдХреЗрдЯрдкреНрд▓реЗрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд┐рди рдХрд░реЗрдВ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдк рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рдг рдЪрд╛рд╣рддреЗ рд╣реИрдВ, sessionRecording: "true" рд░рдЦрдХрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдХреЛрдИ рднреА рд╢реВрдиреНрдп рдкрдВрдХреНрддрд┐ рдХреЛ рдПрдВрдб-рдЯреВ-рдПрдВрдб рдлрд┐рд░ рд╕реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдЕрдиреБрдкрд╕реНрдерд┐рдд рдлрд╝реАрд▓реНрдб (materials, shop.location, reviews[].itemQuality) рдХреЛ рдЫреВрдЯреА рдбреЗрдЯрд╛ рдмрдЧ рдХреЗ рдмрдЬрд╛рдп рдирд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЯреНрд░реАрдЯ рдХрд░реЗрдВ, рдФрд░ рдмрдврд╝рддреА рдмреИрдХрдСрдл рдХреЛ рдЕрд╕реНрдерд╛рдпреА 403s рдХреЛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рдиреЗ рджреЗрдВред рдпрд╣реА рдкреВрд░рд╛ рдкреНрд▓реЗрдмреБрдХ рд╣реИред
рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ AI-рд╕рдВрдЪрд╛рд▓рд┐рдд рдбреЗрдЯрд╛ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ?
рд╣рдорд╛рд░реЗ рд╕рдореБрджрд╛рдп рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВ рддрд╛рдХрд┐ рдПрдХ рдореБрдлреНрдд рдпреЛрдЬрдирд╛ рдХрд╛ рджрд╛рд╡рд╛ рдХрд░реЗрдВ рдФрд░ рдЙрди рдбреЗрд╡рд▓рдкрд░реНрд╕ рд╕реЗ рдЬреБрдбрд╝реЗрдВ рдЬреЛ Etsy рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ: Discord ┬╖ Telegram.
app.scrapeless.com рдкрд░ рд╕рд╛рдЗрди рдЕрдк рдХрд░реЗрдВ рдореБрдлреНрдд Scraping Browser рд░рдирдЯрд╛рдЗрдо рдХреЗ рд▓рд┐рдП тАФ рдореБрдлреНрдд рдЯреНрд░рд╛рдпрд▓ рдкрд░ 100 рдШрдВрдЯреЗ рддрдХ рдХрд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд░рди тАФ рдФрд░ рдКрдкрд░ рджрд┐рдП рдЧрдП рдкреИрдЯрд░реНрди рдХреЛ Etsy рд╢реНрд░реЗрдгрд┐рдпреЛрдВ, рджреБрдХрд╛рдиреЛрдВ рдФрд░ рдХреАрд╡рд░реНрдб рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВ рдЬрд┐рдирдХреА рдЖрдкрдХреЗ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╢реНрди
рдХреНрдпрд╛ Etsy рд╕реЗ рдбреЗрдЯрд╛ рд╕реНрдХреНрд░реИрдк рдХрд░рдирд╛ рдХрд╛рдиреВрдиреА рд╣реИ?
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рдбреЗрдЯрд╛ рдХреЛ рдореВрд▓реНрдп рдирд┐рдЧрд░рд╛рдиреА рдФрд░ рд╢реЛрдз рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реИрдк рдХрд░рдирд╛ рдЖрдорддреМрд░ рдкрд░ рдХрд╛рдиреВрдиреА рд╣реИ, рдмрд╢рд░реНрддреЗ рдЖрдк Etsy рдХреА рдЙрдкрдпреЛрдЧ рдХреА рд╢рд░реНрддреЛрдВ рдХрд╛ рд╕рдореНрдорд╛рди рдХрд░реЗрдВ рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░рдиреЗ рд╕реЗ рдмрдЪреЗрдВред Scrapeless рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдкрдХреЗ рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдЧрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рд░реНрд╡рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рд╕рдореНрдорд╛рди рдХрд░рдиреЗ рдХреА рд╕реБрдирд┐рд╢реНрдЪрд┐рддрддрд╛ рджреЗрддрд╛ рд╣реИред
Scrapeless Etsy рдХреЗ DataDome рд╕реБрд░рдХреНрд╖рд╛ рдореЗрдВ рдХреИрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ?
рдорд╛рдирдХ рдкреНрд░реЙрдХреНрд╕рд┐рдпреЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, Scrapeless рдкреВрд░рд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдФрд░ TLS рд╣реИрдВрдбрд╢реЗрдХ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдЖрдкрдХрд╛ рд╕реНрдХреНрд░реИрдкрд░ рдПрдХ рдЕрд╕рд▓реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдЕрдкреНрд░рднреЗрджреНрдп рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЖрдк DataDome рдХреА sofisticaded рдмреЙрдЯ рдбрд┐рдЯреЗрдХреНрд╢рди рдХреЛ рдмрд┐рдирд╛ рдореИрдиреБрдЕрд▓ рд╕реНрдЯреАрд▓реНрде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╢реНрди 1: рдХреНрдпрд╛ Etsy рдХреЛ рд╕реНрдХреНрд░реИрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдХреНрд╕реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?
рдЬреНрдпрд╛рдВ. рдмрд┐рдирд╛ рдПрдХ рдЖрд╡рд╛рд╕реАрдп рдкреНрд░реЙрдХреНрд╕реА рдХреЗ, DataDome рдЬрд▓реНрджреА рд╣реА рдбреЗрдЯрд╛ рд╕реЗрдВрдЯрд░ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреЛ рдЭрдВрдбреА рджрд┐рдЦрд╛рддрд╛ рд╣реИ тАФ рдлрд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдФрд░ IP-рдкреНрд░рддрд┐рд╖реНрдард╛ рд╕рдВрдпреЛрдЬрди рдЖрдорддреМрд░ рдкрд░ рдЕрд╕реНрд╡реАрдХреГрддрд┐ рдмрд╛рд▓реНрдЯреА рдореЗрдВ рд╕реНрдХреЛрд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реАрдзреЗ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЕрдиреБрд░реЛрдз /listing/ рдкреГрд╖реНрдареЛрдВ рдкрд░ HTTP 403 рдХреЗ рд╕рд╛рде рдПрдХ JavaScript рдЪреБрдиреМрддреА рдкреГрд╖реНрда рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред Scrapeless Scraping Browser рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЖрд╡рд╛рд╕реАрдп рдкреНрд░реЙрдХреНрд╕реА рд╣реЛрддреЗ рд╣реИрдВ тАФ рд╣рд░ рд╕рддреНрд░ рдЪреБрдиреЗ рд╣реБрдП рджреЗрд╢ рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдЖрд╡рд╛рд╕реАрдп IP рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд░реВрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд▓рдЧрд╛рддрд╛рд░ рддрд╛рдЬрд╝рд╛ рд╕рддреНрд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЕрджреНрд╡рд┐рддреАрдп рдЖрдЙрдЯрдмрд╛рдЙрдВрдб IPs (api.ipify.org рдкреНрд░реЙрдм) рд▓реМрдЯрд╛рдиреЗ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░рд╛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдкреНрд░рд╢реНрди 2: рдореИрдВ рдкрд┐рдЫрд▓реЗ рд░рди рдореЗрдВ рд╕реНрдХреНрд░реИрдкрд░ рдиреЗ рдХреНрдпрд╛ рдХрд┐рдпрд╛, рдХреИрд╕реЗ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ?
рдЗрд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╣рд░ рд╕рддреНрд░ WSS URL рдкрд░ sessionRecording: "true" рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП Scrapeless рд╣рд░ рдкреГрд╖реНрда рдХрд╛ рдПрдХ рдкреВрд░реНрдг рд╡реАрдбрд┐рдпреЛ-рд╢реИрд▓реА рдХрд╛ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рд╕рд╣реЗрдЬрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХреНрд▓рд╛рдЙрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдиреЗ рдЫреБрдЖ тАФ рд╕реНрдХреНрд░реЙрд▓ рд╕реНрдерд┐рддрд┐, DOM рд╕реНрдерд┐рддрд┐ рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ред рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдХреЛ app.scrapeless.com тЖТ Scraping Browser тЖТ Sessions рдкрд░ рдЦреЛрдЬреЗрдВ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдпрд╛рд╕ (рдЬреИрд╕реЗ etsy-enrich-3-2-1713198231047) рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реИрдкрд░ рд▓реЙрдЧ рджреНрд╡рд╛рд░рд╛ sessionName рдорд╛рди рд╕реЗ рдореЗрд▓ рдХрд░реЗрдВред
рдпрджрд┐ рдбреИрд╢рдмреЛрд░реНрдб "рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдЕрд╕реНрд╡реАрдХреГрдд тАФ рд╕рддреНрд░ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП 'рд╡реЗрдм рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ' рд╕рдХреНрд╖рдо рдХрд░реЗрдВ" рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрдкрдиреЗ Scrapeless рдЦрд╛рддрд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдкреГрд╖реНрда рдкрд░ рд╡реЗрдм рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдЯреЙрдЧрд▓ рдЪрд╛рд▓реВ рдХрд░реЗрдВред рдпрд╣ рд╣рд░ рдпреЛрдЬрдирд╛ рдкрд░ рдореБрдлреНрдд рд╣реИ; рдпрд╣ рдХреЗрд╡рд▓ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдмрдВрдж рд╣реИред рдПрдХ рдмрд╛рд░ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдкрд░, рд╕рднреА рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕рддреНрд░ рдЕрдкрдиреЗ рдЖрдк рд░рд┐рдХреЙрд░реНрдб рд╣реЛрддреЗ рд╣реИрдВ тАФ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рджреМрд░рд╛рди рдЬреЛ рдкрд┐рдЫрд▓реЗ рд╕рддреНрд░ рдЪрд▓рд╛рдП рдЧрдП, рдЙрдиреНрд╣реЗрдВ рд░реЗрдЯреНрд░реЛрд╕реНрдкреЗрдХреНрдЯрд┐рд╡рд▓реА рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ред
рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкрдВрдХреНрддрд┐ title: null рдХреЗ рд╕рд╛рде рдХреНрдпреЛрдВ рд▓реМрдЯрд╛рдИ рдЧрдИред рд╕рддреНрд░ рдЦреЛрд▓реЗрдВ, рдЙрд╕ рд╕рдордп рддрдХ рдЯрд╛рдЗрдорд▓рд╛рдЗрди рдХреЛ рд╕реНрдХреНрд░рдм рдХрд░реЗрдВ рдЬрдм page.goto рдЪрд╛рд▓реВ рд╣реБрдЖ, рдФрд░ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╕рд░реНрд╡рд░ рдиреЗ рдЕрд╕рд▓реА рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ, DataDome рдЪреБрдиреМрддреА рдпрд╛ рдПрдХ рд╕реНрдЯреЗрд▓-рдпреВрдЖрд░рдПрд▓ рд░рд┐рдбрд╛рдпрд░реЗрдХреНрдЯ рд▓реМрдЯрд╛рдпрд╛ред
рдкреНрд░рд╢реНрди 3: рдХрднреА-рдХрднреА рд╕рдореАрдХреНрд╖рд╛рдПрдБ рдкреГрд╖реНрда рдХреЗ рдмрдЬрд╛рдп рдЖрдВрддрд░рд┐рдХ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреНрдпреЛрдВ рд▓реЛрдб рд╣реЛрддреА рд╣реИрдВ?
рдирдП Etsy рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХреБрдЫ рд╕рдореАрдХреНрд╖рд╛ рдмреИрдЪреЛрдВ рдХреЛ рдкреГрд╖реНрда рдХреЗ рд░реЗрдВрдбрд░ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЖрдВрддрд░рд┐рдХ POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдХреНрд░реИрдкрд░ рдЗрд╕реЗ рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдХреЗ рдФрд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдХреЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ тАФ рдЬрдм рдкрд╛рд░реНрд╕рд░ рдЪрд▓ рд░рд╣рд╛ рд╣реЛрддрд╛ рд╣реИ, рдХрд╛рд░реНрдб DOM рдореЗрдВ рд╣реЛрддреЗ рд╣реИрдВред рд╣рдЬрд╛рд░реЛрдВ рд╕рдореАрдХреНрд╖рд╛рдУрдВ рд╡рд╛рд▓реЗ рдЙрддреНрдкрд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП, рдЖрдк рдкрд╣рд▓реЗ ~30 (рдпрд╛ рдЬреЛ рднреА рдЖрдк maxReviews рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ) рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЧреНрд░рд╛рдлрд╝рдХреНрдпреВрдПрд▓ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЛ рд╕реАрдзреЗ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреА рд╣реИ, рдЬреЛ рдпрд╣рд╛рдБ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИред
рдкреНрд░рд╢реНрди 4: рдХреНрд╖реЗрддреНрд░ рдФрд░ рдореБрджреНрд░рд╛ рд░рд┐рдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
Etsy IP рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд╛рдиреАрдпрдХреГрдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рд░рд┐рдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ (рдЬрд░реНрдорди IP рд╕реЗ etsy.de, рдлреНрд░реЗрдВрдЪ рд╕реЗ etsy.fr)ред рдХреАрдорддреЗрдВ рдФрд░ рдореБрджреНрд░рд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИрдВред рд╕реНрдХреНрд░реИрдкрд░ рдХрд╛ extractNumber рд╣реЗрд▓реНрдкрд░ 1,234.56 (en-US) рдФрд░ 1.234,56 (de-DE) рдкреНрд░рд╛рд░реВрдк рджреЛрдиреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рд╕рднреА рд░рдиреЛрдВ рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ USD рдореВрд▓реНрдп рдирд┐рд░реНрдзрд╛рд░рдг рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ proxyCountry: "US" рдкрд░ рдкрд┐рди рдХрд░реЗрдВред
рдкреНрд░рд╢реНрди 5: рдореИрдВ рдореВрд▓реНрдп, рдмрд┐рдХреНрд░реА рдкрд░, рдореБрдлреНрдд рд╢рд┐рдкрд┐рдВрдЧ, рдпрд╛ рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреИрд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдБ?
рдЖрда filters.* рдХреБрдВрдЬрд┐рдпреЛрдВ рдХрд╛ рдХреЛрдИ рднреА рд╕рдВрдпреЛрдЬрди рд╕реЗрдЯ рдХрд░реЗрдВред рдпреЗ searchQuery рдФрд░ categoryUrl рдореЛрдб рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ Etsy рдХреЗ URL рдкрд░ рд╕реАрдзреЗ рдПрдиреНрдХреЛрдб рд╣реЛрддреЗ рд╣реИрдВ:
ts
const CONFIG: ScraperInput = {
categoryUrl: "https://www.etsy.com/c/bags-and-purses/wallets-and-money-clips/wallets",
filters: {
onSale: true, // тЖТ &is_on_sale=1
freeShipping: true, // тЖТ &free_shipping=1
customizable: true, // тЖТ &is_personalizable=1
shipsTo: "US", // тЖТ &ships_to=US (ISO рджреЗрд╢ рдХреЛрдб)
minPrice: 20, // тЖТ &min=20
maxPrice: 60, // тЖТ &max=60
condition: "vintage", // "рдирдпрд╛" | "рд╡рд┐рдВрдЯреЗрдЬ" (тЖТ &explicit=vintage)
orderBy: "price_asc", // "рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг" | "рджрд┐рдирд╛рдВрдХ_desc" | "price_asc" | "price_desc" | "рдЙрдЪреНрдЪрддрдо рд╕рдореАрдХреНрд╖рд╛рдПрдБ"
},
// ...
};
рджреЛ caveats рдЬрд┐рд╕рд╕реЗ рдЕрд╡рдЧрдд рд╣реЛрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ: `filters.minPrice` / `filters.maxPrice` рдкрд░ рдПрдХ `/search?q=...` URL DataDome-рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реИ (рдЫрд╛рдирдмреАрди рдХреА рдЧрдИ рдЦреЛрдЬ URLs рдХреЛ рдЕрд╕рд╛рдзрд╛рд░рдг рд░реВрдк рд╕реЗ 403'd рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдЗрд╕рд▓рд┐рдП `expandStrategy: "prices"` рдЕрдм рдПрдХ рд╡реНрдпрд╛рдкрдХ рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб `priceBucket` рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЯреИрдЧ рдХрд░рддрд╛ рд╣реИ - рд╡рд╣реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд░рд╛рджрд╛, рдХреЛрдИ URL-рдЫрд╛рдирдмреАрди рдмреНрд▓реЙрдХ рдирд╣реАрдВред `categoryUrl` рдкрд░ рдореВрд▓реНрдп рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
### Q6: рдХреНрдпрд╛ рдореИрдВ retries, timeouts рдФрд░ pacing рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдБ?
рд╣рд╛рдБред рдкреНрд░рддреНрдпреЗрдХ retry рдФрд░ pacing рдорд╛рди `ScraperInput` рдкрд░ рдПрдХ CONFIG рдлрд╝реАрд▓реНрдб рд╣реИ:
| рдлрд╝реАрд▓реНрдб | рдбрд┐рдлрд╝реЙрд▓реНрдЯ | рднреВрдорд┐рдХрд╛ |
|---|---|---|
| `maxRetries` | `10` | рдЙрддреНрдкрд╛рдж рдкрд░ рдХреБрд▓ рдкреНрд░рдпрд╛рд╕ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рд╛рд░ рдорд╛рди рд▓реЗрдВ |
| `retryInitialBackoffMs` | `3000` | рдмрдврд╝рддреА рдмреИрдХрдСрдл рд╕реВрддреНрд░ рдХрд╛ рдЖрдзрд╛рд░ |
| `retryBackoffLinearMs` | `1500` | рд░реИрдЦрд┐рдХ рдкрдж |
| `retryBackoffQuadraticMs` | `500` | рдЧреБрдгрд╛рддреНрдордХ рдкрдж (5 рд╕ тЖТ 57 рд╕ рдХреА рдкреНрд░рдЧрддрд┐ рджреЗрддрд╛ рд╣реИ) |
| `interProductDelayMs` | `3000` | рд▓рдЧрд╛рддрд╛рд░ рдЙрддреНрдкрд╛рдж рд╕рдореГрджреНрдзрд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рд╡рд┐рд░рд╛рдо |
| `pageTimeoutMs` | `60000` | `page.goto` рдЯрд╛рдИрдордЖрдЙрдЯ |
| `h1TimeoutMs` | `15000` | `waitForSelector("h1")` рдЯрд╛рдИрдордЖрдЙрдЯ |
| `postLoadDelayMs` | `1500` | `h1` рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдирд┐рд╖реНрдХрд░реНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ рджреЗрд░реА |
рдХрдареЛрд░ Scrapeless рдпреЛрдЬрдирд╛рдПрдВ рдХрдо `interProductDelayMs` + рдХрдо `maxRetries` рд╕реЗ рд▓рд╛рдн рдЙрдард╛рддреА рд╣реИрдВ; рдХрдард┐рди рдПрдВрдЯреА-рдмреЙрдЯ рд▓рдХреНрд╖реНрдпреЛрдВ рдХреЛ рджреЛрдиреЛрдВ рдкрд░ рдЙрдЪреНрдЪ рдорд╛рдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
### Q7: рдореБрдЭреЗ рдХреМрди рд╕реЗ рд╡рд┐рдлрд▓рддрд╛ рд╢реНрд░реЗрдгрд┐рдпрд╛рдБ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реЛ рд╕рдХрддреА рд╣реИрдВ?
рд╣рд░ рдЙрддреНрдкрд╛рдж рдЬреЛ retry рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдПрдХ рд╕рдВрд░рдЪрд┐рдд `error: { kind, message, attempts }` рдлрд╝реАрд▓реНрдб рд▓реЗрдХрд░ рдЖрддрд╛ рд╣реИред рдЖрда рд╢реНрд░реЗрдгреАрдмрджреНрдз рдкреНрд░рдХрд╛рд░:
- `blocked` тАФ DataDome рд╕реЗ HTTP 403/429 рдпрд╛ рджрд░ рд╕реАрдорд╛ (retryable)
- `not-found` тАФ HTTP 404, рдкреБрд░рд╛рдиреЗ рдпрд╛ рд╣рдЯрд╛рдП рдЧрдП рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ (non-retryable тАФ рддреЗрдЬрд╝реА рд╕реЗ рд╡рд┐рдлрд▓)
- `tls` тАФ `ERR_SSL_*` / `ERR_CERT_*` рдкреНрд░реЙрдХреНрд╕реА TLS рдЭрдЯрдХрд╛ (retryable)
- `network` тАФ `ERR_TUNNEL` / `ERR_CONNECTION_*` / `ERR_ABORTED` (retryable)
- `no-h1` тАФ рдкреГрд╖реНрда рд▓реЛрдб рд╣реЛ рдЧрдпрд╛ рд▓реЗрдХрд┐рди `<h1>` рдХрднреА рдирд╣реАрдВ рдкреНрд░рдХрдЯ рд╣реБрдЖ, рд╕рдВрднрд╡рддрдГ рдПрдХ рдирд░рдо DD рдЪреБрдиреМрддреА рдкреГрд╖реНрда (retryable)
- `timeout` тАФ рдиреИрд╡рд┐рдЧреЗрд╢рди рдЯрд╛рдЗрдордЖрдЙрдЯ рдкрд╛рд░ рдХрд┐рдпрд╛ (retryable)
- `open-browser` тАФ Scrapeless рдХреЗ рд▓рд┐рдП WSS рд╣реИрдВрдбрд╢реЗрдХ рд╡рд┐рдлрд▓ (retryable)
- `unknown` тАФ рдХреБрдЫ рдФрд░ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ retryable)
рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдХреЛрдб `kind: "not-found"` рдХреЛ "рдЗрд╕ URL рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ, рдЗрд╕реЗ рдХрднреА рдкреБрдирдГ рдХрддрд╛рд░рдмрджреНрдз рди рдХрд░реЗрдВ" рдФрд░ `kind: "blocked"` рдХреЛ "рдЗрд╕ рдПрдХ рдХреЛ рдЕрдЧрд▓реЗ рдШрдВрдЯреЗ рдореЗрдВ рдкреБрдирдГ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдЬрдм DataDome рдХреА IP рдкреНрд░рддрд┐рд╖реНрдард╛ рдЦрд┐рдбрд╝рдХреА рд░рд┐рд╕реЗрдЯ рд╣реЛрддреА рд╣реИ" рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рди рд╕рдХрддрд╛ рд╣реИред
рд╕реНрдХреНрд░реИрдкрд▓реЗрд╕ рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рд▓рд╛рдЧреВ рдХрд╛рдиреВрдиреЛрдВ, рд╡рд┐рдирд┐рдпрдореЛрдВ рдФрд░ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдЧреЛрдкрдиреАрдпрддрд╛ рдиреАрддрд┐рдпреЛрдВ рдХрд╛ рд╕рдЦреНрддреА рд╕реЗ рдЕрдиреБрдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдмреНрд▓реЙрдЧ рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдХреЗрд╡рд▓ рдкреНрд░рджрд░реНрд╢рди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдХреЛрдИ рдЕрд╡реИрдз рдпрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рдиреЗ рд╡рд╛рд▓реА рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдмреНрд▓реЙрдЧ рдпрд╛ рддреГрддреАрдп-рдкрдХреНрд╖ рд▓рд┐рдВрдХ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рднреА рджреЗрдпрддрд╛ рдХреЛ рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рд╕рднреА рджреЗрдпрддрд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддреЗ рд╣реИрдВред рдХрд┐рд╕реА рднреА рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЕрдкрдиреЗ рдХрд╛рдиреВрдиреА рд╕рд▓рд╛рд╣рдХрд╛рд░ рд╕реЗ рдкрд░рд╛рдорд░реНрд╢ рдХрд░реЗрдВ рдФрд░ рд▓рдХреНрд╖реНрдп рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреА рд╕реЗрд╡рд╛ рдХреА рд╢рд░реНрддреЛрдВ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░реЗрдВ рдпрд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрдиреБрдорддрд┐рдпрд╛рдБ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред



