# Freelance Gigs Scraper with Competition Score (`woundless_yellowwood/freelance-gigs-scraper`) Actor

Scrape Freelancer.com (free plan) and Upwork (paid plan + residential proxy required) job listings with a 1-10 competition score. Get proposal counts, bid ranges, client quality signals, budget and skills. Filter by max proposals and min budget.

- **URL**: https://apify.com/woundless\_yellowwood/freelance-gigs-scraper.md
- **Developed by:** [Perria](https://apify.com/woundless_yellowwood) (community)
- **Categories:** Lead generation, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

### Freelance Gigs Scraper - Find Low-Competition Jobs on Freelancer.com & Upwork

Stop wasting hours scrolling through overcrowded job boards. This scraper extracts active freelance job listings from Freelancer.com and Upwork, then scores every single gig on a **1-10 competition scale** so you know exactly which jobs are worth your time.

#### The Competition Score - How It Works

Every scraped gig gets a smart score from 1 (easy win) to 10 (nearly impossible) based on:
- **Proposal count** - fewer proposals = less competition
- **Budget size** - higher budgets often mean more serious clients
- **Client quality signals** - verified payment, hire rate, review history
- **Bid range analysis** - wide bid ranges suggest unclear requirements (your chance to stand out)

#### What You Get Per Gig

| Field | Description |
|-------|-------------|
| Job Title | The exact listing title |
| Description | Full job description text |
| Budget (USD) | Fixed price or hourly rate range |
| Skills Required | Listed skills and technologies |
| Proposal Count | How many freelancers already applied |
| Average Bid | Mean bid amount from existing proposals |
| Client Rating | Employer's average review score |
| Client Hire Rate | Percentage of jobs where the client hired someone |
| Payment Verified | Whether the client has verified payment method |
| **Competition Score** | **1-10 score - lower is better** |
| Platform | freelancer.com or upwork.com |
| URL | Direct link to apply |

#### Why This Beats Manual Searching

- **Instant prioritization** - sort by Competition Score and apply to the best gigs first
- **Hidden gems** - find jobs with low proposals that are buried on page 3+
- **Cross-platform** - compare Freelancer.com and Upwork side by side
- **Smart filtering** - skip jobs with too many proposals or budgets below your minimum
- **Structured data** - JSON output ready for your pipeline, spreadsheet or notification system

#### Perfect For

- **Freelancers** - find low-competition, high-value gigs faster than anyone else
- **Freelance agencies** - monitor new job postings across platforms automatically
- **Lead generation** - build lists of businesses posting freelance jobs
- **Market research** - analyze freelance market trends, average budgets and competition levels
- **Job alert systems** - set up automated notifications for your niche keywords
- **Rate benchmarking** - understand what clients pay for specific skills

#### Platform Support

| Platform | Free Plan | Proxy Required | Notes |
|----------|-----------|----------------|-------|
| Freelancer.com | Yes | No | Uses CheerioCrawler - fast and lightweight |
| Upwork | No | Yes (Residential) | Requires paid plan + residential proxies for Cloudflare bypass |

#### How to Use

1. Select your platforms (freelancer, upwork, or both)
2. Enter search keywords (e.g., "python scraping", "react developer", "logo design")
3. Set your filters: max proposals, minimum budget, max pages
4. Run and get scored results sorted from easiest to hardest

#### Example Output

```json
{
  "title": "Build a Python web scraper for e-commerce prices",
  "description": "Need a scraper that extracts product prices from 5 competitor websites...",
  "platform": "freelancer",
  "budgetMin": 250,
  "budgetMax": 750,
  "currency": "USD",
  "proposalCount": 8,
  "averageBid": 450,
  "clientRating": 4.8,
  "clientHireRate": 0.85,
  "paymentVerified": true,
  "skills": ["python", "web-scraping", "data-extraction"],
  "competitionScore": 3,
  "url": "https://www.freelancer.com/projects/..."
}
````

#### Technical Details

- **Crawler engine**: CheerioCrawler for Freelancer.com (no browser needed), Playwright for Upwork
- **Validation**: AJV schema validation on all inputs
- **Free plan compatible**: Freelancer.com works without proxies on Apify FREE plan
- **Output format**: Structured JSON via Apify Dataset
- **Error handling**: Failed URLs logged to KeyValueStore under "FAILED\_URLS"

# Actor input Schema

## `platforms` (type: `array`):

Platforms to scrape. Allowed values: 'freelancer', 'upwork'. Default is \['freelancer'] because Upwork requires residential proxies (paid plan) to bypass Cloudflare.

## `keywords` (type: `array`):

Search keywords, e.g. \['python scraping', 'react developer']. At least one keyword is required.

## `categories` (type: `array`):

Job category slugs from the platform (optional filter). Example: 'web-development', 'mobile-development'.

## `max_proposals` (type: `number`):

Skip listings with more proposals than this threshold. Lower = only less competitive gigs.

## `min_budget` (type: `number`):

Minimum job budget in USD. Listings below this are skipped. Optional.

## `max_pages` (type: `integer`):

Maximum pages to scrape per keyword per platform. Default 3 to conserve compute units on FREE plan. Keep <=3 for Upwork to avoid login walls.

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

Select proxies to be used by the actor. Leave EMPTY on FREE plan — Freelancer.com works without proxies. Residential required for Upwork.

## Actor input object example

```json
{
  "platforms": [
    "freelancer"
  ],
  "keywords": [
    "python scraping",
    "react developer"
  ],
  "max_proposals": 50,
  "max_pages": 3,
  "proxyConfiguration": {}
}
```

# 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 = {
    "platforms": [
        "freelancer"
    ],
    "keywords": [
        "python scraping",
        "react developer"
    ],
    "proxyConfiguration": {}
};

// Run the Actor and wait for it to finish
const run = await client.actor("woundless_yellowwood/freelance-gigs-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 = {
    "platforms": ["freelancer"],
    "keywords": [
        "python scraping",
        "react developer",
    ],
    "proxyConfiguration": {},
}

# Run the Actor and wait for it to finish
run = client.actor("woundless_yellowwood/freelance-gigs-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "platforms": [
    "freelancer"
  ],
  "keywords": [
    "python scraping",
    "react developer"
  ],
  "proxyConfiguration": {}
}' |
apify call woundless_yellowwood/freelance-gigs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=woundless_yellowwood/freelance-gigs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Freelance Gigs Scraper with Competition Score",
        "description": "Scrape Freelancer.com (free plan) and Upwork (paid plan + residential proxy required) job listings with a 1-10 competition score. Get proposal counts, bid ranges, client quality signals, budget and skills. Filter by max proposals and min budget.",
        "version": "0.0",
        "x-build-id": "fPpE7Bze0YMagCBLg"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/woundless_yellowwood~freelance-gigs-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-woundless_yellowwood-freelance-gigs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/woundless_yellowwood~freelance-gigs-scraper/runs": {
            "post": {
                "operationId": "runs-sync-woundless_yellowwood-freelance-gigs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/woundless_yellowwood~freelance-gigs-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-woundless_yellowwood-freelance-gigs-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "platforms",
                    "keywords",
                    "max_pages"
                ],
                "properties": {
                    "platforms": {
                        "title": "Platforms",
                        "type": "array",
                        "description": "Platforms to scrape. Allowed values: 'freelancer', 'upwork'. Default is ['freelancer'] because Upwork requires residential proxies (paid plan) to bypass Cloudflare.",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "freelancer"
                        ]
                    },
                    "keywords": {
                        "title": "Search Keywords",
                        "type": "array",
                        "description": "Search keywords, e.g. ['python scraping', 'react developer']. At least one keyword is required.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "categories": {
                        "title": "Categories (optional)",
                        "type": "array",
                        "description": "Job category slugs from the platform (optional filter). Example: 'web-development', 'mobile-development'.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "max_proposals": {
                        "title": "Max Proposals Threshold",
                        "minimum": 0,
                        "type": "number",
                        "description": "Skip listings with more proposals than this threshold. Lower = only less competitive gigs.",
                        "default": 50
                    },
                    "min_budget": {
                        "title": "Minimum Budget (USD)",
                        "minimum": 0,
                        "type": "number",
                        "description": "Minimum job budget in USD. Listings below this are skipped. Optional."
                    },
                    "max_pages": {
                        "title": "Max Pages per Keyword",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum pages to scrape per keyword per platform. Default 3 to conserve compute units on FREE plan. Keep <=3 for Upwork to avoid login walls.",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Select proxies to be used by the actor. Leave EMPTY on FREE plan — Freelancer.com works without proxies. Residential required for Upwork."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
