# Metacpan Perl Modules Scraper (`b2b_lead_generation/metacpan-perl-modules-scraper`) Actor

Search MetaCPAN for Perl modules, latest releases, and PAUSE author profiles. Easily extract clean data and export results as JSON, CSV, or Excel datasets.

- **URL**: https://apify.com/b2b_lead_generation/metacpan-perl-modules-scraper.md
- **Developed by:** [B2B Lead Generation](https://apify.com/b2b_lead_generation) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 results

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

## MetaCPAN Perl Modules Scraper: Perl modules search

MetaCPAN Perl Modules Scraper searches for Perl modules, latest distribution releases, and PAUSE author profiles. Results land in an Apify dataset you can export as JSON, CSV, or Excel.

A run stops at your item cap, waits between requests, and writes an error row when one entry fails so the rest of the list finishes smoothly.

### Use cases

- **Perl module catalogs**: search CPAN releases with a Lucene query and keep the rows organized in a spreadsheet.
- **Dependency review**: pull the latest Moose-style distribution record, license, and download link before an upgrade.
- **Author watch**: collect a PAUSE profile and direct page links quickly.
- **Archive checks**: export older backpan releases next to current latest rows.
- **Scheduled exports**: rerun the same query on a routine basis and drop the dataset into Sheets or a data warehouse.
- **No-fuss research**: grab Perl module metadata effortlessly.

### Input

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `mode` | string | `search` | Release search, latest release, or author. |
| `query` | string | `name:Moose*` | Lucene query used in release search. |
| `distributions` | array | `Moose` | Distribution names for latest-release mode. |
| `authors` | array | `ETHER` | PAUSE IDs for author mode. |
| `maxItems` | integer | `100` | Stop after this many rows. Hard max 1000. |
| `requestDelaySecs` | number | `1` | Pause between requests. |
| `userAgent` | string | \`\` | Contact string sent on every request. |
| `timeoutSecs` | integer | `300` | Whole-run time limit in seconds. |
| `requestTimeoutSecs` | integer | `30` | Per-request time limit in seconds. |
| `proxyConfiguration` | object | No proxy | Optional proxy settings. Default is `{"useApifyProxy": false}`. |

#### Example input

```json
{
    "mode": "search",
    "query": "name:Moose*",
    "maxItems": 100,
    "requestDelaySecs": 1,
    "timeoutSecs": 300,
    "requestTimeoutSecs": 30,
    "proxyConfiguration": { "useApifyProxy": false }
}

```

Latest release mode uses `distributions` such as `["Moose"]`. Author mode uses `authors` such as `["ETHER"]`.

### What data does this actor extract?

Each success row is one release, or one author record when that mode is selected.

```json
{
    "name": "Moose-0.45",
    "distribution": "Moose",
    "version": "0.45",
    "abstract": "A postmodern object system for Perl 5",
    "author": "STEVAN",
    "date": "2008-05-25T04:35:10",
    "license": ["perl_5"],
    "status": "backpan",
    "download_url": "[https://cpan.metacpan.org/authors/id/S/ST/STEVAN/Moose-0.45.tar.gz](https://cpan.metacpan.org/authors/id/S/ST/STEVAN/Moose-0.45.tar.gz)",
    "url": "[https://metacpan.org/release/STEVAN/Moose-0.45](https://metacpan.org/release/STEVAN/Moose-0.45)",
    "scraped_at": "2026-10-12T00:00:00+00:00",
    "error": "",
    "message": ""
}

```

| Field | Type | Description |
| --- | --- | --- |
| `name` | string | Release name, or the person name on an author row. |
| `distribution` | string | Distribution name. |
| `version` | string | Version string. |
| `abstract` | string | Short summary text. |
| `author` | string | PAUSE ID. |
| `date` | string | Release date, or author record update time. |
| `license` | array | License identifiers such as `perl_5`. |
| `status` | string | `latest`, `cpan`, or `backpan` on a release. HTTP status code on an error row. |
| `download_url` | string | Archive package download link. |
| `url` | string | Public release or author page. |
| `scraped_at` | string | UTC timestamp when the row was saved. |
| `error` | string | Failure description. Empty when successful. |
| `message` | string | Detailed failure message for filtering. |

A missing distribution or PAUSE ID will not halt your run. The tool saves an error row containing `url`, `status`, and `message`, then smoothly continues with the remaining items. Duplicate release or author IDs inside a single run are automatically deduplicated.

### How it works

1. Reads your input settings, verifies the selected mode, and prepares the queue.
2. Sends clean, properly identified web requests with custom user-agent headers.
3. Pages through release results until reaching page limits, hit totals, or your specified `maxItems`.
4. Maps records into dataset fields, skips duplicates, and saves rows in organized batches of 50.
5. Logs error entries for broken links without breaking the entire run, providing clear summaries at completion.

### FAQ

**How many Perl modules can one run export?**
`maxItems` defaults to 100 and holds a upper limit of 1000 per single run. You can raise the cap or schedule additional runs to grab remaining chunks of larger queries.

**What happens if a distribution or PAUSE ID is wrong?**
If a target is not found, the actor records a clear error row with details and continues processing the rest of your list.

**Can I export CSV?**
Yes, once your dataset finishes, you can export your findings directly as JSON, CSV, or Excel.

**Does the actor use a proxy?**
Not by default. `proxyConfiguration` is entirely optional and defaults to `{"useApifyProxy": false}`.

#### Trademark Notice

MetaCPAN Perl Modules and related names, logos, and trademarks belong to their respective owners. Their use in this documentation is solely to identify the data context and does not imply affiliation, sponsorship, endorsement, or partnership.

#### Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, sponsored by, or otherwise officially associated with MetaCPAN Perl Modules or its owners. All data is gathered from publicly accessible sources. Users are responsible for complying with terms of use, rate limits, and attribution requirements.

#### Is web scraping legal?

This Actor only collects publicly available data without bypassing access controls. Scraping public data is generally legal, but how you use it matters:

- **Personal data:** If results include personal data (such as names, emails, or profile details), laws such as GDPR in the EU and CCPA in California may apply. Only collect and store personal data when you have a legitimate business reason.
- **Copyright:** Certain content (articles, descriptions) may be protected by copyright. Do not republish full copyrighted materials without permission.
- **Terms of use:** Respect stated rate limits, community guidelines, and attribution requirements listed in the documentation.
- **Legal advice:** This general overview is provided for context, not formal legal advice. If you have specific compliance questions, consult legal counsel.

To learn more, check out Apify's guide: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

# Actor input Schema

## `mode` (type: `string`):

Choose release search, the latest release of a distribution, or a PAUSE author profile.

## `query` (type: `string`):

Lucene query for release search. A status:latest clause keeps the result on current uploads.

## `distributions` (type: `array`):

Distribution names for latest-release mode, one per line. Example: Moose.

## `authors` (type: `array`):

PAUSE IDs for author mode, one per line. Example: ETHER.

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

Maximum records to save in one run. Hard cap is 1000.

## `requestDelaySecs` (type: `number`):

Seconds to wait between MetaCPAN requests. Default is 1 so runs stay polite.

## `userAgent` (type: `string`):

Identify your app with a contact address. MetaCPAN rejects an empty user agent.

## `timeoutSecs` (type: `integer`):

Maximum time the whole run may take, in seconds.

## `requestTimeoutSecs` (type: `integer`):

Maximum time to wait for a single MetaCPAN response, in seconds.

## `proxyConfiguration` (type: `object`):

Optional proxy for MetaCPAN requests. Leave useApifyProxy false unless the source blocks your IP.

## Actor input object example

```json
{
  "mode": "search",
  "query": "name:Moose*",
  "distributions": [
    "Moose"
  ],
  "authors": [
    "ETHER"
  ],
  "maxItems": 100,
  "requestDelaySecs": 1,
  "userAgent": "b2bleadgeneration@gmail.com",
  "timeoutSecs": 300,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Table view of the scraped Perl modules.

## `datasetItems` (type: `string`):

All dataset items.

# 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 = {
    "query": "name:Moose*",
    "distributions": [
        "Moose"
    ],
    "authors": [
        "ETHER"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_lead_generation/metacpan-perl-modules-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 = {
    "query": "name:Moose*",
    "distributions": ["Moose"],
    "authors": ["ETHER"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_lead_generation/metacpan-perl-modules-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 '{
  "query": "name:Moose*",
  "distributions": [
    "Moose"
  ],
  "authors": [
    "ETHER"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call b2b_lead_generation/metacpan-perl-modules-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_lead_generation/metacpan-perl-modules-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/iYCO6Zbzf8oBdDIRk/builds/tUiW6vG7cIg1LdG45/openapi.json
