Nimbryxo Studio

Use Pexels Stock Media Scraper with Python

Scrape free stock photos and videos from Pexels. Search by keyword, browse curated/popular media, a photographer's portfolio, or a curated collection. Get direct image and video file URLs, photographer credit, tags, colors, and more.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "collectionSlug": "aquatic-aesthetic-bw7dkse",
  "color": "all",
  "colorHex": "",
  "dedupe": true,
  "includeDetails": false,
  "locale": "en-US",
  "maxDuration": 0,
  "maxItems": 3,
  "mediaIds": [
    "18872916"
  ],
  "mediaType": "photos",
  "minDuration": 0,
  "minFps": 0,
  "minHeight": 0,
  "minWidth": 0,
  "mode": "search",
  "orientation": "all",
  "peopleAge": "all",
  "peopleCount": "all",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "publishedAfter": "",
  "publishedBefore": "",
  "searchQueries": [
    "nature"
  ],
  "size": "all",
  "username": "alex-ivanov-773258579"
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
modestringrequiredWhat to fetch from Pexels. Use Search by keyword for discovery, Look up media by ID/URL for exact assets, Photographer portfolio or Collection for a catalog, Similar media for related assets, Curated feed for Pexels' editorial selection, or Paste URLs to route any Pexels link automatically.
searchQueriesarrayoptionalOne or more keywords for mode=search, one per line. Each query is searched separately and duplicates are removed. Example: `nature`, `city skyline`, `coffee`.
mediaTypestringoptionalPhotos, videos, or both. `all` searches photos and videos and merges the results. Exact ID/URL lookups return the requested media type regardless of this setting.
startUrlsarrayoptionalPexels search, photo, video, photographer, collection, image-file, or video-file URLs for mode=byUrl. Search URLs keep their orientation, size, color, people, and page filters.
orientationstringoptionalFilter by media orientation. Applies to search, profile, and collection modes.
sizestringoptionalPexels minimum-size filter. Photos: large is 24 MP, medium is 12 MP, small is 4 MP. Videos: large is 4K, medium is Full HD, small is HD.
colorstringoptionalFilter photos by dominant color. Use Color hex instead for an exact hex value. Photos only.
colorHexstringoptionalOptional hex color such as `#2563eb` or `#fff`. Overrides the Color dropdown when set. Photos only.
peopleCountstringoptionalFilter by how many people appear in the media. Applies to photos and videos.
peopleAgestringoptionalFilter by the age of people in the media. Applies to photos and videos.
localestringoptionalPexels locale for titles, descriptions, and search results. Search terms are used as typed.
minWidthintegeroptionalOnly return media at least this wide. 0 disables the filter. Enforced on each returned record.
minHeightintegeroptionalOnly return media at least this tall. 0 disables the filter. Enforced on each returned record.
minFpsintegeroptionalOnly return videos with at least this many frames per second (for example 60). 0 disables the filter. Photos always pass.
minDurationintegeroptionalOnly return videos at least this many seconds long. 0 disables the filter.
maxDurationintegeroptionalOnly return videos at most this many seconds long. 0 disables the filter.
publishedAfterstringoptionalOptional YYYY-MM-DD date. Only return media published on or after this date. Applied to the records returned by the current search/all listing.
publishedBeforestringoptionalOptional YYYY-MM-DD date. Only return media published on or before this date. Applied to the records returned by the current search/all listing.
mediaIdsarrayoptionalPexels photo or video IDs, or full photo/video/image-file URLs. Used by Look up media by ID/URL and Similar media modes.
usernamestringoptionalPexels photographer handle, ID, or profile URL for mode=byUser. Example: `alex-ivanov-773258579` or `https://www.pexels.com/@alex-ivanov-773258579/`.
collectionSlugstringoptionalPexels collection slug or full collection URL for mode=byCollection. Example: `aquatic-aesthetic-bw7dkse`.
maxItemsintegeroptionalMaximum number of media records to return across all queries, IDs, and URLs. Pexels search serves at most about 480 records per query (20 pages of 24); a single search query cannot exceed that even with a higher value.
includeDetailsbooleanoptionalOpen each media's detail page to add views, downloads, likes, camera/EXIF data, and the photographer's full profile. Adds one request per item and can be slow on large runs. Mode=byMediaId always enriches.
dedupebooleanoptionalKeep only the first occurrence of each photo or video across queries, IDs, and URLs.
proxyConfigurationobjectoptionalOptional Apify proxy override. The actor works directly without a proxy and escalates automatically only if Pexels blocks the run.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/b6anw2Kxq3xyPpgNC/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

Free stock photos and videos from Pexels — titles, photographer credit, dimensions, tags, colors, and direct image/video file URLs.

Questions before you run

Which inputs are required?

The published required fields are mode

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build rSmmuRgL2b2u0iqFa and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.