# Capterra Category Scraper — Ranked Software Lists (`thenetaji/capterra-category-scraper`) Actor

Export a software category in Capterra's ranked order, with every product's name, rank, rating, review count, one-line summary and Shortlist flag. Each row carries the two-part page address the other Actors take, which cannot be guessed from a product's name.

- **URL**: https://apify.com/thenetaji/capterra-category-scraper.md
- **Developed by:** [The Netaji](https://apify.com/thenetaji) (community)
- **Categories:** Business, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 product listeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Capterra Category Scraper

A software category's ranked listing, exported as a spreadsheet of products. Each row carries
the product's rank across the whole category, its name, its aggregate rating and review count,
the one-line summary from its listing card, and whether Capterra puts it on the category's own
Shortlist.

It also carries the product's page address — and on this site that is the part worth staying
for. A Capterra product is addressed by a number *and* a name, `/p/147657/monday-com/`, and
neither half can be worked out from the other or from the product's own title: Capterra spells
them `monday-com`, `GitLab`, `Structure`, `Asana-PM`. The numbers rot, too. So a category walk
is not one way to find products here, it is the way — every other Actor in this family needs an
address this one produces.

### Accepted input

`categorySlugs` is required and takes one or more category slugs, one per line, such as
`project-management-software`. The `-software` suffix is part of the slug, so
`project-management` is a different value and not a valid one. A pasted category page link
works too and is reduced to the slug inside it. A bare value with a query string on the end is
refused rather than trimmed, because `project-management-software?page=2` quietly reduced to
the plain slug would serve page 1 to somebody who asked for page 2 — the page is a field of its
own.

`maxItems` bounds each category separately and defaults to `100`. The cap is per category
rather than per run because a run given five categories is asking for a comparable slice of
each; a single shared cap would return the first category and nothing else. Set `0` to walk a
category to the end.

`startPage` sets the page each category begins at and defaults to `1`. It resumes a walk that
stopped and splits a large category across several runs.

```json
{
  "categorySlugs": ["project-management-software"],
  "maxItems": 25,
  "startPage": 1
}
```

### Response fields

One row per product. This is the first row of that exact run:

```json
{
  "category_slug": "project-management-software",
  "category_name": "Best Project Management",
  "category_url": "https://www.capterra.com/project-management-software/",
  "page": 1,
  "total_products": 1227,
  "page_limit": 26,
  "position": 1,
  "name": "monday.com AI Work Platform",
  "product_id": "147657",
  "slug": "monday-com",
  "url": "https://www.capterra.com/p/147657/monday-com/",
  "summary": "monday.com centralizes work, and automates tasks, allowing teams to manage the entire project lifecycle in one place.",
  "shortlisted": true,
  "rating": 4.6,
  "rating_best": 5,
  "review_count": 6095
}
```

Fields absent from a listing card are returned as null rather than omitted, so every row has
the same shape.

`url` is the key. Paste it into
[Capterra Profile Scraper](https://apify.com/thenetaji/capterra-profile-scraper) or
[Capterra Reviews Scraper](https://apify.com/thenetaji/capterra-reviews-scraper) and both
halves of the address are read off it; `product_id` and `slug` are the same two halves as
separate columns for anything that would rather join on them. The name half is **case
sensitive** — `GitLab` is not `gitlab` — which is why it is published rather than left to be
typed.

`position` is the rank across the whole category rather than within its page. Page 2 of the
category above opened at 26 and ran to 75.

`total_products` and `page_limit` disagree, and they are meant to. The category above states
1,227 products while its own pagination stops at page 26. `page_limit` is the number the walk
follows; `total_products` is Capterra's count of the taxonomy behind the listing, and treating
it as a walk target means asking for pages that were never there.

### Behaviour on partial results

A category slug Capterra serves nothing for is logged and skipped, and the run continues with
the next one. A category that exists and lists no products returns a successful run with no
rows for it.

The walk ends on Capterra's own pagination rather than on a short page, and on this listing
that distinction is not academic. Measured on 2026-08-23: page 1 of
`project-management-software` returned **25** products at positions 1–25, and pages 2 and 3
returned **fifty each**, at 26–75 and 76–125, with no product appearing twice — while the
response called its own page size 25 on all three. A page of 25 is therefore neither full nor
short, it is simply what page 1 looks like, and a walk that stopped on "fewer than a full page"
would end every category after its first one.

### Frequently asked questions

**Why do some runs take half a minute for the first page and two seconds for the next?**
Because a page Capterra is already holding answers immediately and a page that has to be
fetched fresh does not. Across eight live calls on 2026-08-23 the same category endpoint
answered in 33.6s, 33.1s and 2.8s. A run that appears to sit still for half a minute before its
first row is behaving normally.

**Why did a page fail and then work?**
Capterra sometimes refuses a request outright and states how long to wait. Two of those eight
calls came back that way. The wait is honoured and the page is asked for again; the run reports
it and carries on rather than failing.

**How many products does a category hold?**
As many as `page_limit` pages hold, which is fewer than `total_products` claims. Set `maxItems`
to `0` to find out for a given category — it walks to the last page Capterra paginates to and
stops.

**Can I get a product's reviews from here?**
No, and no category row carries any review text. Take `url` to
[Capterra Reviews Scraper](https://apify.com/thenetaji/capterra-reviews-scraper), which reads
25 reviews a page with the pros and cons kept as separate answers.

**Can I search Capterra by product name instead?**
Not through this Actor, and not usefully by hand either — the name half of a product's address
is Capterra's spelling rather than the product's, so a guessed address is an address that does
not exist. A category listing is the discovery surface, and the run log names the category and
its pagination limit as it starts.

**Is a Capterra account, cookie or API key required?**
No. No account, session cookie or key of any kind is supplied to the Actor or needed by it.

### Related Actors

[Capterra Profile Scraper](https://apify.com/thenetaji/capterra-profile-scraper) reads the
vendor's full description, the supported platforms and the product Q\&A from any `url` here.

[Capterra Reviews Scraper](https://apify.com/thenetaji/capterra-reviews-scraper) reads any
product's reviews from the same `url`, with pros and cons apart and the reviewer's job title,
industry and length of use on every row.

# Actor input Schema

## `categorySlugs` (type: `array`):

Capterra category slugs, one per line — for example project-management-software. The `-software` suffix is part of the slug, so `project-management` is not the same value. A pasted category page link works too and is reduced to the slug inside it.

## `startPage` (type: `integer`):

Which page each item in the list starts from. It resumes a walk that stopped, and it splits a long product or category across several runs.

## `maxItems` (type: `integer`):

Maximum products to save for each category in the list. Set 0 for no limit. A page returns at least 25 products and has been measured returning fifty, so a run asks for as many pages as it takes to reach this number.

## Actor input object example

```json
{
  "categorySlugs": [
    "project-management-software"
  ],
  "startPage": 1,
  "maxItems": 25
}
```

# Actor output Schema

## `dataset` (type: `string`):

All records scraped by this run

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categorySlugs": [
        "project-management-software"
    ],
    "startPage": 1,
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("thenetaji/capterra-category-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categorySlugs": ["project-management-software"],
    "startPage": 1,
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("thenetaji/capterra-category-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categorySlugs": [
    "project-management-software"
  ],
  "startPage": 1,
  "maxItems": 25
}' |
apify call thenetaji/capterra-category-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thenetaji/capterra-category-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/mS5Qooqo94x9xUF31/builds/12tBnvB9X2oSBo8PY/openapi.json
