DR hàng loạt cho danh sách khách hàng, dưới dạng một job Python 40 dòng
Bạn có một bảng tính các tên miền và một bảng điều khiển cần một số liệu cho mỗi hàng. Một công cụ kiểm tra miền backlink cho công việc này chủ yếu là phần xử lý dữ liệu, và kịch bản này chính là phần xử lý đó.

Kịch bản
Nó đọc domains.txt, gửi 200 tên miền mỗi yêu cầu, lưu trữ từng phản hồi thô trong SQLite và in ra chi phí của lần chạy. Chúng tôi lưu toàn bộ nội dung vì tên các trường tốt nhất là sao chép từ phản hồi thực tế, không phải từ bài viết trên blog.
import os, sqlite3, time, json, requests
BASE = "https://seomasters.dev/api.php"
KEY = os.environ["SEO_API_KEY"]
BATCH = 200
db = sqlite3.connect("dr.db")
db.execute("create table if not exists raw (ts int, batch text, body text)")
domains = [d.strip() for d in open("domains.txt") if d.strip()]
spent = 0
for i in range(0, len(domains), BATCH):
chunk = domains[i:i + BATCH]
for attempt in range(4):
try:
r = requests.get(BASE, timeout=30,
params={"action": "bulk_dr", "domains": ",".join(chunk)},
headers={"Authorization": "Bearer " + KEY})
break
except requests.RequestException:
time.sleep(2 ** attempt)
else:
raise SystemExit(f"network gave up at batch {i}")
if r.status_code in (401, 402):
raise SystemExit(f"HTTP {r.status_code}: fix the key or top up, do not retry")
body = r.json()
if not body.get("ok"):
raise SystemExit(f"ok=false at batch {i}: {json.dumps(body)[:300]}")
db.execute("insert into raw values (?,?,?)", (int(time.time()), str(i), r.text))
db.commit()
print(body.get("_credits"))Mỗi phần đang làm gì
action=bulk_dr
Một credit mỗi lần gọi. Giới hạn tài liệu là 2.000 tên miền mỗi lần gọi.
domains=
Một tham số GET ở đây. Điểm cuối cũng chấp nhận một POST body, đây là lựa chọn tốt hơn khi danh sách dài. Hãy kiểm tra bộ phân cách với hai tên miền trước khi chạy toàn bộ.
BATCH = 200
Thói quen của chúng tôi, không phải giới hạn: 200 tên miền ngắn giữ cho URL nằm dưới các giới hạn proxy thông thường.
_credits
Có trong các phản hồi đã xác thực: chi phí của lần gọi và số dư còn lại. In nó mỗi batch là chuỗi kiểm toán rẻ nhất.
Cột body thô
Bạn sẽ phân tích sau, một lần, dựa trên một mẫu đã lưu. Một thay đổi lược đồ từ phía chúng tôi khi đó chỉ tốn một truy vấn, không phải chạy lại toàn bộ.

Một lần chạy giả định, với các phép tính
Đây là một ví dụ, không phải câu chuyện của khách hàng. Hãy tưởng tượng một agency theo dõi 1.800 tên miền khách hàng và tiềm năng trong Google Sheet và muốn làm mới DR vào mỗi thứ Hai.
Ở mức 200 tên miền mỗi batch, đó là 9 yêu cầu. Chín yêu cầu với 1 credit mỗi lần là 9 credits, hay $0.0009 cho mỗi lần chạy, và qua 52 thứ Hai, tổng cộng là 468 credits, quy ra dưới năm xu.
Chi phí không phải là ràng buộc. Độ tươi mới mới là vấn đề. Chỉ mục được xây dựng lại khoảng hàng tháng, vì vậy các lần chạy hàng tuần sẽ hiển thị cùng giá trị ba trong bốn tuần, và một lần chạy hàng tháng nắm bắt được cùng sự biến động với khoảng một phần tư số lần gọi.
Vì vậy, hãy chạy nó hàng tháng và giữ bảng tính hàng tuần cho các chỉnh sửa của con người. Chi tiết về lý do điểm số có thể đứng yên có trong tham chiếu DR.
Những sự cố có thể xảy ra với kịch bản này
| Triệu chứng | Nguyên nhân | Cách khắc phục |
|---|---|---|
SystemExit: HTTP 402 | Số dư bằng không | Nạp tiền từ trang tài khoản, chạy lại; các batch đã hoàn thành đã có trong SQLite |
SystemExit: HTTP 401 | Biến môi trường trống hoặc lỗi chính tả khóa | In len(KEY) và kiểm tra tiền tố sk_ |
ok=false ở batch 3 | Giá trị không hợp lệ trong danh sách, chẳng hạn như URL đầy đủ | Xóa lược đồ và đường dẫn trước khi gửi, xem bảng lỗi |
| Cùng DR với tuần trước | Chỉ mục chưa được xây dựng lại | Đã dự kiến; so sánh hàng tháng |
| URL dài bị từ chối | Batch quá lớn đối với GET | Giảm BATCH hoặc chuyển sang POST body |
Kích thước batch, GET và POST cho danh sách dài
Giới hạn là 2.000 tên miền mỗi lần gọi, và kịch bản gửi một phần mười con số đó. Mỗi lần gọi có cùng chi phí credit cố định, vì vậy kích thước batch là vấn đề về lỗi và tải trọng, không phải giá cả.
Tại sao là 200 chứ không phải 2.000
Một batch nhỏ hơn sẽ thất bại với chi phí thấp. Nếu một lần chạy dừng giữa chừng, phần đuôi còn lại để chạy lại chỉ dài bằng một batch, không phải cả danh sách.
Các danh sách ngắn hơn cũng giữ cho mỗi body được lưu nhỏ enough để quét bằng mắt khi một con số có vẻ sai, và điều đó quan trọng hơn một vài lần gọi được lưu.
Nếu sau này bạn tăng kích thước batch, hãy làm một lần, trong một hằng số duy nhất, và chạy lại bài kiểm tra hai tên miền. Một con số lớn hơn không phải là lý do để bỏ qua bài kiểm tra.
Lên kế hoạch batch dựa trên độ dài lần chạy mà bạn có thể chịu đựng, không phải dựa trên giới hạn. Một job chạy hàng đêm phải hoàn thành trước báo cáo buổi sáng có thể chấp nhận các batch nhỏ hơn, an toàn hơn so với việc lấp đầy dữ liệu một lần.
GET cho danh sách ngắn, POST cho danh sách dài
Dạng GET đặt mọi tên miền vào URL. Điều đó hoạt động cho đến khi một proxy hoặc một dòng nhật ký cắt ngắn truy vấn, đó là lý do bảng trên nói giảm batch trước. Khi danh sách phát triển, hãy gửi cùng giá trị domains trong một POST body.
Hãy kiểm tra bộ phân cách và mã hóa với hai tên miền trước khi chạy toàn bộ. Một dấu phẩy lạc xuất hiện ở batch đầu tiên, và việc thấy nó ở đó sẽ rẻ hơn.
Một POST body cũng giữ danh sách khỏi các nhật ký truy cập mà nhiều máy chủ lưu theo mặc định. Đó là một lợi ích nhỏ về quyền riêng tư cho danh sách khách hàng, và nó tốn một dòng tiêu đề bổ sung trong kịch bản.
Khi chuyển sang POST, hãy giữ phiên bản GET của kịch bản làm dự phòng cho các danh sách ngắn. Hai đường dẫn mã nghe có vẻ nặng nề, nhưng một hàm nhỏ chọn một trong hai theo độ dài rất dễ đọc và dễ kiểm tra.
Cắt và loại bỏ trùng lặp trước yêu cầu đầu tiên
Xóa khoảng trắng, chuyển đổi tên miền thành chữ thường và loại bỏ các bản sao trước khi bất kỳ dữ liệu nào rời khỏi máy của bạn. Các bản sao chiếm dung lượng dưới giới hạn 2.000 tên miền, và chúng khiến số lượng trong bảng tính của bạn không khớp với số lượng trong phản hồi.
Chọn một quy tắc cho www. và áp dụng nó trong một hàm duy nhất, để cùng một trang web không bao giờ được tra cứu dưới hai cách viết. Bất kỳ công cụ kiểm tra miền backlink nào mở rộng quy mô vượt quá vài trăm tên miền đều cần sự kỷ luật đó.
Nhật ký lần chạy nên ghi gì
In giá trị _credits sau mỗi batch, và ghi số batch, số lượng tên miền và thời gian bên cạnh nó. Ba con số đó trả lời hầu hết mọi câu hỏi mà một độc giả tài chính sẽ đặt ra về một lần chạy.
Một lần chạy không in gì cho đến khi kết thúc sẽ không cho bạn manh mối khi nó bị treo. Một dòng mỗi batch rất rẻ, và nó biến một lần treo im lặng thành một số batch bạn có thể đặt tên.
Giữ nhật ký trong cùng thư mục với tệp SQLite, để một bản sao lưu sao chép cả hai. Một nhật ký sống ở nơi khác là thứ sẽ bị mất trong sự cố.

Ba tiện ích mở rộng đáng dành cả buổi chiều
Lưu số batch bên cạnh dấu thời gian. Nó đã có trong bảng trên, và nó cho phép bạn chạy lại chỉ batch bị lỗi sau một lỗi 402 giữa chừng.
Viết một truy vấn nhỏ trên bảng thô một khi bạn đã kiểm tra một phản hồi thực tế: tên miền, điểm, thời gian lấy. Các bảng điều khiển đọc truy vấn, và cột thô vẫn là bằng chứng của bạn nếu một con số bị chất vấn.
Chạy nó từ GitHub Actions hoặc cron thông thường trên một VPS nhỏ. Cái nào cũng được. Điều quan trọng là job phải thoát với mã khác không khi có bất kỳ lỗi nào, vì một lỗi im lặng trông giống như một biểu đồ lỗi thời sau ba tuần.
Sắp xếp đầu ra là vấn đề của giao diện người dùng. Xếp hạng danh mục đầu tư theo điểm số, phân loại nó, hoặc so sánh nó với dr_distribution (1 credit) để xem vị trí của từng khách hàng trong số tất cả 181.132.097 tên miền.
Sự trôi trường và bảng thô
Một job chạy dài thất bại im lặng khi một trường thay đổi hình dạng. Cột thô có đó để thất bại vẫn rõ ràng và dễ sửa.
Lưu body thô trước
Cột thô là lưới an toàn. Nếu một trường được đổi tên hoặc một trường mới xuất hiện, bạn chạy lại một truy vấn trên các phản hồi đã lưu thay vì trả tiền cho toàn bộ danh sách một lần nữa. Phân tích sau đó rất rẻ, trong khi mua lại thì không.
Giữ một mẫu đã lưu mỗi tuần trong một tệp riêng biệt. Khi việc phân tích bị hỏng, bạn so sánh mẫu của tuần này với mẫu hoạt động gần nhất.
Ghi body chính xác như khi nhận được, không định dạng đẹp và không cắt xén. Bất kỳ thay đổi nào bạn thực hiện đối với văn bản trước khi lưu nó là một thay đổi bạn không thể hoàn tác sau này.
Sự trôi trông như thế nào trong thực tế
Giả sử một bảng điều khiển đột nhiên hiển thị các điểm số trống cho một batch. Hàng thô vẫn còn đó. Bạn mở nó, so sánh các khóa của nó với mẫu của tuần trước, và tìm ra sự khác biệt trong vài phút.
Cách khắc phục sau đó là một dòng duy nhất trong truy vấn, không phải chạy lại toàn bộ danh sách. Đó là toàn bộ điểm của việc lưu body.
Giữ một ghi chú ngắn bên cạnh truy vấn nói rõ trường nào nó đọc và khi nào bạn kiểm tra nó lần cuối với một phản hồi thực tế. Ghi chú mất một phút để viết và tiết kiệm một lần tìm kiếm dài sau này.
Sắp xếp các bản di chuyển với dữ liệu
Tạo bảng thô trước truy vấn, và truy vấn trước bất kỳ truy vấn bảng điều khiển nào. Giữ các câu lệnh tạo trong một tệp, chạy chúng theo thứ tự và ghi lại số batch với mỗi hàng.
Cơ sở dữ liệu riêng biệt cho từng khách hàng trôi đi theo cách giống như một cơ sở dữ liệu dùng chung. Quy tắc vẫn giống nhau: một body được lưu mỗi lần gọi, và một nơi để phân tích nó.
Giữ trình phân tích gần các bài kiểm tra
Đặt hàm phân tích trong cùng kho lưu trữ với một bài kiểm tra đọc một body đã lưu. Bài kiểm tra là nơi một trường bị trôi đầu tiên xuất hiện, lâu trước khi một biểu đồ làm vậy.
Đặt tên các trường mà trình phân tích mong đợi trong một hằng số gần đầu tệp. Một người xem sau đó có thể thấy mọi phụ thuộc vào hình dạng phản hồi trong một màn hình.
Lần chạy đầu tiên, theo thứ tự
- 1
Kiểm tra một tên miền
Gọi
bulk_drvới một tên miền đơn lẻ bạn biết, và đọc toàn bộ phản hồi. Ghi lại các khóa trước khi bạn viết bất kỳ mã phân tích nào. - 2
Chạy hai batch
Cung cấp cho kịch bản một danh sách 400 tên miền, để chính xác hai batch chạy. Kiểm tra xem sự giảm
_creditscó khớp với hai lần gọi với một credit mỗi lần không. - 3
Đếm các hàng đã lưu
Mở tệp SQLite và so sánh số hàng với số batch. Một sự không khớp có nghĩa là một batch đã bị bỏ qua hoặc được lưu hai lần, và bạn tìm ra điều đó trước khi bảng điều khiển làm vậy.
- 4
Lên lịch cho danh sách đầy đủ
Chỉ sau khi các lần chạy thử nghiệm sạch, hãy thêm danh sách đầy đủ và bộ lên lịch. Giữ mã thoát khác không, để một lỗi trở nên rõ ràng vào đêm đầu tiên.
Trước khi lên lịch nó
- Loại bỏ trùng lặp và chuyển đổi chữ thường danh sách trước
- Quyết định một lần, trong một hàm, xem
www.có giữ lại hay không - Giữ khóa trong kho bí mật, không phải trong crontab
- Cảnh báo về mã thoát khác không
- Chạy các con số ngân sách credit cho khối lượng của riêng bạn