Cách Đo Lường Hiệu Suất của Web Unlockers: Một Thiết Kế Thử Nghiệm Có Thể Tái Lập
Senior Cybersecurity Analyst
TL;DR:
- Một tiêu chuẩn kiểm tra mở khóa web phải đo lường nội dung sử dụng được, không chỉ trạng thái HTTP. Một phản hồi có thể thành công về mặt kỹ thuật trong khi chứa một trang thách thức, vỏ rỗng, khu vực sai hoặc kết xuất chưa hoàn tất.
- Mẫu URL nên được phân tầng trước khi kiểm tra. Tách biệt các trang tĩnh, trang được máy chủ kết xuất, ứng dụng JavaScript, chuyển hướng và thách thức kiểm tra lưu lượng để một danh mục dễ dàng không thể ẩn danh mục khác.
- Độ trễ cần có sự phân bố. Báo cáo trung vị và một phần trăm cao cùng với tỷ lệ phản hồi và tỷ lệ thành công nội dung.
- Chi phí hiệu quả phụ thuộc vào các giao hàng sử dụng được. Chia chi tiêu quan sát được cho các phản hồi vượt qua các kiểm tra nội dung, không phải cho các nỗ lực đã gửi.
- Khả năng tái tạo đến từ một bản kê. Ghi lại danh mục URL, dấu hiệu mong đợi, yêu cầu kết xuất, khu vực, cài đặt yêu cầu và mã đo lường cho từng ô kiểm tra.
Giới thiệu: Một Tiêu Chuẩn Là Một Hợp Đồng Kiểm Tra
Một tiêu chuẩn kiểm tra mở khóa web thất bại khi “thành công” chỉ có nghĩa là một điểm cuối trả về phản hồi.
Câu hỏi hữu ích là liệu dịch vụ có cung cấp nội dung công khai dự định dưới dạng mà trình phân tích downstream có thể sử dụng hay không. Điều đó đòi hỏi một hợp đồng kiểm tra: các URL đã biết, nhãn danh mục, dấu hiệu nội dung mong đợi, cài đặt yêu cầu nhất quán, số lượng mẫu giới hạn và quy tắc chấm điểm được quyết định trước khi kết quả xuất hiện.
Hướng dẫn này xây dựng hợp đồng đó cho Scrapeless Web Unlocker. Nó sử dụng unlocker.webunlocker diễn viên hiện tại và POST /api/v2/unlocker/request bề mặt, nhưng thiết kế có thể áp dụng cho bất kỳ dịch vụ mở khóa được quản lý nào.
Một Web Unlocker Làm Gì
Một web unlocker chấp nhận một URL mục tiêu và trả về nội dung trang công khai sau khi quản lý công việc mạng và trình duyệt cần thiết cho yêu cầu đó.
Điều này khác với việc cung cấp một địa chỉ proxy. Một proxy thay đổi đường dẫn mạng; ứng dụng gọi vẫn sở hữu các tiêu đề, thực thi trình duyệt, cookie, kiểm tra độ hoàn chỉnh của trang và phân tích phản hồi. Một web unlocker được quản lý chấp nhận yêu cầu cấp cao hơn và trả về nội dung qua một API.
Scrapeless Web Unlocker chấp nhận các đối tượng actor, input và proxy. Điểm cuối hiện tại hỗ trợ unlocker.webunlocker diễn viên, một URL mục tiêu, một phương thức HTTP, điều khiển chuyển hướng, tiêu đề yêu cầu tùy chọn và một quốc gia proxy. Sản phẩm có thể trả về HTML, JSON, Markdown hoặc một ảnh chụp màn hình, và chỉ những yêu cầu thành công mới bị tính phí.
Tiêu chuẩn kiểm tra nên đánh giá sản phẩm được cung cấp, không suy diễn chất lượng từ hạ tầng được sử dụng để lấy sản phẩm đó.
Định Nghĩa Thành Công Trước Khi Gửi Yêu Cầu
Kết quả tiêu chuẩn kiểm tra nên vượt qua bốn kiểm tra độc lập.
- Thành công vận chuyển. Yêu cầu Scrapeless API hoàn tất với trạng thái HTTP thành công theo tiêu chuẩn ngữ nghĩa HTTP.
- Danh tính mục tiêu. Phản hồi tương ứng với URL dự định hoặc một URL cuối được phép.
- Thành công nội dung. Một dấu hiệu cụ thể cho mục tiêu xuất hiện và một dấu hiệu trang chặn đã biết không xuất hiện.
- Tính hoàn chỉnh. Nội dung được cung cấp chứa phần yêu cầu, sàn số lượng bản ghi, hoặc phần tử được kết xuất cho trường hợp kiểm tra đó.
Giữ những kiểm tra này riêng biệt trong kết quả thô. Một thành công vận chuyển với một dấu hiệu nội dung bị thiếu không phải là một giao hàng sử dụng được. Một dấu hiệu hợp lệ với khu vực sai cũng là một thất bại khi địa lý là một phần của yêu cầu.
Xây Dựng Một Mẫu URL Phân Tầng
Một tiêu chuẩn kiểm tra mở khóa web có thể tái tạo bắt đầu với các danh mục đại diện cho khối lượng công việc sản xuất.
| Danh mục | Những gì mà nó kiểm tra | Các trường trong bản kê |
|---|---|---|
| Kiểm soát tĩnh | Định tuyến cơ bản và tính toàn vẹn phản hồi | URL, dấu hiệu tiêu đề mong đợi |
| Trang được máy chủ kết xuất | Giao hàng HTML từ một ứng dụng bình thường | URL, dấu hiệu tiêu đề ổn định |
| Trang được kết xuất bằng JavaScript | Thực thi trình duyệt và nội dung được tạo | URL, dấu hiệu đã kết xuất, yêu cầu kết xuất |
| Đường chuyển hướng | Xử lý URL cuối | bắt đầu URL, URL cuối được phép |
| Trang kiểm tra lưu lượng | Xử lý quyền truy cập được quản lý | URL, dấu hiệu nội dung mong đợi, các dấu hiệu thách thức đã biết |
| Trang theo vùng | Giao hàng cụ thể theo địa lý | URL, quốc gia proxy, dấu hiệu địa phương |
Không nên lấy tất cả URL từ một miền hoặc một lớp độ khó. Nếu khối lượng công việc sản xuất là thương mại điện tử, tin tức, tìm kiếm và tài liệu, hãy giữ các nhóm đó rõ ràng trong kết quả. Mỗi nhóm nên đóng góp cùng một số lượng yêu cầu hoặc nhận một trọng số sản xuất rõ ràng.
Bản kê tiêu chuẩn kiểm tra thuộc về kiểm soát phiên bản. Một hàng nên bao gồm case_id, category, url, expected_marker, blocked_markers, proxy_country, redirect và render_required. Điều này giúp các so sánh sau này sử dụng cùng một mục tiêu và logic chấm điểm.
Quy tắc:
- Đầu ra CHỈ là văn bản đã dịch — không giải thích, không mã bọc thêm.
- Giữ nguyên cấu trúc Markdown/HTML (tiêu đề, danh sách, liên kết, bảng) chính xác.
- Giữ nguyên bất kỳ mã giữ chỗ nào như ```python
import csv
import os
import statistics
import time
from pathlib import Path
import requests
ENDPOINT = "https://api.scrapeless.com/api/v2/unlocker/request"
API_KEY = os.environ["SCRAPELESS_API_KEY"]
SAMPLES_PER_CASE = 3
CASES = [
{
"case_id": "static-control",
"category": "static",
"url": "https://example.com",
"expected_marker": "Example Domain",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "html-control",
"category": "server-rendered",
"url": "https://httpbin.io/html",
"expected_marker": "Herman Melville",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "js-page",
"category": "javascript",
"url": "https://quotes.toscrape.com/js/",
"expected_marker": "Quotes to Scrape",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "redirect-control",
"category": "redirect",
"url": "https://httpbin.io/redirect/1",
"expected_marker": "url",
"proxy_country": "ANY",
"redirect": True,
},
]
def run_case(case):
payload = {
"actor": "unlocker.webunlocker",
"input": {
"url": case["url"],
"method": "GET",
"redirect": case["redirect"],
},
"proxy": {"country": case["proxy_country"]},
}
started = time.perf_counter()
response = requests.post(
ENDPOINT,
headers={
"Content-Type": "application/json",
"x-api-token": API_KEY,
},
json=payload,
timeout=120,
)
elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
response.raise_for_status()
body = response.text
return {
"case_id": case["case_id"],
"category": case["category"],
"elapsed_ms": elapsed_ms,
"api_status": response.status_code,
"body_bytes": len(response.content),
"marker_found": case["expected_marker"] in body,
}
rows = []
for case in CASES:
for sample in range(1, SAMPLES_PER_CASE + 1):
row = run_case(case)
row["sample"] = sample
rows.append(row)
Path("benchmark-results.csv").write_text("", encoding="utf-8")
with open("benchmark-results.csv", "w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
latencies = [row["elapsed_ms"] for row in rows]
usable = [row for row in rows if row["marker_found"]]
print({
"requests": len(rows),
"usable_deliveries": len(usable),
"response_rate": len(rows) / len(rows),
"content_success_rate": len(usable) / len(rows),
"latency_p50_ms": statistics.median(latencies),
"result_file": "benchmark-results.csv",
})
hoặc `unlocker.webunlocker` ĐÚNG như vậy; không bao giờ dịch, sắp xếp lại, hợp nhất, hoặc định dạng lại chúng. 4. KHÔNG thêm hoặc bớt mã bọc, và KHÔNG bao bọc văn bản bình thường vào một mã bọc.
Tôn trọng các điều khoản và chính sách truy cập của mỗi mục tiêu. Giao thức loại trừ Robots định nghĩa một cách tiêu chuẩn để chủ sở hữu trang web giao tiếp sở thích thu thập thông tin, nhưng nó không thay thế việc xem xét pháp lý hoặc ủy quyền cụ thể cho trang web.
Gửi Yêu cầu Mở khóa Web có Kiểm soát
Yêu cầu Mở khóa Web hiện tại sử dụng một điểm cuối và một khóa API trong tiêu đề x-api-token.
Lưu ý: Khối đo lường yêu cầu một khóa API Scrapeless và gói Python
requests. Chạy nó trong tài khoản mà việc sử dụng và xuất hóa đơn sẽ được phân tích.
python
import csv
import os
import statistics
import time
from pathlib import Path
import requests
ENDPOINT = "https://api.scrapeless.com/api/v2/unlocker/request"
API_KEY = os.environ["SCRAPELESS_API_KEY"]
SAMPLES_PER_CASE = 3
CASES = [
{
"case_id": "static-control",
"category": "static",
"url": "https://example.com",
"expected_marker": "Example Domain",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "html-control",
"category": "server-rendered",
"url": "https://httpbin.io/html",
"expected_marker": "Herman Melville",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "js-page",
"category": "javascript",
"url": "https://quotes.toscrape.com/js/",
"expected_marker": "Quotes to Scrape",
"proxy_country": "ANY",
"redirect": False,
},
{
"case_id": "redirect-control",
"category": "redirect",
"url": "https://httpbin.io/redirect/1",
"expected_marker": "url",
"proxy_country": "ANY",
"redirect": True,
},
]
def run_case(case):
payload = {
"actor": "unlocker.webunlocker",
"input": {
"url": case["url"],
"method": "GET",
"redirect": case["redirect"],
},
"proxy": {"country": case["proxy_country"]},
}
started = time.perf_counter()
response = requests.post(
ENDPOINT,
headers={
"Content-Type": "application/json",
"x-api-token": API_KEY,
},
json=payload,
timeout=120,
)
elapsed_ms = round((time.perf_counter() - started) * 1000, 1)
response.raise_for_status()
body = response.text
return {
"case_id": case["case_id"],
"category": case["category"],
"elapsed_ms": elapsed_ms,
"api_status": response.status_code,
"body_bytes": len(response.content),
"marker_found": case["expected_marker"] in body,
}
rows = []
for case in CASES:
for sample in range(1, SAMPLES_PER_CASE + 1):
row = run_case(case)
row["sample"] = sample
rows.append(row)
Path("benchmark-results.csv").write_text("", encoding="utf-8")
with open("benchmark-results.csv", "w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
latencies = [row["elapsed_ms"] for row in rows]
usable = [row for row in rows if row["marker_found"]]
print({
"requests": len(rows),
"usable_deliveries": len(usable),
"response_rate": len(rows) / len(rows),
"content_success_rate": len(usable) / len(rows),
"latency_p50_ms": statistics.median(latencies),
"result_file": "benchmark-results.csv",
})
Mẫu này được cố ý nhỏ và công khai. Mở rộng nó với các mục tiêu sản xuất được ủy quyền chỉ sau khi quy trình và các quy tắc chấm điểm đã ổn định.
Bắt đầu Thu thập dữ liệu với Scrapeless
Khởi động quy trình thu thập dữ liệu và tự động hóa web của bạn với Scrapeless!
Đăng ký hôm nay và nhận 5 đô la tín dụng miễn phí — không cần thẻ tín dụng.Đòi hỏi tín dụng miễn phí của bạn ngay bây giờ tại Bảng điều khiển Scrapeless.
Đo lường Tỷ lệ Phản hồi và Thành công Nội dung Tách biệt
Tỷ lệ phản hồi đo lường xem API đã hoàn thành thành công hay chưa. Tỷ lệ thành công nội dung đo lường xem đối tượng trả về có vượt qua các kiểm tra cụ thể của mục tiêu hay không.
Sử dụng các công thức này:
- Tỷ lệ phản hồi = số phản hồi API thành công / tổng số yêu cầu.
- Tỷ lệ thành công nội dung = số phản hồi vượt qua kiểm tra danh tính, đánh dấu, trang chặn và độ hoàn chỉnh / tổng số yêu cầu.
- Chất lượng nội dung có điều kiện = số sản phẩm giao hàng khả dụng / số phản hồi API thành công.
Tỷ lệ thứ ba giải thích xem dịch vụ có trả về nội dung kỹ thuật thành công nhưng không sử dụng được hay không. Giữ nguyên lý do thô cho mọi kiểm tra nội dung thất bại, chẳng hạn như missing_marker, known_challenge_marker, wrong_final_url hoặc below_record_floor.
Một mã đánh dấu văn bản cố định chỉ là điểm xuất phát. Đối với một lưới sản phẩm, yêu cầu ít nhất một thùng chứa sản phẩm ổn định và các trường mà sơ đồ hạ nguồn cần. Đối với một trang JavaScript, khẳng định một phần tử đã được cung cấp thay vì một tiêu đề shell tồn tại trước khi hiển thị.
Báo cáo Độ trễ là p50 và p95
Độ trễ nên được báo cáo như một phân phối vì một trung bình đơn lẻ che giấu các yếu tố chậm của khối lượng công việc.
Ghi lại thời gian đã trôi qua từ ngay trước khi yêu cầu API đến khi toàn bộ nội dung phản hồi có sẵn. Báo cáo p50 cho yêu cầu điển hình và p95 cho yếu tố chậm hơn. Mô hình Thời gian Điều hướng W3C giải thích tại sao điều hướng có các giai đoạn thời gian khác biệt, nhưng một điểm kiểm tra API bên ngoài nên sử dụng một đồng hồ đầu cuối duy nhất nhất quán trừ khi nhà cung cấp công khai dữ liệu giai đoạn tương tự.
Tính toán các phần trăm cho toàn bộ mẫu và theo từng danh mục. Một kết quả tĩnh mạnh không nên che giấu một phân phối JavaScript hoặc phân phối theo vùng yếu. Công bố kích thước mẫu bên cạnh mọi phần trăm, và tránh so sánh các phần trăm được sản xuất bằng các phương pháp tính toán khác nhau.
Tài liệu phương pháp phân vị bên cạnh kết quả để một điều hành viên khác có thể tái tạo cùng các phép tính p50 và p95. Tài liệu thống kê Python làm cho việc chọn phương pháp trở nên rõ ràng và là một tài liệu tham khảo trung lập hữu ích khi ghi lại phép tính đó.
Tính Toán Chi Phí Hiệu Quả trên Giao Hàng Khả Dụng
Chi phí hiệu quả chuyển đổi việc lập hóa đơn thành kết quả khối lượng công việc.
Sử dụng hóa đơn hoặc xuất hóa đơn cho khoảng thời gian đo lường thay vì nhân số yêu cầu với một giá được sao chép từ một trang tiếp thị. Sau đó tính toán:
effective cost per usable delivery = observed spend / usable deliveries
Nếu quy trình sản xuất trích xuất các bản ghi, thêm một phép đo thứ hai:
effective cost per accepted record = observed spend / records passing schema checks
Việc này giữ cho điểm chuẩn nhất quán với nhiệm vụ kinh doanh. Một mức giá yêu cầu thấp hơn không giúp ích khi phản hồi thiếu các trường mà quy trình cần. Scrapeless chỉ tính phí cho các yêu cầu Mở khóa Web thành công, nhưng điểm chuẩn vẫn nên áp dụng định nghĩa chất lượng nội dung của riêng nó trước khi gọi một giao hàng là khả dụng.
Kiểm Tra Tính Toàn Vẹn JavaScript
Tính toàn vẹn JavaScript đo lường xem nội dung trả về có bao gồm trạng thái được sản xuất sau khi thực thi của khách hàng hay không.
Chọn một phần tử ổn định chỉ xuất hiện sau khi ứng dụng được hiển thị. Ghi lại bộ chọn hoặc mã đánh dấu văn bản của nó trong bảng khai báo. Một bài kiểm tra mạnh mẽ hơn cũng kiểm tra số lượng bản ghi tối thiểu và một trường được lấp đầy từ dữ liệu đã hiển thị thay vì shell HTML ban đầu.
Đừng chỉ sử dụng kích thước cơ thể. Văn bản đồng ý, chrome điều hướng, hoặc tài liệu thách thức có thể lớn mà không chứa dữ liệu mục tiêu. Kết hợp kích thước với các khẳng định cấu trúc.
Đối với đầu ra ảnh chụp màn hình, xác định một vùng hình ảnh và một phần tử mong đợi trước khi chạy. Ảnh chụp màn hình là bằng chứng hữu ích, nhưng chúng cần một khẳng định của con người hoặc thị giác để trở thành kết quả được chấm điểm.
Giữ cho Thí nghiệm Có thể Tái Tạo
Một thí nghiệm có thể tái sản xuất ghi lại đủ chi tiết để một nhà vận hành khác có thể chạy lại cùng một ma trận.
Lưu trữ:
- bản kê và phiên bản của nó;
- kịch bản chuẩn và tệp khóa phụ thuộc;
- cài đặt yêu cầu, quốc gia proxy và chính sách chuyển hướng;
- thời gian bắt đầu và kết thúc trong dữ liệu thô;
- trạng thái phản hồi, URL cuối cùng khi có sẵn, thời gian trôi qua và kích thước nội dung;
- mọi khẳng định nội dung và lý do thất bại;
- phương pháp phần trăm và mã tổng hợp;
- xuất dữ liệu sử dụng hoặc thanh toán được sử dụng cho các phép tính chi phí hiệu quả.
Chạy các nhà cung cấp theo thứ tự cân bằng khi so sánh hơn một dịch vụ. Các điều kiện miền thay đổi theo thời gian, vì vậy việc hoàn tất tất cả các yêu cầu cho một dịch vụ trước khi bắt đầu một dịch vụ khác có thể gây ra thiên lệch về thời gian. Giữ độ song song cố định và đủ nhỏ để bài kiểm tra đo lường dịch vụ hơn là một nút thắt phía client.
Đọc kết quả mà không vượt quá yêu cầu
Một bài kiểm tra mở khóa web mô tả các URL đã chọn, cài đặt, vị trí và khoảng thời gian đo lường.
Báo cáo kết quả theo danh mục trước khi đưa ra điểm số tổng thể. Bao gồm khoảng tin cậy hoặc số liệu thô khi mẫu nhỏ. Phân tách các trường hợp không được hỗ trợ ra khỏi các trường hợp thất bại. Ghi chú bất kỳ mục tiêu nào bị loại bỏ sau khi chạy và giữ lại lý do, vì việc thay đổi bí mật tập hợp URL sẽ phá vỡ tính khả so sánh.
Tránh các tuyên bố phổ quát như “hoạt động trên mọi trang web.” Kết luận có thể bảo vệ được là hẹp hơn: dịch vụ nào đã tạo ra nội dung có thể sử dụng cho bản kê này dưới những cài đặt này.
Kết luận: Làm cho nội dung có thể sử dụng trở thành đơn vị thành công
Một bài kiểm tra mở khóa web có thể tái sản xuất bắt đầu với một bản kê và kết thúc với các nội dung có thể sử dụng. Phân loại tập hợp URL, xác định các khẳng định nội dung, đo lường thành công phản hồi và nội dung riêng biệt, báo cáo độ trễ p50 và p95, và tính toán chi phí từ chi tiêu quan sát trên từng đầu ra được chấp nhận.
Xem tính giá Scrapeless, theo dõi tài liệu Web Unlocker hiện tại, và sử dụng hướng dẫn Scraper API để đặt thí nghiệm vào trong một quy trình dữ liệu rộng hơn.
Sẵn sàng để đo lường Web Unlocker trên khối lượng công việc của bạn?
Tham gia cộng đồng Scrapeless để so sánh các thí nghiệm thu thập dữ liệu có thể tái sản xuất: Discord · Telegram.
Tạo một tài khoản miễn phí tại app.scrapeless.com và chạy bản kê trên một tập hợp nhỏ các trang công cộng được ủy quyền.
Câu hỏi thường gặp
Q: Một bài kiểm tra mở khóa web nên đo lường gì?
Một bài kiểm tra mở khóa web nên đo lường tỷ lệ phản hồi API, tỷ lệ thành công nội dung, phân phối độ trễ, độ hoàn thiện JavaScript và chi phí hiệu quả trên mỗi đầu ra có thể sử dụng.
Q: Tại sao HTTP 200 không đủ để tính là thành công?
HTTP 200 chỉ mô tả trạng thái phản hồi. Nội dung có thể vẫn chứa trang sai, tài liệu xác thực lưu lượng, một khung ứng dụng rỗng, hoặc dữ liệu mục tiêu không hoàn chỉnh.
Q: Bài kiểm tra nên bao gồm bao nhiêu URL?
Bài kiểm tra nên bao gồm đủ URL để đại diện cho mọi danh mục sản xuất và báo cáo sự không chắc chắn, nhưng không có quy định tối thiểu phổ quát. Bắt đầu với một bản kê cân bằng nhỏ, xác thực khung, sau đó mở rộng mẫu được ủy quyền.
Q: Thế nào là tính toán độ trễ p95?
Tính toán p95 với một phương pháp phân bổ phân lượng tài liệu trên một mẫu được xác định rõ ràng, và công bố số lượng yêu cầu bên cạnh kết quả. Sử dụng cùng một phương pháp cho mọi dịch vụ và danh mục được so sánh.
Q: Có hợp pháp để kiểm tra các trang web công cộng không?
Tính hợp pháp phụ thuộc vào quyền tài phán, mục đích, điều khoản mục tiêu và loại dữ liệu. Sử dụng các mục tiêu công cộng được ủy quyền, giảm thiểu tải, tôn trọng chính sách trang web, và nhận lời khuyên pháp lý cho việc sử dụng sản xuất dự kiến.
Q: Web Unlocker có giống như một proxy không?
Không. Một proxy thay đổi lộ trình mạng, trong khi Web Unlocker chấp nhận một yêu cầu mức cao hơn và quản lý quy trình truy cập trang và giao hàng nội dung phía sau một API.
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.



