用 Python 不開瀏覽器在 Global Sources 尋找已核實工廠
Finding verified factories on Global Sources with Python, no browser
作者開發 Global Sources Scraper,讓用戶毋須使用瀏覽器,便可透過 Python 或 Node 從 Global Sources 擷取產品及供應商資料。這款 Apify 付費工具每 1,000 件產品收費 $1.50,並可按製造商核實狀態、MOQ 和價格篩選。工具只擷取搜尋結果,不會開啟產品頁面取得完整規格表或按數量劃分的價格。
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.
來源:DEV Community · dev.to