Temu, быстро растущий маркетплейс с огромным каталогом товаров по конкурентным ценам: электроника, одежда, товары для дома. Страницы поиска и листинга несут именно те публичные данные, которые нужны ритейлерам, аналитикам и трекерам цен: название товара, актуальная цена, оценки покупателей и количество уже проданных единиц. Взятые в совокупности по категории, эти поля показывают, что в тренде и куда движутся цены.
Это руководство показывает, как парсить Temu с помощью JavaScript и Node.js, используя cheerio. Вы создадите небольшой рабочий скрапер, который получает страницу результатов поиска Temu через Crawling API, извлекает заголовок, цену, рейтинг, количество продаж и ссылку для каждого товара, обрабатывает пагинацию через кнопку «Показать ещё» и экспортирует результат в форматах JSON и CSV. Всё руководство ограничено публичными данными листинга товаров, а раздел о правовых аспектах в конце не является стандартной оговоркой, поэтому прочитайте его, прежде чем применять скрапер на реальных объёмах.
Что вы создадите
Скрипт на Node.js, который принимает публичный URL поиска Temu, получает отрисованный HTML через Crawling API и извлекает структурированную запись для каждого товара в листинге. Для примера используем обобщённый поисковый запрос и извлекаем следующие поля для каждого элемента:
- Title, название товара, отображаемое на карточке, используется для идентификации товара и его категории.
- Price, цена в том виде, в каком она отображается, для мониторинга трендов и сравнения похожих товаров.
- Rating, звёздный рейтинг на карточке, быстрый индикатор мнения покупателей.
- Sold count, цифра «N продано», которую Temu показывает на многих карточках, приблизительный сигнал спроса.
- Image URL, миниатюра товара для визуальной базы данных или дальнейшего использования в приложении.
- Link, URL страницы отдельного товара, чтобы можно было детально изучить его позже.
Почему обычный запрос не работает на Temu
Если запросить URL поиска Temu обычным HTTP-клиентом, вы редко получите сетку товаров в ответе. Здесь действуют два фактора. Во-первых, Temu рендерит карточки листинга в браузере с помощью JavaScript, поэтому исходный HTML, почти пустая оболочка, пока скрипты страницы не запустятся и не загрузят список товаров. Во-вторых, Temu агрессивно реагирует на автоматизированный трафик: IP-адреса датацентров и паттерны запросов, не похожие на настоящий браузер, получают CAPTCHA, ограничение по скорости или блокировку ещё до того, как доберутся до отрисованных данных о товарах.
Значит, рабочий скрапер Temu должен решать в одном запросе две задачи: браузер, который действительно рендерит страницу, и IP-адрес, который платформа воспринимает как реального посетителя. Можно собрать это самостоятельно с помощью headless-браузера и пула ротирующихся резидентских прокси, но поддержание их в рабочем состоянии, это основная часть работы. Crawling API объединяет оба компонента в одном вызове: вы передаёте ему URL, он рендерит страницу через доверенный IP-адрес и возвращает готовый HTML для парсинга с помощью cheerio. Поскольку список товаров загружается клиентскими скриптами, вы просите API дождаться появления этого контента перед возвратом.
Для парсинга контента, отрисованного JavaScript, как на Temu, требуется токен для JavaScript-запросов из вашего дашборда Crawlbase, а не обычный токен. Бесплатный уровень включает до 5 000 бесплатных запросов без привязки карты, и вы платите только за успешные запросы. Подробнее о кредитовании обычных и JavaScript-запросов см. на странице ценообразования.
Предварительные требования
Прежде чем писать код, необходимо подготовить несколько вещей. Ни одна из них не займёт много времени.
Базовые знания JavaScript и Node.js. Вы должны уметь писать и запускать Node-скрипты, а также устанавливать пакеты с помощью npm. Если вы новичок в Node, официальная документация или любой вводный курс выведут вас на уровень, который предполагает данное руководство.
Node.js 16 или новее. Проверьте версию командой node --version. Если Node.js не установлен, установите его с официального сайта или через менеджер версий, например nvm.
Аккаунт Crawlbase и токен. Зарегистрируйтесь, откройте дашборд и скопируйте токен для JavaScript-запросов со страницы документации аккаунта. Обращайтесь с токеном как с паролем: он аутентифицирует ваши запросы, поэтому не добавляйте его в систему контроля версий.
Настройка проекта
Создайте папку проекта, инициализируйте её и установите две библиотеки, которые нужны скраперу.
node --version mkdir temu-scraper && cd temu-scraper npm init -y npm install crawlbase cheerio
Две зависимости выполняют всю работу: crawlbase, официальный Node-клиент для Crawling API, а cheerio парсит возвращаемый HTML с помощью jQuery-подобного API, что позволяет извлекать отдельные поля по CSS-селекторам. Создайте файл temu-scraper.js в этой папке и добавьте код из следующих шагов.
Шаг 1: Получение отрисованной страницы поиска
Начните с получения готовой страницы. Импортируйте класс CrawlingAPI, инициализируйте его вашим JavaScript-токеном и запросите URL поиска. Temu загружает список товаров с помощью клиентских скриптов, поэтому передайте параметры ajax_wait и page_wait, чтобы дать контенту время появиться до того, как API вернёт ответ. Проверка кода статуса перед парсингом позволяет сразу замечать ошибки.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const searchURL = 'https://www.temu.com/search_result.html?search_key=wireless+earbuds'; const options = { ajax_wait: 'true', page_wait: '5000' }; api .get(searchURL, options) .then((response) => { if (response.statusCode === 200) { console.log(response.body.slice(0, 500)); } }) .catch((error) => console.error('API request error:', error));
Запустите скрипт командой node temu-scraper.js, и вверху тела ответа должна появиться реальная разметка товаров Temu, а не пустая оболочка. Это подтверждает, что рендеринг работает, ещё до написания первого селектора. Флаг ajax_wait указывает API дождаться завершения внутристраничных запросов, а page_wait добавляет фиксированную задержку в миллисекундах, что вместе даёт списку товаров время на загрузку.
Первый запрос только что вернул полностью отрисованную страницу поиска Temu без headless-браузера и без прокси на вашей стороне. Crawling API запускает страницу в настоящем браузере, ожидает загрузки списка товаров JavaScript, ротирует резидентские IP-адреса на стороне сервера и обрабатывает CAPTCHA, которыми Temu атакует скраперы, и всё это в одном вызове. Попробуйте на поисковом запросе на бесплатном уровне.
Шаг 2: Парсинг каждого товара с помощью cheerio
Получив отрисованный HTML, загрузите его в cheerio и пройдитесь по карточкам товаров. Temu размещает каждый результат поиска в повторяющемся контейнере внутри списка товаров, поэтому вы выбираете все карточки, а затем считываете заголовок, цену, рейтинг, количество продаж, изображение и ссылку из каждой из них. Защитное чтение каждого поля не позволяет одному отсутствующему значению сломать весь запуск.
const cheerio = require('cheerio'); function parseSearchResults(html) { const $ = cheerio.load(html); const products = []; const cards = $( 'div.js-search-goodsList > div.autoFitList > div.EKDT7a3v' ); cards.each((index, element) => { const card = $(element); const title = card.find('h2._2BvQbnbN').text().trim(); const price = card.find('span._2de9ERAH').text().trim(); const rating = card.find('div._1bGyLOoB').text().trim(); const sold = card.find('span._3VxQjs6a').text().trim(); const imageUrl = card.find('img.goods-img-external').attr('src') || ''; const href = card.find('a._2Tl9qLr1').attr('href'); const link = href ? new URL(href, 'https://www.temu.com').href : ''; if (title) { products.push({ title, price, rating, sold, imageUrl, link }); } }); return products; }
Несколько деталей обеспечивают точность по отношению к странице. Каждая карточка находится под селектором div.js-search-goodsList > div.autoFitList > div.EKDT7a3v, заголовок берётся из заголовка h2._2BvQbnbN, цена, из span._2de9ERAH, рейтинг и количество продаж, из собственных небольших текстовых узлов, миниатюра, из атрибута src элемента img.goods-img-external, а ссылка, из атрибута href элемента a._2Tl9qLr1, преобразованного в абсолютный URL. Проверка if (title) отсеивает пустые ячейки-заглушки, которые иногда присутствуют в сетке.
Имена классов Temu (_2BvQbnbN, _2de9ERAH, EKDT7a3v и остальные) генерируются и меняются без предупреждения. Воспринимайте приведённые выше селекторы как шаблон, а не как неизменный контракт. Если поле возвращается пустым, заново изучите страницу в инструментах разработчика браузера и обновите селектор. Периодическое обслуживание селекторов, норма для любого производственного скрапера, а не признак поломки.
Шаг 3: Обработка пагинации и сборка финального скрипта
Temu загружает больше результатов за кнопкой «Показать ещё», а не на отдельных пронумерованных страницах. Crawling API может нажать эту кнопку за вас ещё до возврата HTML, используя параметр css_click_selector, поэтому один рендер может вернуть большую партию карточек. Свяжите получение данных, нажатие кнопки и парсинг в один рабочий скрипт, затем сохраните записи на диск в форматах JSON и CSV.
const fs = require('fs'); const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); async function crawl(url) { const response = await api.get(url, { ajax_wait: 'true', page_wait: '5000', css_click_selector: 'div.R8mNGZXv[role="button"]', }); if (response.statusCode === 200) return response.body; console.error(`Request failed: ${response.statusCode}`); return null; } function toCsv(rows) { const headers = ['title', 'price', 'rating', 'sold', 'imageUrl', 'link']; const escape = (value) => `"${String(value).replace(/"/g, '""')}"`; const lines = [headers.join(',')]; for (const row of rows) { lines.push(headers.map((h) => escape(row[h])).join(',')); } return lines.join('\n'); } async function main() { const url = 'https://www.temu.com/search_result.html?search_key=wireless+earbuds'; const html = await crawl(url); if (!html) return; const products = parseSearchResults(html); fs.writeFileSync('temu-products.json', JSON.stringify(products, null, 2)); fs.writeFileSync('temu-products.csv', toCsv(products)); console.log(`Saved ${products.length} products to JSON and CSV`); } main();
Вставьте функцию parseSearchResults из Шага 2 в тот же файл, чтобы main мог её вызвать. Параметр css_click_selector указывает на элемент управления «Показать ещё» на Temu (div.R8mNGZXv[role="button"]); API нажимает его во время рендеринга, и возвращаемый HTML включает дополнительные карточки, которые загружаются при нажатии. Запустите скрипт командой node temu-scraper.js и получите два файла: temu-products.json с полными структурированными записями и temu-products.csv, готовый к открытию в таблице. Вспомогательная функция toCsv оборачивает каждое поле в кавычки и экранирует встроенные кавычки двойными, что особенно важно, так как названия товаров длинные и часто содержат запятые.
Как выглядит результат
JSON-файл содержит по одному объекту на каждый товар в порядке листинга, каждый с заголовком, ценой, рейтингом, количеством продаж, URL изображения и ссылкой.
[ { "title": "Wireless Earbuds Bluetooth 5.3 with Charging Case", "price": "$8.97", "rating": "4.6", "sold": "12K+ sold", "imageUrl": "https://img.kwcdn.com/product/open/earbuds-001.jpg", "link": "https://www.temu.com/goods-detail-g-601099527865713.html" }, { "title": "True Wireless Sports Earphones Noise Cancelling", "price": "$11.49", "rating": "4.4", "sold": "3.2K+ sold", "imageUrl": "https://img.kwcdn.com/product/open/earbuds-002.jpg", "link": "https://www.temu.com/goods-detail-g-601099537192760.html" } ]
CSV повторяет те же строки с заголовком, поэтому он сразу открывается в Excel, Google Sheets или любом конвейере данных, работающем с файлами с разделителями.
title,price,rating,sold,imageUrl,link "Wireless Earbuds Bluetooth 5.3 with Charging Case","$8.97","4.6","12K+ sold","https://img.kwcdn.com/product/open/earbuds-001.jpg","https://www.temu.com/goods-detail-g-601099527865713.html" "True Wireless Sports Earphones Noise Cancelling","$11.49","4.4","3.2K+ sold","https://img.kwcdn.com/product/open/earbuds-002.jpg","https://www.temu.com/goods-detail-g-601099537192760.html"
Масштабирование по запросам и сохранение работоспособности
Один поисковый запрос, это демонстрация; реальная задача обходит несколько запросов или категорий. Составьте список поисковых терминов, получайте каждый через Crawling API с теми же параметрами ожидания и нажатия, парсите с помощью той же функции и отмечайте каждую строку соответствующим запросом перед экспортом. Поскольку все страницы поиска используют одинаковую структуру карточек, уже написанный парсер работает со всеми запросами без изменений.
async function scrapeQueries(queries) { const all = []; for (const query of queries) { const term = encodeURIComponent(query); const url = `https://www.temu.com/search_result.html?search_key=${term}`; const html = await crawl(url); if (!html) continue; const rows = parseSearchResults(html).map((p) => ({ query, ...p })); all.push(...rows); await new Promise((r) => setTimeout(r, 2000)); } return all; } scrapeQueries(['wireless earbuds', 'phone case', 'led lights']).then((rows) => { console.log(`Collected ${rows.length} products across queries`); });
Даже при обработке рендеринга Temu отслеживает трафик, характерный для скраперов, поэтому несколько привычек помогают поддерживать работоспособность запуска. Дозируйте запросы: задержка setTimeout между запросами выше распределяет трафик вместо бомбардировки страниц в тесном цикле, что является главным фактором соблюдения лимитов скорости. Используйте ротацию: пул резидентских IP-адресов распределяет запросы по множеству адресов реальных пользователей, чтобы ни один из них не превысил лимит и не вызвал CAPTCHA, а Crawling API берёт это на себя. Читайте коды статусов: запуск, который начинает возвращать не-200 ответы, сигнализирует о необходимости замедлиться. Более подробный план действий см. в руководстве по обходу блокировок при скрапинге, а по части рендеринга, в статье о сканировании JavaScript-сайтов.
Этот подход напрямую переносится в задачи ценообразования и аналитики. Чтобы превратить данные листинга в решения по ценам, изучите руководство по использованию веб-скрапинга для анализа цен, а для более широкого взгляда на скрапинг маркетплейсов, руководство по скрапингу в сфере электронной коммерции, которое рассматривает подходы с повторным использованием того же метода «получить и разобрать» для других магазинов.
Законно ли парсить Temu?
Разрешён ли скрапинг Temu, зависит от условий использования сервиса, вашей юрисдикции и того, что вы делаете с данными. Условия Temu ограничивают автоматизированный доступ, поэтому скрапинг может противоречить этим условиям вне зависимости от тщательности ваших инструментов. Ни один из приведённых здесь кодов не меняет этого; он просто делает техническую часть рабочей. Ознакомьтесь с Условиями использования Temu и её файлом robots.txt и воспринимайте оба как границы того, что вы собираете.
Несколько правил, которых стоит придерживаться. Собирайте только публичные данные о товарах: название, цену, рейтинг, количество продаж, изображение и ссылку на товар, которые любой может видеть на странице поиска без аккаунта. Соблюдайте заявленные ожидания Temu по скорости запросов и держите объём запросов достаточно низким, чтобы не перегружать серверы. Избегайте персональных данных, включая всё, что связано с идентифицируемыми рецензентами, кроме сводных рейтингов и подсчётов, показанных на странице. Не распространяйте защищённые авторским правом материалы Temu, такие как фотографии товаров, как если бы они были вашими; использование URL изображения в качестве ссылки отличается от коммерческого перепубликования самого изображения.
Это руководство намеренно ограничено публичными данными поиска и листинга, так как это та линия, которая делает работу правомерной. Оно не распространяется на что-либо за логином, личные данные покупателей или продавцов, историю заказов или любые попытки обойти аутентификацию или CAPTCHA, которую вы не должны были проходить. Если ваш проект требует большего, чем публичные листинги, или вы планируете коммерческое переиспользование данных, правильный путь, официальное соглашение или санкционированная программа партнёрства, а не более изощрённый скрапер. Когда маркетплейс предлагает официальный канал данных, предпочитайте его для объёмного или коммерческого использования.
Ключевые выводы
- Temu рендерит листинги на стороне клиента и жёстко блокирует запросы. Обычный запрос возвращает пустую оболочку или CAPTCHA, поэтому необходимо рендерить страницу за доверенным IP-адресом и дожидаться загрузки списка товаров перед парсингом.
-
Crawling API выполняет всю тяжёлую работу в одном вызове. Он рендерит страницу, ожидает AJAX-контента с помощью
ajax_waitиpage_wait, ротирует резидентские IP-адреса и обрабатывает CAPTCHA, возвращая готовый HTML. - cheerio извлекает поля. Выберите все карточки в списке товаров, затем считывайте заголовок, цену, рейтинг, количество продаж, изображение и ссылку, ожидая, что генерируемые имена классов будут меняться.
-
Пагинация, это нажатие кнопки «Показать ещё». Temu загружает больше результатов за кнопкой, поэтому параметр
css_click_selectorуказывает API нажать её во время рендеринга и вернуть расширенную партию. - Работайте только с публичными данными. Соблюдайте Условия использования и robots.txt Temu, дозируйте запросы, избегайте персональных данных и контента для авторизованных пользователей, экспортируйте чистые JSON и CSV для дальнейшего использования.
Часто задаваемые вопросы
Почему обычный запрос возвращает неполные данные с Temu?
Потому что Temu рендерит сетку товаров на стороне клиента с помощью JavaScript и защищается от автоматизированного трафика с помощью CAPTCHA. Обычный HTTP-запрос с IP-адреса датацентра обычно возвращает пустую оболочку или страницу блокировки, а не карточки товаров. Чтобы получить полную страницу, необходимо рендерить её за доверенным IP-адресом и дождаться загрузки списка товаров: именно это Crawling API делает за вас с помощью ajax_wait и page_wait.
Нужен ли JavaScript-токен для парсинга Temu?
Да. Контент Temu рендерится JavaScript, поэтому вы используете токен для JavaScript-запросов из дашборда Crawlbase, а не обычный, и передаёте параметры ожидания, чтобы в ответе присутствовал отрисованный список товаров. Бесплатный уровень включает до 5 000 бесплатных запросов без привязки карты, а JavaScript-запросы кредитуются иначе, чем обычные, поэтому ознакомьтесь со страницей ценообразования для получения подробностей.
Как работает пагинация на Temu?
Temu загружает больше листингов за кнопкой «Показать ещё» вместо отдельных пронумерованных страниц. Crawling API может нажать эту кнопку во время рендеринга с помощью параметра css_click_selector, поэтому один запрос может вернуть большую партию карточек. Укажите селектор кнопки (например, div.R8mNGZXv[role="button"]), и дополнительные результаты вернутся в том же HTML, который вы парсите.
Мои селекторы возвращают пустые значения. Что изменилось?
Почти наверняка изменилась разметка Temu. Имена контейнеров и классов, такие как _2BvQbnbN, _2de9ERAH и EKDT7a3v, генерируются и меняются без предупреждения, поэтому селекторы, работавшие в прошлом месяце, могут сломаться. Заново изучите страницу в инструментах разработчика браузера и обновите селекторы. Периодическое обслуживание селекторов, норма для любого производственного скрапера.
Можно ли хранить данные Temu в базе данных вместо CSV?
Да. CSV и JSON удобны для первого прохода, но для больших или постоянных проектов база данных, такая как PostgreSQL или MongoDB, упрощает запросы и анализ данных со временем. Замените вызовы writeFileSync в main на логику вставки вашего клиента базы данных, оставив остальную часть скрапера без изменений.
Как избежать блокировок при парсинге Temu?
Держите скорость запросов на IP низкой, добавляйте задержки между запросами и маршрутизируйте через ротирующиеся резидентские IP-адреса, чтобы ни один адрес не превысил лимит скорости или не вызвал CAPTCHA. Crawling API управляет ротацией, доверенным пулом IP-адресов и обработкой CAPTCHA; если вы строите собственный стек, именно в эту часть стоит инвестировать. Следите за кодами статусов и замедляйтесь при появлении проверок.
Обходите любой сайт в масштабе, без борьбы с инфраструктурой.
Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.
