Yupoo Scraper avatar

Yupoo Scraper

Pricing

from $5.50 / 1,000 product scrapeds

Go to Apify Store
Yupoo Scraper

Yupoo Scraper

Scrape public or password-protected Yupoo stores, categories, and albums into structured titles, descriptions, image URLs, and album links.

Pricing

from $5.50 / 1,000 product scrapeds

Rating

2.0

(1)

Developer

Ibrahim

Ibrahim

Maintained by Community

Actor stats

0

Bookmarked

5

Total users

0

Monthly active users

15 days ago

Last modified

Share

πŸ–ΌοΈ Yupoo Scraper β€” Albums, Images, Titles, Descriptions

Point it at a Yupoo store, category, or single album and get clean structured data back. Public and owner-authorized password-protected pages are supported without browser automation.

This Actor does one job properly: it reads Yupoo pages and hands you exactly what is on them β€” image URLs, titles, descriptions, album URLs. It does not score, rank, rewrite, or "enrich" anything. What you see in the output is what the seller published.


πŸ’‘ Who is this for?

  • Catalog and inventory work β€” pulling a supplier's full album list into a spreadsheet or database.
  • Developers building on top of Yupoo data who want a clean JSON feed instead of writing an HTML parser.
  • Anyone doing bulk image collection from albums that hold 30–100 photos each.

🎯 What it does

You give itYou get back
A store URL β€” https://STORE.x.yupoo.com/albumsEvery album in the store
A category URL β€” https://STORE.x.yupoo.com/categories/5280382Every album in that category
A single album URL β€” https://STORE.x.yupoo.com/albums/246388734?uid=1That one album
A bare store name β€” chaosmade20Same as the store URL

Mix as many as you like in one run β€” each URL is detected automatically, no mode switch to set.


⚑ Quick start

Just the album URLs from a store (fastest and cheapest β€” reads index pages only, never opens an album):

{ "urls": ["chaosmade20"], "albumUrlsOnly": true }

Everything from one category:

{ "urls": ["https://chaosmade20.x.yupoo.com/categories/5280382"] }

Only the images from a single album:

{
"urls": ["https://chaosmade20.x.yupoo.com/albums/246388734?uid=1"],
"fields": ["images"]
}

A password-protected store or album:

{
"urls": ["https://STORE.x.yupoo.com/albums"],
"password": "PASSWORD_FROM_THE_STORE_OWNER"
}

The password is sent only to that Yupoo host for the current run. It is marked as a secret input and is never written to the dataset or logs. Use it only where the store owner has authorized your access.

πŸ’‘ Start small. Run one album first and check the output is shaped the way you need before pointing it at a store with thousands of albums. Yupoo stores vary a lot β€” some put their whole catalog on one page, some paginate, some leave descriptions empty.


πŸ“€ Output

One record per album, pushed straight to the Dataset β€” no file keys to hunt for, no post-processing step. Export as JSON, CSV, or Excel from the Storage tab, or pull it from the API.

{
"store": "chaosmade20",
"albumUrl": "https://chaosmade20.x.yupoo.com/albums/246388734?uid=1",
"title": "Washed Black Tee",
"description": "https://example.com/products/tee",
"images": [
"https://photo.yupoo.com/chaosmade20/95d571333a/big.jpg",
"https://photo.yupoo.com/chaosmade20/a87080adfd/big.jpg"
]
}

store and albumUrl are always present. Everything else is whatever you selected in fields β€” unselected fields are left out entirely, not returned as empty strings or nulls.


⚠️ Read this before you import images anywhere

Yupoo image URLs are hotlink-protected. This is a property of Yupoo, not of this Actor, and it will affect you no matter which scraper you use. Measured directly:

How the image is requestedWhat Yupoo returns
No Referer headerHTTP 567 β€” a 7 KB HTML error page, not an image
Referer from your own siteHTTP 567 β€” blocked
Referer: https://STORE.x.yupoo.com/HTTP 200 β€” the real JPEG (337 KB)

What this means in practice:

  • Pasting an image URL straight into a browser tab shows a broken image. The URL is still correct.
  • Embedding these URLs directly in a storefront or web page will not work.
  • Downloading them does work β€” send a Referer header of https://STORE.x.yupoo.com/ with the request:
curl -H "Referer: https://chaosmade20.x.yupoo.com/" \
"https://photo.yupoo.com/chaosmade20/95d571333a/big.jpg" -o image.jpg

Once downloaded, host the files wherever you like and the restriction no longer applies.

βœ… Optional image rehosting

Rehosting is off by default because downloading and uploading every photo is the most expensive mode. Turn it on only when you need image links that display outside Yupoo. Every selected image is then downloaded using the correct store referer, re-uploaded, and returned as a working URL in the images field.

To use your own image-host account instead of the built-in one, set imageHostApiKey. To skip rehosting entirely and get raw Yupoo URLs β€” much faster and lighter β€” set rehostImages: false.

{
"urls": ["https://chaosmade20.x.yupoo.com/albums/246388734?uid=1"],
"imageHostApiKey": "YOUR_KEY"
}
imageHostGet a key atNotes
freeimagefreeimage.hostDefault. Chevereto API.
imgbbapi.imgbb.comSupports link expiry.
customβ€”Any Chevereto-compatible v1 endpoint via uploadEndpoint.

How it behaves:

  • Keys are validated before the run starts. A wrong or blocked key fails in seconds instead of dying three thousand images into a long job.
  • If no key is available at all, the run still completes β€” you get every album with its original Yupoo URLs, plus a warning in the log. The scrape is never lost because of an image-host problem.
  • A failed upload keeps its original Yupoo URL rather than dropping out of the results. Your record is never left short β€” but a run can return a mix of rehosted and original URLs, so make sure your import handles both.
  • The run log reports the split β€” how many images were rehosted and how many kept their originals.
  • imageLinkExpirySeconds: 0 (the default) keeps images forever. Expiry is an ImgBB feature and is ignored by hosts that do not support it.
  • Resolution is preserved, but the file is re-encoded. Measured on freeimage.host: a 1080Γ—1080 source came back 1080Γ—1080, with the JPEG about 18% smaller. You keep full dimensions; you do not get a byte-identical copy. If you need the exact original file, download it yourself with the referer method above.

⚠️ Free image hosts have their own limits and terms. Bulk-uploading tens of thousands of images may get you rate limited or blocked. Uploads go to your own account, so quotas and content rules are between you and that host. If one blocks you, switch imageHost rather than rewriting anything.


πŸ’° What a run costs

Rehosting uses a separate pay-per-event charge because it adds a download, a base64 upload, and substantial data transfer for every photo. Your own image host may also impose quotas. Apify platform usage is driven by requests, memory time, proxy traffic, and transfer.

ModeRequestsData moved
albumUrlsOnly: true1 per ~77–120 albums (index pages only)Negligible
rehostImages: false1 per album, plus index pages~50–150 KB per album
Rehosting on1 per album + 2 per image~780 KB per image

The rehosting row is the one to plan around when enabling that option. Each image is downloaded (~340 KB) and re-uploaded as base64, which inflates it by roughly a third (~440 KB). Albums hold 30–100 images, so a single album can move 25–75 MB.

A worked example: 100 albums averaging 50 images each is 5,000 images β‰ˆ 3.9 GB of transfer and 10,000 upload round trips. That is a long, heavy run.

How to keep it cheap:

  • Use albumUrlsOnly when you only need the catalog structure β€” it is roughly 100Γ— cheaper than a full scrape.
  • Leave rehostImages: false for exploratory runs. Turn it on only for the albums you are actually importing.
  • Use maxImagesPerAlbum to cap rehosting if you only need a few photos per product.
  • Set fields to just what you need. It does not reduce requests (all fields come from the same page) but it does shrink your dataset.
  • Always test on one album first and read the run's usage before scaling to a store.

πŸ“₯ Input reference

FieldTypeDefaultDescription
urlsarrayβ€”Required. Album, category, or store URLs β€” mix freely. Bare store names work.
passwordstringβ€”Optional owner-provided password for a protected store or album. Secret and never included in output or logs.
fieldsarrayall threeAny of images, title, description.
albumUrlsOnlybooleanfalseList album URLs without opening each album. Dramatically faster.
maxAlbumsPerStoreinteger25Per store or category URL. 0 = no limit.
maxPagesinteger3Album-index pages to walk.
imageSizestringbigsmall, medium, or big. Costs no extra requests β€” see below.
maxImagesPerAlbuminteger00 = no limit.
albumConcurrencyinteger3Album pages fetched at once.
requestDelayMsinteger250Minimum pause before each request. Raise if you see 429s.
maxRetriesinteger3Retries per failed request.
rehostImagesbooleanfalseRe-uploads images so the URLs work anywhere. Off by default to control cost.
imageHoststringfreeimagefreeimage, imgbb, or custom.
imageHostApiKeystringβ€”Optional β€” use your own image-host account. Stored as a secret.
uploadEndpointstringβ€”Only for imageHost: "custom".
imageLinkExpirySecondsinteger00 = never expire. ImgBB only.
imageConcurrencyinteger2Images downloaded and uploaded at once.
proxyConfigurationobjectOffDirect requests are cheaper. Enable an Apify proxy only if Yupoo is unreachable from your run region.

πŸ” Notes from the field

Things learned the hard way, documented so you do not have to rediscover them:

  • Album URLs need their uid query parameter. Strip it and Yupoo replies 200 OK with a body reading "this album is not exist" β€” not a 404. A naive scraper writes that as a valid empty record. This Actor keeps the parameter and detects the body anyway, so a dead album is reported rather than silently returned.
  • Two gallery layouts are live simultaneously. Older stores render album3__main cards, newer ones album__main. Both are handled.
  • Titles live in three different places depending on layout. When a page forces a fall back to <title>, that value carries a | album | STORE | … suffix, which is stripped before output.
  • Not every store paginates. Some render the entire catalog on page one. Pagination stops as soon as a page yields nothing new instead of walking empty pages.
  • Albums are large. Across the stores tested, albums held roughly 30–100 images each. That is why maxImagesPerAlbum defaults to no limit β€” a silent cap would quietly discard most of your data.
  • Image size is a URL rewrite. Yupoo serves /small.jpg, /medium.jpg, and /big.jpg from the same path, so choosing big costs nothing extra.
  • Descriptions are freeform. Sellers write whatever they want there β€” sometimes a product link, sometimes measurements, sometimes nothing. You get the text as-is.

πŸ”Œ API integration

Replace YOUR_TOKEN with your token from Apify Console β†’ Settings β†’ API & Integrations.

Small jobs β€” one call, results returned inline

For a single album or a small category, run synchronously and get the data straight back:

curl -X POST "https://api.apify.com/v2/acts/Vw1EDApmqzgczTA1a/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["https://chaosmade20.x.yupoo.com/albums/246388734?uid=1"],"fields":["images"]}'

The response is the array of results. No polling, no second request.

Large jobs β€” start, poll, fetch

Big stores take a while, so start the run asynchronously:

curl -X POST "https://api.apify.com/v2/acts/Vw1EDApmqzgczTA1a/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"urls":["chaosmade20"],"maxAlbumsPerStore":0}'

Save data.id (the run ID) and data.defaultDatasetId from the response, poll until the status is SUCCEEDED, then download:

$curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_TOKEN&format=json" -o output.json

Full script (Node.js)

Save as scrape.mjs and run with node scrape.mjs.

const ACTOR = 'Vw1EDApmqzgczTA1a';
const TOKEN = 'YOUR_APIFY_TOKEN';
const BASE = 'https://api.apify.com/v2';
const INPUT = {
urls: ['chaosmade20'], // store, category, or album URLs
fields: ['images', 'title', 'description'],
maxAlbumsPerStore: 0, // 0 = no limit
};
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const getJson = async (url) => (await fetch(url)).json();
// 1. Start the run
const start = await (
await fetch(`${BASE}/acts/${ACTOR}/runs?token=${TOKEN}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(INPUT),
})
).json();
const { id: runId, defaultDatasetId: datasetId } = start.data;
console.log('Run:', runId);
// 2. Poll until it finishes
let status = start.data.status;
while (['RUNNING', 'READY'].includes(status)) {
await wait(30_000);
({ data: { status } } = await getJson(`${BASE}/actor-runs/${runId}?token=${TOKEN}`));
console.log('Status:', status);
}
if (status !== 'SUCCEEDED') throw new Error(`Run ended as ${status}`);
// 3. Download the results
const items = await getJson(`${BASE}/datasets/${datasetId}/items?token=${TOKEN}&format=json`);
const { writeFileSync } = await import('node:fs');
writeFileSync('output.json', JSON.stringify(items, null, 2));
console.log(`Saved ${items.length} albums to output.json`);

🧰 What this Actor does not do

Stated plainly so you can judge fit before spending anything:

  • No AI or LLM processing. Prices, SKUs, and sizes are not extracted from description text. Yupoo has no price field β€” sellers type prices into freeform text, so any extraction is guesswork. Across the stores tested, price text was absent entirely from 1 in 4 of them. You get the raw description and can parse it yourself if your catalog is consistent.
  • No video extraction. Images only.
  • No password cracking or authentication bypass. The optional password field only uses a password you already have from the store owner.

πŸ–₯️ Running it locally

$npm install
$npm test

Put your input in storage/key_value_stores/default/INPUT.json, then:

$node src/main.js

Results land in storage/datasets/default/.


βš–οΈ Responsible use

This Actor reads publicly accessible pages and password-protected pages you are authorized to access. It does not crack passwords, bypass authentication, evade rate limits, or defeat access controls, and it ships with a request delay and conservative concurrency β€” please leave them in place.

You are responsible for what you do with the output. Images and listings on Yupoo are usually someone else's intellectual property. Republishing or selling based on scraped content may carry legal obligations depending on the content and your jurisdiction. Check before you build on it.