DEV Community

Cover image for How to Scrape Hotel Data and Save It to Notion With Apify
Federico Trotta
Federico Trotta

Posted on

How to Scrape Hotel Data and Save It to Notion With Apify

If you want an Actor to write into an app like Notion, Slack, or GitHub on your behalf, you've traditionally had to hardcode a personal API token into the Actor's input. Thanks to the Model Context Protocol (MCP), Apify's new MCP Connectors give you a new option. The Actor talks to the third-party app through the Model Context Protocol, while your credentials never enter the Actor's code at all.

In this article, you'll see this in action twice:

  • First with a ready-made Actor that scrapes hotel data and writes it straight into a Notion dashboard.
  • Then wiring that same Actor into an n8n workflow that adds an AI analysis step on top.

Along the way, we'll look at exactly when, during a run, the connector actually fires, and what that gets you that pasting in a Notion API key couldn't.

What Are MCP Connectors?

Apify’s MCP connectors are Actors that allow you to connect Apify with third parties. This evolution of the platform is important because, until now, the output of each data collection had to run outside Apify. This happened because it was difficult to provide Actors with authenticated access to external applications.

MCP connectors give Actors secure access to external applications on behalf of your account. That means an Actor executes tasks with that account's permissions. However, this connection is secure, and Actors never get access to your credentials or authentication tokens.

To discover the collections, navigate to the MCP connectors collections page:

How to Scrape Hotel Data and Save It to Notion With Apify

In this section, you will learn how to use the “Web Data to Notion Dashboard” Actor. This Actor:

  • Retrieves several verticals like restaurants, hotels, gyms, and more for a given location.
  • Saves the results to a Notion page.

In this tutorial, you’ll learn how to retrieve hotels in a specific location in Los Angeles. Follow along to see how it works!

Prerequisites
To reproduce this tutorial, you need the following:

Setting Up The Environment
Thanks to Apify’s MCP connectors, the only thing you need is the target Notion page where the Actor will report the result:

You will paste its URL later, in step #2.

Step #1: Choose What to Scrape
Connect to Apify’s dashboard using the dedicated actor’s template:

Choose Hotels in What to scrape and define the location:

The target location must be input as:

City, State ZIP
Enter fullscreen mode Exit fullscreen mode

Based on the above image, the location I used is the following:

Long Beach, CA 90801
Enter fullscreen mode Exit fullscreen mode

There’s no particular reason why I chose this location. I wanted a city with a real spread in terms of costs to see whether the price-tier analysis downstream (we’ll do that later in the n8n workflow) would actually mean something.

This template allows you to spend 0$ on your first try by using the demo data already retrieved by the author. Such demo data are restaurants in Austin. If you want to change this setting to scrape different data, click on the JSON tab:

Locate dataSource:

Change demo to yourOwn:

Alright! You correctly set up the target content to scrape.

Step #2: Connect the Notion Page’s URL
This is where the connector gets wired up. In the MCP Connector box, click on the + button under the Notion workspace section:

Select Notion’s MCP server:

Give a name to the connector, select the authorization method you prefer, and click on Authorize:

Paste the Notion page’s URL you previously created:

So, in a couple of clicks, you connected Apify to Notion via MCP.

Step #3: Define Optional Parameters
Considering this specific case, you should set the following:

  • Map view: Set to Auto (Recommended).
  • Gallery view: Toggle on. This is because the scraper will provide you with a gallery of photo thumbnails, which is useful for this use case.
  • Cost cap: Define a maximum amount of dollars you’d like to spend. Just in case this goes far than you think.
  • Run options: You can leave as default.

Below is what you’ll see in the dashboard:

At this point, the setup is complete.

Step #4: Run and See Results
When you are ready, click on Save and start to save and run the program:

The Actor will start running:

In the Output tab, you will see:

Note that the three red crosses shown in the image above are not signs of failures, as I thought in the very first moment I saw them. In this case, these mean that:

  • The Notion URL is not a public one.
  • The data provided is not from the sample. Indeed, in step #1 you switched from demo to yourOwn so that Apify’s actor could retrieve the data you needed.
  • The data is not cached from a previous run. Indeed, this was the first run.

The result on the Notion page is the following:

What’s interesting to note is that all this only costs only 0.2$:

That’s it for this first tutorial with Apify’s MCP connectors.

Where the Connector Actually Fires

Everything up to now happened before the run started. At this point, it's worth pausing on what happens during the run, because that's the part a manual integration can't replicate.

The Actor's execution is really two separate phases, using two separate credentials:

  1. Scrape phase: The Actor calls an upstream scraper (Google Maps Scraper, in this hotel example) using Apify's own token, exactly like any normal Actor-to-Actor call.
  2. Write phase: Once the scraped rows are normalized, the Actor calls Notion's MCP server. This is the moment the connector fires. The call leaves the Actor, hits Apify's MCP proxy, and the proxy (not the Actor) attaches your Notion token before forwarding it to Notion.

Two things fall out of that design that a manual API-key setup doesn't give you:

  • The Actor's code never holds your token: It's not in an environment variable, not in the input JSON you just filled in, not in any log line. If you inspect a run's logs, you'll see that notion-create-pages was called and how many times.
  • The connection is scoped, not just authenticated: The Actor declares up front, in its input schema, exactly four Notion tools it's allowed to call. Apify's proxy enforces that list at runtime. And even if Notion itself would allow broader access with your token, the Actor physically cannot call anything outside that allowlist.

Keep that in mind as we now rebuild the same pipeline manually in n8n, and watch for the point where you have to go get a Notion token yourself.

How to Build an Analysis Workflow On Top Of It With n8n

In this section, we’re going to create an automation workflow with n8n that allows us to do a step more than before. When Apify’s Actor has written the scraped data into the Notion page, we’ll use AI to make some analytics on the hotel data.

Prerequisites
To reproduce this tutorial, you have to match the prerequisites of the previous paragraph, plus you need a valid n8n account.

NOTE: n8n provides you with a 14-day trial.

Step #1: Start a New n8n Workflow and Connect Apify to It
Start by creating a new n8n workflow:

As a first node, add an Apify Actor:

At first usage, you’ll need to install the Apify node:

When the Apify node is installed in n8n, select Run an Actor:

Below is what you’ll see inside the node:

Step #2: Set Up Apify Actor
To use the Apify node, connect it to your Apify account and allow access:

Select Apify Store Actors as the Actor Source. In the Actor box, select By URL and paste the Actor’s template URL:

The Apify node in n8n must work the same way the Apify Actor does in Apify’s dashboard. What’s missing, at this point, is the JSON that governs the process. You can retrieve it in the Input tab in Run in your Apify dashboard:

Copy and paste the complete JSON in the JSON box in n8n’s node:

Leave the other settings as default. To test it, click on Execute step. In the OUTPUT section, you will see that the run was successful:

If you go to the Runs tab in your Apify console, you will find a new run. In this case, the system flags this run as started from n8n:

Your Apify node is correctly set up. Let’s expand the workflow with other nodes.

Step #3: Add a Notion Node
The second item in the workflow should be a Notion node. This way, the Apify node will save the results into the target Notion page. Search for Notion and select the Get many child blocks:

This node reads a target Notion page and returns all its content elements as JSON.

To use this node, connect to your Notion account. This is where the procedure differs from the previous one, as there’s no MCP connector in this case. Click on Set up credentials:

Notice the shift here: in the Apify-only walkthrough above, the connector meant you never touched a Notion token. In n8n, there's no equivalent connector for this node. So, you're back to the manual pattern: generating a personal API key and pasting it in. That's the trade-off of leaving Apify's proxy: n8n's own credential store is reasonably secure, but the token now exists somewhere you have to manage yourself.

Select a connection methodology. In this case, I chose to connect via API Key (but you can choose OAuth2, if you prefer) because, in my specific case, it was the fastest way:

NOTE: You can create a Notion API key in the personal access tokens page.

Set the other parameters as in the following image:

The ID of the target Notion page can be retrieved from its URL like that:

https://app.notion.com/p/<your-page-ID>?v=<other-numbers>
Enter fullscreen mode Exit fullscreen mode

When you execute the step, you can see the result in the OUTPUT section:

At that point, your workflow looks like that:

At this point, the results in the Notion page are ready to be retrieved and analyzed.

Step #4: Add an Aggregator
As said in the previous step, the Notion node retrieves the data in the target Notion page and reports it inside the workflow as JSON. To let the AI evaluate the JSON response as a whole, add an aggregator item node:

Choose Individual Fields in the Aggregate box. Under Fields to aggregate, add the property_price_tier and property_name fields:

This way, when you execute the node, the aggregator will aggregate these two fields. We used these properties so that the LLM can “connect” the price to the related hotel name.

There are two ways by which you can insert the target properties into the field boxes:

  • You can copy and paste them.
  • You can drag and drop them from the INPUT panel directly into the fields.

Below is the workflow until now:

With this node, the results are now aggregated. Time to use AI to analyze it!

Step #5: Add an AI Node
There are a few ways in which you can introduce AI into n8n workflows. For this tutorial, adding a Basic LLM chain node is sufficient:

Select Define below in Source for Prompt to define a custom prompt:

You can use the following custom prompt:

You are a data analysis assistant. Below is a list of hotels retrieved from a database. 

DATA:
{{ JSON.stringify($json) }}

YOUR TASK:
1. Extract the 'property_name' and the numerical value from 'property_price_tier' (e.g., convert "$85" to 85).
2. Calculate the mean (average) price of all hotels that have a price listed.
3. List the hotels that are ABOVE the mean price.
4. List the hotels that are BELOW the mean price.
5. Identify any hotels that have a missing price and list them separately.

Respond in a clear, structured format.
Enter fullscreen mode Exit fullscreen mode

Two things you have to take care of if you use this exact prompt:

  • {{ JSON.stringify($json) }} is needed because it converts the computer-formatted data (JavaScript object) into plain text (a JSON string) so the AI can actually "read" and analyze the content.
  • You have to use the exact parameter names you used in the previous step: property_name and property_price_tier.

In the model’s connector, add an LLM of your choice:

Below is how the workflow appears now:

The workflow is now complete!

Step #6: See The Workflow’s Results
You can now execute the Basic LLM Chain node, obtaining the final result:

Below is the cleaned result:

After removing entries with missing prices and converting to numerical values, the average price of the hotels is calculated as $125.65. 
Hotels with prices ABOVE the mean price of $125.65:
- Kearney Motel    
- The Cove Hotel    
- Residence Inn by Marriott Long Beach Downtown    
- Hyatt Centric The Pike Long Beach    
- The Maya (formerly Hotel Maya)   
- Historic Broadlind Hotel at Long Beach Convention Center    
- Hotel Mai Downtown Long Beach   
- Dockside Boat & Bed\n    
- Fairmont Breakers Long Beach    
- Hilton Long Beach    
- City Center Hotel by Kasa    
- City Center Hotel Long Beach, Sonder   
- Lumea by the Sea Long Beach Convention Center  
- Hyatt Regency Long Beach   
- Courtyard by Marriott Long Beach Downtown  
- Marriott Long Beach Downtown  
- The Queen Mary   
- Best Western Plus Hotel at the Convention Center    
- The Westin Long Beach 

Hotels with prices BELOW the mean price of $125.65:   
- Hyland Inn    
- Ruby Motel 
- La Mirage Inn - Long Beach 
- Arlington Motel 
- Tower Motel Long Beach   
- UpTown Inn
- Cabana Inn & Suites 
- Playa Inn Motel  
- Eagle Inn Long Beach   
- Sunlight Motel 
- Parkside Inn
- La Bonita Inn Motel Long Beach    
- Searle Motel    
- Sunshine Motel    
- Stallion Inn Motel    
- Hotel Salina Long Beach   
- Scottish Inns Long Beach, CA    
- Kay's Motel    
- Vagabond Inn Long Beach    
- Walls Motel Long Beach    
- Flamingo Inn Motel  
- Beach Inn
- Inn of Long Beach  
- Hotel Metropolitan Long Beach   
- Inn at 50 Long Beach Convention Center   
- Hotel Current Long Beach
- Travelodge by Wyndham Long Beach Convention Center   
- The Belmont Shore Inn

Hotels with a missing price:  
- Bristol Motel   
- Travel King Motel
Enter fullscreen mode Exit fullscreen mode

Just to be sure the result is not a hallucination by the model, the image below shows the two hotels that actually have missing prices:

Et voilà! You made it to create an automation workflow, starting from an Apify Actor.

Conclusion

Across both walkthroughs, the pattern worth remembering is where the credential lives. With Apify's MCP Connector, the Notion token never leaves Apify's proxy, and the Actor is limited to a fixed, declared set of Notion tools. This means a run can create your dashboard but can't touch anything else in your workspace, by construction.

Overall, using the Apify MCP connector also simplified n8n’s workflow. This is because, without that, you’d need an additional node that gets the results scraped from an Apify actor and writes them to Notion. And guess what? That node would need authentication to your Notion account!

Top comments (0)