Cách Xây dựng Trình Thu Thập Dữ Liệu Shopify với Playwright
Lead Scraping Automation Engineer
Tóm tắt nhanh:
- Một scraper Shopify nên tìm URL sản phẩm trước khi trích xuất các trường dữ liệu. Liên kết sản phẩm cùng nguồn (same-origin) bền vững hơn các class dùng để tạo kiểu của theme.
- Dữ liệu sản phẩm có cấu trúc công khai có thể lộ các biến thể mà không cần nhấp vào từng swatch. Hãy xác minh phản hồi trên cửa hàng đích trước khi dựa vào nó.
- Playwright có thể giữ ngữ cảnh trình duyệt trong khi đọc dữ liệu từ storefront. Giữ các request sản phẩm và tiền tệ bên trong ngữ cảnh đó.
- Ví dụ chạy cục bộ trả về định danh biến thể và giá trị giá thô. Quy đổi tiền tệ và so khớp giữa các cửa hàng vẫn là các tác vụ riêng.
- Miễn phí để bắt đầu. Tài khoản Scrapeless mới bao gồm runtime Scraping Browser miễn phí — đăng ký tại app.scrapeless.com.
Giới thiệu: Thẻ sản phẩm không mô tả mọi biến thể
Một thẻ sản phẩm trên storefront thường tóm tắt nhiều biến thể có thể mua được. Đọc giá hiển thị trên thẻ hữu ích cho việc dò tìm, nhưng nó không thể xác định giá và tình trạng còn hàng của mọi kích cỡ hoặc màu sắc.
Hướng dẫn trích xuất dữ liệu sản phẩm Shopify này dùng Playwright để mở một storefront công khai, tìm một liên kết sản phẩm và đọc dữ liệu biến thể có cấu trúc trong ngữ cảnh trình duyệt của trang. Ví dụ được cố ý giới hạn trong một sản phẩm. Bạn có thể kiểm tra các trường trả về trước khi xây dựng một job catalog lớn hơn.
Playwright điều khiển trình duyệt; hợp đồng trích xuất của bạn quyết định thế nào là một bản ghi hợp lệ. Quy trình cảnh báo giảm giá giải thích cách các quan sát đã ghi có thể trở thành các sự kiện ở bước sau.
Chọn nguồn trích xuất trước khi chọn selector
Nguồn hữu ích nhất là bề mặt công khai ổn định nhất chứa các trường bạn cần.
| Surface | Phù hợp tốt | Giới hạn cần kiểm tra |
|---|---|---|
| Phản hồi sản phẩm công khai | ID biến thể, mảng tùy chọn, các trường giá | Khả năng truy cập và độ đầy đủ thay đổi theo từng storefront |
| Dữ liệu có cấu trúc nhúng | Định danh sản phẩm và một offer được mô tả | Có thể chỉ tóm tắt offer đang được chọn |
| Các control sản phẩm được render | Trạng thái sau khi chọn kích cỡ, thị trường hoặc tùy chọn mua | Cần kiểm tra riêng cho từng cửa hàng |
| Mẫu URL liên kết sản phẩm | Dò tìm và khử trùng lặp | Storefront headless có thể dùng dạng route khác |
Ví dụ sử dụng một liên kết /products/<handle> quan sát được, sau đó đọc phản hồi .js công khai của sản phẩm. Giao diện Ajax product của Shopify tài liệu hóa route này và các request phụ thuộc locale. Mảng biến thể của nó có giới hạn được ghi nhận; đừng khẳng định bao phủ đầy đủ một catalog biến thể lớn chỉ vì request thành công.
Khi một storefront cần tương tác để lộ một offer, hãy kiểm tra các control của nó và chờ một marker trạng thái đặc trưng cho sản phẩm sau tương tác. Một selector giá tổng quát có thể vô tình chọn thẻ gợi ý, khoản tài chính hoặc giá của biến thể trước đó.
Yêu cầu và cài đặt
Ví dụ chạy cục bộ cần Node.js, pnpm và runtime Chromium của Playwright.
Dùng bản phát hành Node.js được Playwright đã cài đặt hỗ trợ. Môi trường đã kiểm chứng dùng Node.js 24. Phần mở rộng trên cloud yêu cầu thêm một tài khoản Scrapeless đang hoạt động và một khóa API dịch vụ trong SCRAPELESS_API_KEY; thông tin xác thực đó là điều kiện tiên quyết, và không cần thiết cho collector cục bộ.
Chạy các lệnh này trong một thư mục làm việc mới:
bash
pnpm add playwright @scrapeless-ai/sdk
pnpm exec playwright install chromium
Cài đặt thư viện trình duyệt của Playwright tách riêng package và bản tải về trình duyệt. Lưu các ví dụ JavaScript dưới dạng file .mjs để Node.js xử lý chúng như ES module. Phần mở rộng trên cloud dùng Scrapeless Node.js SDK.
Xây dựng collector dò tìm & trích xuất cục bộ
Collector tìm một thẻ neo sản phẩm đã được kiểm tra và trả về từng biến thể từ phản hồi có cấu trúc.
Lưu đoạn này thành shopify.mjs và chạy node shopify.mjs. Sản phẩm cụ thể là một ví dụ công khai, nên hãy kiểm tra lại URL và chính sách cửa hàng trước khi tái sử dụng. Script báo cáo thiếu thẻ neo dò tìm thay vì im lặng chuyển sang mặt hàng khác.
javascript
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
try {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.taylorstitch.com/', {
waitUntil: 'domcontentloaded', timeout: 45000
});
const result = await page.evaluate(async () => {
const link = Array.from(document.querySelectorAll('a[href]'))
.map(a => new URL(a.href))
.find(u => u.origin === location.origin &&
/^\/products\/jack-in-valley-plaid-waffle-2610\/?$/.test(u.pathname));
if (!link) throw new Error('Expected product anchor is absent');
const root = window.Shopify.routes.root;
const productResponse = await fetch(link.pathname.replace(/\/$/, '') + '.js');
const cartResponse = await fetch(root + 'cart.js');
if (!productResponse.ok || !cartResponse.ok) {
throw new Error('Product or currency response unavailable');
}
const product = await productResponse.json();
const cart = await cartResponse.json();
if (!product.id || !Array.isArray(product.variants) || !cart.currency) {
throw new Error('Incomplete public product response');
}
return {
product_id: String(product.id), title: product.title,
source_url: link.href, currency: cart.currency,
observed_at: new Date().toISOString(),
variants: product.variants.map(v => ({
variant_id: String(v.id), options: v.options,
price_raw: v.price, compare_at_price_raw: v.compare_at_price ?? null,
available: v.available, sku: v.sku ?? null
}))
};
});
console.log(JSON.stringify(result, null, 2));
} finally {
await browser.close();
}
domcontentloaded là ranh giới điều hướng, chứ không phải một lời hứa rằng mọi widget đã hoàn tất. Trang chủ được kiểm tra lộ thẻ neo sản phẩm tại ranh giới đó. Với một theme khác, hãy chờ đúng liên kết hoặc control sản phẩm bạn cần trước khi trích xuất.
Request giỏ hàng chỉ đọc xác định đơn vị tiền tệ trình bày cho ngữ cảnh trình duyệt đó. Nó không thêm sản phẩm hay bắt đầu quy trình checkout. Lần đọc sản phẩm và tiền tệ vẫn diễn ra ở các thời điểm khác nhau; đừng mô tả chúng như một snapshot tồn kho nguyên tử.
Giữ nguyên hợp đồng biến thể được trả về
Kết quả là một phong bì sản phẩm với một mảng biến thể, không phải là lịch sử giá của đối thủ cạnh tranh đã được chuẩn bị sẵn.
| Trường | Ý nghĩa | Quy tắc kiểm tra |
|---|---|---|
product_id |
Mã định danh sản phẩm của cửa hàng, được tuần tự hóa dưới dạng văn bản | Phải có |
source_url |
URL sản phẩm công khai được phát hiện | Giữ nguyên host của storefront |
currency |
Đơn vị tiền tệ được báo cáo trong ngữ cảnh trình duyệt hiện tại | Phải được biết trước khi so sánh |
observed_at |
Thời điểm thu thập của bộ thu thập | Giữ cùng với các trường thay đổi |
variant_id |
Mã định danh biến thể của cửa hàng | Phải được giữ liên kết với cha của nó |
options |
Giá trị tùy chọn nguồn | Giữ nguyên thứ tự và giá trị |
price_raw |
Giá trị tiền tệ trong đơn vị gốc của phản hồi | Xác nhận ngữ nghĩa đơn vị trước khi hiển thị |
compare_at_price_raw |
Giá trị so sánh có thể rỗng | Null không có nghĩa là bằng không |
available |
Tín hiệu khả năng mua công khai | Không phải số lượng tồn kho |
sku |
Mã SKU thương nhân tùy chọn từ nguồn | Không phải là mã định danh sản phẩm chung |
Sản phẩm được kiểm tra chứa sáu biến thể và ngữ cảnh báo cáo USD. Những quan sát đó thiết lập rằng đường dẫn này trích xuất dữ liệu sản phẩm thực từ nguồn đã chọn; chúng không thiết lập rằng mọi storefront Shopify đều sử dụng cùng một theme hoặc cấu hình truy cập.
Từ vựng sản phẩm hữu ích để phân biệt các thuộc tính nhận dạng và mô tả với các trường thương mại thay đổi của một ưu đãi. Giữ ranh giới đó khi làm phẳng các biến thể thành các dòng trong kho.
Bắt đầu Scraping với Scrapeless
Tăng cường quy trình web scraping và tự động hóa của bạn với Scrapeless!
Đăng ký ngay hôm nay và nhận $5 tín dụng miễn phí — không cần thẻ tín dụng.Nhận tín dụng miễn phí của bạn ngay trong Bảng điều khiển Scrapeless.
Mở Rộng Khả Năng Khám Phá Mà Không Mất Ranh Giới Danh Mục
Khám phá danh mục cần một quy tắc dừng rõ ràng và một tập hợp bền vững các URL đã truy cập.
Đối với một trình thu thập dựa trên bộ sưu tập, hãy kiểm tra liên kết trang tiếp theo thực tế hoặc cơ chế phân trang được tài liệu hóa của storefront. Giữ việc khám phá bộ sưu tập tách biệt với trích xuất sản phẩm. Khử trùng lặp các đường dẫn sản phẩm chuẩn để một mặt hàng xuất hiện trong nhiều bộ sưu tập không trở thành nhiều sản phẩm.
Ghi lại liệu một lần chạy là một phạm vi đầy đủ đã được phê duyệt hay một mẫu một phần. Ví dụ một sản phẩm đơn lẻ là một mẫu; nó không thể xác lập kích thước danh mục của cửa hàng. Giới hạn mảng biến thể, bộ sưu tập đã lọc, hoặc một trang không truy cập được nên xuất hiện như một giới hạn vùng phủ trong đầu ra của bạn.
Để scrape các trang sản phẩm Shopify động, hãy giữ nguyên lựa chọn tùy chọn chính xác và trạng thái hiển thị khi nguồn có cấu trúc là không đủ. Không sao chép giá tối thiểu của cha vào mọi dòng biến thể. Dừng lại khi ưu đãi đã chọn không thể được xác định một cách tự tin.
Phần Mở Rộng Đám Mây cho Playwright
Scrapeless Agent Browser có thể chạy một phiên Playwright từ xa trong khi bộ thu thập của bạn vẫn giữ logic kiểm tra riêng.
Sử dụng kết nối Playwright được tài liệu hóa khi việc lưu trữ trình duyệt cục bộ trở thành gánh nặng vận hành. SDK tạo phiên trình duyệt; Playwright gắn vào endpoint được trả về của nó.
Lưu ý: Kết nối đám mây sau đây yêu cầu khóa API dịch vụ Scrapeless đang hoạt động trong
SCRAPELESS_API_KEY. Ví dụ thu thập cục bộ chạy độc lập. Bước phụ thuộc vào thông tin xác thực này phải được thực thi trong tài khoản của bạn trước khi triển khai đường dẫn đám mây.
javascript
import { Scrapeless } from '@scrapeless-ai/sdk';
import { chromium } from 'playwright';
const client = new Scrapeless();
const { browserWSEndpoint } = await client.browser.create({
sessionName: 'shopify-public-product',
sessionTTL: 180,
proxyCountry: 'US'
});
const browser = await chromium.connectOverCDP(browserWSEndpoint);
try {
const page = await browser.newPage();
await page.goto('https://www.taylorstitch.com/', {
waitUntil: 'domcontentloaded'
});
console.log(await page.title());
} finally {
await browser.close();
}
Sau khi xác nhận kết nối, hãy áp dụng cùng quy trình khám phá và trích xuất trong phiên đó. Định tuyến quốc gia là một tham số của trình duyệt; hãy xác minh đơn vị tiền tệ và locale của storefront thay vì suy ra chúng chỉ từ thiết lập proxy. Đánh giá Agent Browser và giá runtime so với lịch trình thu thập của bạn.
Khắc Phục Sự Thiếu Dữ Liệu Tại Ranh Giới Nguồn
Thiếu dữ liệu nên được chẩn đoán trước khi nó trở thành một bản ghi sản phẩm được lưu trữ.
| Triệu chứng | Kiểm tra | Cách xử lý an toàn |
|---|---|---|
| Không có anchor sản phẩm | Đường dẫn chuẩn và trạng thái thuộc bộ sưu tập hiện tại | Đánh dấu khám phá chưa hoàn tất |
| HTML thay vì JSON | Thách thức truy cập hoặc hành vi endpoint khác | Tạm dừng trích xuất |
| Biến thể vắng mặt | Giới hạn phản hồi và sản phẩm đã chọn | Đánh dấu vùng phủ chưa hoàn tất |
| Tiền tệ đã thay đổi | Locale, cookie, và lựa chọn thị trường | Bắt đầu một chuỗi ngữ cảnh riêng biệt |
| Giá trống | Ngữ nghĩa của ưu đãi đã chọn và trường nguồn | Giữ không xác định; không bao giờ chèn số 0 |
Xem lại các quy tắc truy cập của cửa hàng trước khi lên lịch công việc. Tiêu chuẩn loại trừ trình thu thập thông tin mô tả các tùy chọn của robot, trong khi điều khoản và quyền cấp phép chi phối ranh giới truy cập rộng hơn.
Kết luận: Giữ Khám phá, Ngữ cảnh và Kết quả Đầu ra Cùng nhau
Một trình thu thập Shopify với Playwright trở nên dễ bảo trì hơn khi việc khám phá sản phẩm sử dụng các liên kết bền vững và việc trích xuất biến thể sử dụng một nguồn có cấu trúc đã được kiểm tra. Bảo toàn ngữ cảnh trình duyệt, giữ các trường tiền tệ rõ ràng, và xác thực kết quả trước khi lưu trữ. Chỉ mở rộng vượt ra ngoài mẫu sau khi đã xác minh phân trang, giới hạn truy cập và tính đầy đủ biến thể cho cửa hàng mục tiêu.
Sẵn sàng Xây dựng Quy trình Bộ sưu tập Shopify của Bạn?
Tham gia cộng đồng của chúng tôi để nhận gói miễn phí và kết nối với các nhà phát triển đang làm việc trên thu thập thương mại điện tử dựa trên trình duyệt: Discord · Telegram.
Đăng ký tại app.scrapeless.com và áp dụng hợp đồng trích xuất đã được kiểm tra cho các nguồn sản phẩm đã được phê duyệt của bạn.
Câu hỏi thường gặp
Hỏi: Việc thu thập dữ liệu công khai về sản phẩm Shopify có hợp pháp không?
Câu trả lời phụ thuộc vào khu vực pháp lý của bạn, điều khoản của cửa hàng, phương thức truy cập và mục đích sử dụng dự định. Xem lại các điều kiện đó và tham khảo ý kiến cố vấn pháp lý khi cần. Giữ quy trình làm việc trên các bề mặt sản phẩm công khai, được cho phép.
Hỏi: Có cần proxy để xây dựng một trình thu thập Shopify không?
Ví dụ cục bộ đã được kiểm tra đọc một nguồn công khai có thể truy cập mà không cần proxy. Phần mở rộng đám mây đặt proxyCountry thành US để định tuyến nhất quán; việc chọn đơn vị tiền tệ và thị trường vẫn cần được xác thực riêng.
Hỏi: Trình thu thập nên xử lý trang WAF hoặc Access Denied như thế nào?
Xem kết quả như một bộ sưu tập chưa được xác nhận, không phải dữ liệu sản phẩm. Đối với quy trình làm việc trên đám mây đã được ủy quyền, hãy mở trang chủ trước trong cùng phiên, sau đó đợi một dấu hiệu sản phẩm thực. Dừng lại khi cửa hàng không cho phép quyền truy cập được yêu cầu.
Hỏi: Điều gì thay đổi khi một giao diện Shopify xoay vòng các lớp DOM của nó?
Kiểm tra lại đánh dấu trực tiếp và bảo toàn URL sản phẩm ổn định hoặc nguồn có cấu trúc khi có thể. Chỉ cập nhật bộ chọn sau khi xác nhận rằng chúng trỏ đến sản phẩm và biến thể đã chọn.
Hỏi: Có thể chạy cái này mà không cần tác nhân AI không?
Có. Script cục bộ chạy trực tiếp với Node.js. Một tác nhân có thể giúp kiểm tra một cửa hàng khác, nhưng không bắt buộc để thực thi bộ thu thập.
Hỏi: Nên xử lý tính đồng thời và URL sản phẩm như thế nào?
Bắt đầu với một worker cho mỗi cửa hàng và URL chuẩn được phát hiện từ các liên kết công khai của nó. Nếu cửa hàng cho phép thu thập song song, hãy sử dụng giới hạn ban đầu là ba worker cho mỗi host hoặc giới hạn nghiêm ngặt hơn của nó. Giữ việc chọn biến thể tách biệt khỏi danh tính sản phẩm chuẩn.
Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.



