DEV Community

Cover image for Overcoming Cloudflare Blocks on Preply to Analyze Tutor Pricing Trends
Crawler Bros
Crawler Bros

Posted on Fully Autonomous

Overcoming Cloudflare Blocks on Preply to Analyze Tutor Pricing Trends

Building a localized pricing index for online language tutoring requires structured, fresh market data. Analysts comparing tutoring marketplaces often need to evaluate average hourly rates, native speaker availability, and professional certifications across different languages and regions. However, extracting this data at scale from Preply presents immediate technical challenges. The platform uses Cloudflare protection to prevent automated collection, which frequently results in HTTP 503 errors or CAPTCHA challenges when using standard scraping libraries.

To bypass these blocks and gather clean structured datasets, developers can use the preply-scraper on the Apify platform. This tool is built specifically to navigate Preply's anti-scraping defenses while exposing clean parameters for filtering by subject, language, country, and price.

How to Query the Preply Public Directory

The scraper operates in two distinct execution paths defined by the mode parameter: directory search (searchTutors) and direct profile extraction (getTutor).

In searchTutors mode, the tool paginates through Preply's public index. It handles the underlying pagination logic automatically, returning up to 10 tutors per page. You can narrow your query using specific schema parameters to target exact market segments. For instance, if you need to analyze the premium market for certified German teachers, you can target specific sub-segments rather than pulling the entire directory.

Here is an example input payload for a targeted search:

{
  "mode": "searchTutors",
  "language": "german",
  "proOnly": true,
  "minRating": 4.8,
  "maxPrice": 50,
  "maxItems": 100,
  "useProxy": true
}
Enter fullscreen mode Exit fullscreen mode

The useProxy boolean is set to true by default. When enabled, the execution automatically falls back to Playwright combined with residential proxy rotation if direct HTTP requests are blocked by Cloudflare. This ensures that the scraper mimics legitimate user traffic and maintains a high success rate over large runs.

Extracting Detailed Profiles with IDs

The directory search returns a high-level summary of each tutor, including their hourlyRate, rating, totalLessons, and responseRate. However, if your analysis requires deep academic or credential verification, you need the tutor's historical background.

By switching the mode parameter to getTutor, you can feed the scraper specific identifiers. This mode accepts either full profile links via the startUrls array or numeric IDs via the tutorIds array.

{
  "mode": "getTutor",
  "tutorIds": ["12345", "67890"]
}
Enter fullscreen mode Exit fullscreen mode

When running in getTutor mode, the scraper extracts detailed nested structures that are omitted from the main search results page, specifically:

  • education: Academic degrees, institutions, and graduation years.
  • certificates: Certified teaching credentials and issuing bodies.

The output from this run is returned as a clean JSON object containing the scrapedAt timestamp, ensuring you can track data freshness for historical analysis.

{
  "tutorId": "12345",
  "name": "Maria S.",
  "country": "Spain",
  "nativeLanguage": "Spanish",
  "languagesTaught": ["Spanish"],
  "hourlyRate": 15.0,
  "currency": "USD",
  "rating": 4.9,
  "reviewCount": 150,
  "totalLessons": 1200,
  "responseRate": "98%",
  "isPro": true,
  "profileUrl": "https://preply.com/en/tutor/12345",
  "avatarUrl": "https://cdn.preply.com/avatar/12345.jpg",
  "recordType": "tutor",
  "scrapedAt": "2026-05-17T10:00:00+00:00"
}
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Implementation

To run this scraper programmatically, follow these steps:

  1. Configure your Apify environment: Set up an account on the Apify platform to access the API and retrieve your API token.
  2. Define your search parameters: Construct your JSON input. Specify the target language (such as "spanish" or "japanese") and apply filters like tutorCountry using ISO country codes (e.g., ES or MX,CO) to segment your search.
  3. Execute the Actor: Run the preply-scraper with your payload. The platform handles the infrastructure, proxy rotation, and retries on rate limits.
  4. Fetch the Dataset: Once the run completes, download the resulting data from the default dataset.

Predictable Event-Based Costs

Estimating the cost of data pipeline operations is straightforward because this scraper uses a transparent PAY_PER_EVENT pricing model. Unlike traditional scrapers that bill based on unpredictable server execution time, this tool charges strictly for successful data delivery and execution starts.

The cost structure consists of exactly two event types:

  • Actor Start (apify-actor-start): Charged at a flat rate of $0.005 per GB of memory allocated to the run. This event occurs once per run execution.
  • Result (apify-default-dataset-item): Charged at $0.005 per single tutor profile successfully returned in your dataset.

As your data requirements scale, the pricing for results decreases according to specific volume-tier prices:

  • FREE: $0.005 per result
  • BRONZE: $0.00433 per result
  • SILVER: $0.00367 per result
  • GOLD: $0.003 per result
  • PLATINUM: $0.003 per result
  • DIAMOND: $0.003 per result

For example, a run configured with maxItems: 1000 allocated with 1 GB of memory will cost exactly $0.005 for the run initiation, plus the cost of the results. Under the FREE tier rate, 1,000 extracted tutor profiles will cost $5.00, bringing the total run cost to $5.005.

Limitations of the Scraping Approach

This scraper is optimized for public directory extraction and individual profile retrieval, but it is not designed for real-time chat monitoring or scheduling updates. It cannot access private tutor-student messaging feeds, internal lesson bookings, or account-specific dashboards, as these require active user authentication. Additionally, while the scraper can filter by general availability using the availabilityDay parameter, it does not fetch the granular, real-time booking calendar slots for individual tutors.


The examples here were produced with Preply Tutor Profiles Scraper. Its README lists the output fields, so you can check a response against the schema before you build on it.

Top comments (0)