I built this actor; it's a paid tool on Apify with a free trial credit.
Global Sources is the older, more curated cousin of Alibaba: a Hong Kong B2B marketplace where most suppliers are paying, ranked members, many of them verified on site as factories, and plenty exhibit at its trade shows. If you source products, it is the second place you check after Alibaba, and comparing the two by hand is slow. There is no public product API.
I'm an 18-year-old engineering student, and I built Global Sources Scraper to turn a keyword into clean JSON rows over plain HTTP. This post covers how it works, calling it from Python and Node, what a row looks like, and a small project: a shortlist of verified, low-MOQ factories for a product.
How it works
Global Sources' search page is a single-page app that loads its results from a JSON search endpoint, 80 products per call, with the filters (supplier location, verified business type, supplier ranking, years in business, certificates, FOB port, OEM, trade show) sent in the same request. The actor calls exactly that endpoint, pages through until your limit, and applies price and MOQ filters before a row is saved, so filtered-out products are never charged. It connects directly and only retries blocked requests through a proxy.
Each row has the product (title, URL, images, video, model number, category path), the price (FOB from / to in USD, price type), MOQ and unit, lead time and FOB port when given, and the supplier: name, homepage, country, star ranking P1-P6, years on Global Sources, business types, verified supplier and verified manufacturer badges, and trade show history.
Calling it from Python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/global-sources-scraper").call(run_input={
"searchTerms": ["yoga mat", "bluetooth speaker"],
"maxResultsPerSearch": 200,
"verifiedManufacturerOnly": True,
"maxMoq": 1000,
"maxPrice": 20,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["priceText"], "| MOQ", item["moq"], item["moqUnit"], "|", item["supplierName"], f"P{item['supplierLevel']}", item["supplierLocation"])
The same from Node:
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('rel8ble/global-sources-scraper').call({
searchTerms: ['led light'],
supplierLocations: ['Vietnam', 'India'],
minSupplierLevel: 5,
maxResultsPerSearch: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const p of items) console.log(p.priceMin, p.moq, p.supplierName, p.supplierYearsOnGlobalSources, p.url);
What a row looks like
From the default demo run ("led light"), trimmed:
{
"productId": "1230765239",
"title": "Multi function LED Work Light | Rotatable, Magnetic Base & Rechargeable Spotlight with Multiple Light",
"url": "https://www.globalsources.com/Work-light/LED-work-light-1230765239p.htm",
"priceMin": 7.3,
"priceMax": 7.5,
"priceType": "PRICE_BY_ORDER_QUANTITY",
"moq": 100,
"moqUnit": "Boxes",
"leadTimeDays": 7,
"fobPort": "Ningbo",
"categoryPath": ["Hardware", "Lighting & Electricals", "Industrial Lighting", "Work lights"],
"supplierName": "Market Union Co. Ltd",
"supplierUrl": "https://market-union.manufacturer.globalsources.com/",
"supplierLocation": "China",
"supplierYearsOnGlobalSources": 4,
"supplierLevel": 6,
"supplierBusinessTypes": ["Buying Office", "Trading Company", "Agent"],
"verifiedSupplier": true,
"verifiedManufacturer": false,
"tradeShows": "Exhibited at 2 GS shows"
}
Project: a verified-factory shortlist
Goal: for a product, list verified manufacturers with an MOQ under 500, one line per supplier, cheapest first, with how many matching products each one lists.
from collections import defaultdict
from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/global-sources-scraper").call(run_input={
"searchTerms": ["silicone kitchen utensils"],
"maxResultsPerSearch": 400,
"verifiedManufacturerOnly": True,
"maxMoq": 500,
})
suppliers = defaultdict(lambda: {"products": 0, "cheapest": None, "url": None, "level": None, "years": None})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
s = suppliers[p["supplierName"]]
s["products"] += 1
s["url"], s["level"], s["years"] = p["supplierUrl"], p["supplierLevel"], p["supplierYearsOnGlobalSources"]
if p["priceMin"] and (s["cheapest"] is None or p["priceMin"] < s["cheapest"]):
s["cheapest"] = p["priceMin"]
ranked = sorted(suppliers.items(), key=lambda kv: (kv[1]["cheapest"] or 1e9))
for name, s in ranked[:20]:
print(f"${s['cheapest'] or '?':>6} | P{s['level']} | {s['years']:>2} yrs | {s['products']:>3} products | {name} | {s['url']}")
Run it weekly on a schedule and diff the supplier set to see who is new in your category. Pair it with an Alibaba search on the same keyword and you have a two-marketplace price comparison in one script.
Pricing and limits
$1.50 per 1,000 products, no start fee. Products removed by your filters, duplicates and failed requests are never charged. Search results only: full spec sheets and per-quantity price tiers live on product pages, which this version doesn't open. Certificates are rarely printed on search cards, so the certificate fields are often empty, but the certificate filters work because Global Sources applies them itself. Some suppliers hide prices (about 5% in tests).
Store page: https://apify.com/rel8ble/global-sources-scraper
This article was drafted with AI and published by me.
Top comments (0)