How to Do Bulk Domain Analysis in Python – Moz

Checking one domain in an SEO tool is easy. Checking 500 domains is where the innocent-looking spreadsheet begins plotting against you.

Bulk domain analysis solves that problem by turning a repetitive browser task into a reproducible Python workflow. Instead of copying Domain Authority scores one row at a time, you can send groups of domains to the Moz Links API, collect link metrics, handle temporary errors, and export a clean CSV file for reporting or further analysis.

This tutorial walks through a production-friendly approach rather than a five-line script that works beautifully until domain number 37 throws a timeout and sends the entire project into emotional bankruptcy.

What Is Bulk Domain Analysis?

Bulk domain analysis is the process of evaluating many websites in a single workflow. The domains might be competitors, outreach prospects, expired-domain candidates, affiliate partners, publishers, customers, or sites discovered during backlink research.

A useful bulk report may include:

  • Domain Authority
  • Page Authority
  • Spam Score
  • Linking root domains
  • Inbound-link counts
  • Nofollow percentages
  • Redirect or canonical information
  • Processing status and error details

Moz provides a version 2 URL Metrics endpoint at https://lsapi.seomoz.com/v2/url_metrics. A request is sent with HTTP Basic authentication and a JSON payload containing a targets array. The response contains a results collection with metrics for the submitted targets. Moz also exposes endpoints for linking root domains, anchor text, top pages, link intersections, redirects, and account usage data.

Why Use Python for Moz Domain Analysis?

Python is particularly comfortable around APIs, CSV files, and repetitive jobs. That makes it a natural fit for an SEO workflow in which the basic recipe is “read rows, send requests, organize JSON, write rows.”

More importantly, Python allows you to make the process dependable. A reusable script can normalize domains, remove duplicates, protect credentials, retry temporary failures, preserve failed rows, and produce the same output structure every time.

This consistency matters when domain analysis becomes part of a recurring process. An agency may refresh prospect scores every month. An acquisition team may screen thousands of potential properties. A digital PR team may compare publisher quality before launching outreach. Manual checking becomes impractical surprisingly quicklyusually around the same moment somebody says, “It is only a few hundred domains.”

Understanding the Moz Metrics

Domain Authority

Domain Authority, commonly abbreviated as DA, is a Moz score designed for comparing the relative ranking strength of domains. It is most useful when domains are evaluated against relevant competitors or peers.

A DA of 45 is not automatically “good,” just as being six feet tall does not automatically make someone an NBA center. Context matters. A score of 45 may be strong in a specialized local market and ordinary in a national finance niche.

Page Authority

Page Authority applies the same general idea at the individual-page level. When your target is a homepage, PA can help describe that specific URL. When analyzing a complete website, however, one page should not be treated as a perfect summary of every page on the domain.

Spam Score

Spam Score is a screening signal, not a courtroom verdict. A higher value deserves investigation, but it should be reviewed alongside topical relevance, traffic patterns, link quality, ownership, editorial standards, and the actual pages producing links.

Linking Root Domains

Linking root domains often provide more context than raw backlink totals. Ten thousand links from one site and ten thousand links from two thousand independent sites describe very different link profiles.

The strongest reports therefore avoid ranking domains by one metric alone. DA may be the headline number, but the supporting cast often tells the more interesting story.

Prepare the Python Project

Create the Input CSV

Create a file named domains.csv with a column called domain:

The script below accepts both plain domains and full URLs. It reduces them to hostnames, removes a leading www., converts uppercase characters to lowercase, and discards paths or query strings.

Python’s urllib.parse module can split URLs into their major components. However, URL parsing alone does not determine the registrable root domain for every suffix. Domains such as example.co.uk demonstrate why production systems sometimes incorporate the Public Suffix List or a library built around it.

Install the Dependencies

Pandas handles the tabular input and output, while Requests manages HTTP communication. Pandas provides dedicated functions for reading CSV data and exporting DataFrames back to CSV, including options for data types, encoding, chunking, and missing values.

Store Moz Credentials Safely

Do not paste an Access ID or Secret Key directly into a script that may be uploaded to GitHub, emailed to a coworker, or included in a tutorial. Store credentials in environment variables instead:

Hardcoded API credentials are easy to leak through repositories, logs, screenshots, configuration archives, and copied code. Centralized secret storage, rotation, restricted access, and auditing are safer practices for any workflow that may become part of a business system.

Complete Python Script for Bulk Moz Analysis

The following script reads the CSV file, normalizes and deduplicates the domains, sends them to the Moz URL Metrics endpoint in configurable batches, retries selected transient failures, and writes the results to moz_domain_analysis.csv.

How the Script Works

1. It Cleans the Domain List

The normalization function accepts values such as example.com, https://example.com/about, and WWW.EXAMPLE.COM. They all become example.com.

This prevents duplicate API usage caused by superficial formatting differences. It also catches blank or malformed values before they are mixed into a network request.

2. It Sends Domains in Batches

The Moz URL Metrics endpoint accepts multiple targets in one JSON body. Batching reduces HTTP overhead and generally produces a cleaner workflow than firing one request per domain.

The sample batch size is configurable because API capabilities and subscription limits can change. Check the current Moz documentation and your account limits rather than assuming that a number copied from an old blog post remains permanent.

3. It Uses Timeouts

Requests does not apply a timeout unless one is supplied. Without one, an application may wait indefinitely for an unresponsive connection. The example uses separate connection and read timeouts with timeout=(10, 60).

4. It Retries Temporary Failures

The session retries selected rate-limit and server-error responses with progressively longer delays. Immediate, aggressive retries can worsen an overloaded service, while exponential backoff gives the remote API time to recover. Adding randomized jitter is an additional improvement for systems running many workers or scheduled jobs simultaneously.

The code explicitly permits retries for the URL Metrics POST request because the operation retrieves data rather than changing a remote resource. Do not blindly copy that setting to POST endpoints that create orders, publish content, charge cards, or perform other non-idempotent actions.

5. It Keeps Failed Rows

A weak bulk script disappears at the first error. A useful one produces an auditable report.

This implementation writes failures into the output with a status, optional HTTP code, and error message. You can therefore filter the CSV for failed domains and retry only those records instead of repeating the entire run.

How to Interpret the Output

Once the CSV has been created, avoid sorting by DA and calling the job complete. Build decision rules around several dimensions.

For Link Outreach

Start with topical relevance, editorial quality, real audience signals, and evidence that pages are maintained. Use Domain Authority, Spam Score, and linking-domain counts as supporting filters.

For Competitor Research

Compare domains within the same market. Add columns for estimated organic traffic, ranking keywords, content categories, and your relationship to each competitor. Authority differences become more meaningful when paired with business context.

For Expired-Domain Screening

Do not purchase a domain because one score looks attractive. Review link destinations, anchor text, historical content, trademarks, indexing status, redirects, language changes, and obvious manipulation. A domain can wear a respectable metric like a rented tuxedo.

For Digital PR

Segment publishers by niche, geography, audience type, authority range, and Spam Score. This creates better outreach lists than one giant worksheet sorted from “very famous” to “probably somebody’s abandoned coupon blog.”

Scaling Beyond a Few Thousand Domains

For larger projects, separate the workflow into stages: ingestion, normalization, API collection, storage, scoring, and reporting. Save raw API responses before transforming them so that the original data remains available when reporting rules change.

A local SQLite database is often enough for a small agency workflow. PostgreSQL, BigQuery, Snowflake, or another managed analytical store may be more appropriate when several users, scheduled refreshes, or millions of records are involved.

Also consider caching results. Authority and link metrics do not need to be fetched repeatedly during every test run. A cache keyed by normalized domain and collection date can reduce cost, shorten processing time, and prevent accidental duplication.

Python’s ThreadPoolExecutor can run I/O-bound calls concurrently, but concurrency should be added only after batching, retries, caching, and account limits are understood. More threads do not magically create more API capacity; sometimes they merely allow you to receive rate-limit errors with impressive efficiency.

Experience Notes from Realistic Bulk-Analysis Workflows

One of the first lessons teams learn is that input quality determines output quality. Domain lists collected from exports, scraped pages, customer records, and old spreadsheets rarely arrive in one consistent format. Some rows include protocols, some include paths, some contain email addresses, and others contain cheerful surprises such as “N/A,” “pending,” or a note written by Kevin in 2022. Normalization is not glamorous, but it prevents wasted API rows and confusing duplicates.

A second lesson is that the fastest-looking design is not always the fastest completed workflow. Sending hundreds of simultaneous requests may appear efficient during a tiny test, but production runs introduce rate limits, dropped connections, retries, and partial responses. Controlled batches with modest pauses are often easier to debug and may finish sooner because they avoid long recovery cycles. Reliability beats theatrical speed.

Another recurring issue is failing to preserve the relationship between requests and responses. A script may send 25 domains and receive 25 results, but later transformations can reorder rows or drop missing values. Always retain the original normalized domain as a dedicated field. Never assume that a returned page name, redirect target, or canonical value will be identical to the submitted string.

Teams also discover that stakeholders love a single score. A clean DA column is easy to sort, color, and paste into a presentation. Unfortunately, it is equally easy to misuse. A domain with moderate authority, strong relevance, genuine readership, and careful editorial review may be more valuable than a high-authority site with unrelated content or questionable publishing practices. The practical solution is a weighted scoring model that combines authority with relevance, risk, traffic, and human review.

Caching is another lesson usually learned immediately after somebody reruns the same 8,000-domain file by accident. Store the retrieval date and raw response. Then define a freshness period appropriate to the project. A weekly outreach process may tolerate older values, while a due-diligence review may require a new pull. The ideal refresh schedule depends on the decision being made, not on the fact that an API can technically be called again.

Finally, successful workflows treat errors as data. A timeout, invalid domain, authentication failure, or quota response should not vanish into a terminal window. It should become a structured row that can be filtered, counted, and retried. This approach turns a brittle script into an operational tool. The difference is rarely a clever algorithm; it is usually careful bookkeeping, informative logs, and the humility to assume that the internet will occasionally behave like the internet.

Conclusion

Bulk domain analysis in Python turns Moz metrics into a repeatable research pipeline. The essential workflow is straightforward: clean the input, protect the credentials, submit normalized targets in batches, handle transient failures, retain unsuccessful rows, and export structured results.

The real value appears after collection. Domain Authority, Page Authority, Spam Score, and link counts should support an SEO decision rather than replace one. Combine them with relevance, content quality, traffic, historical checks, and manual review to create a report that is useful instead of merely colorful.

Note: Moz endpoints, available fields, authentication requirements, batch capabilities, pricing, and usage limits may change. Verify the current Moz Links API documentation and your subscription before running a large production job.