In this guide we read every story on the Hacker News front page and save each one into a table: its title, its link and its id. Run it again and nothing is saved twice. This is how you collect products, posts, prices or leads from any listing page.
What you build: Manual β Open URL β Extract (list) β Loop over items β Data table (back into the loop), then Notify when done
The website: https://news.ycombinator.com. Each story is a table row <tr class="athing" id="β¦"> with its title link in .titleline > a.
Step 1: Make the table
The table keeps your data between runs.
- In the sidebar, open Dataset βΊ Tables.
- Press New table.
- Name:
Stories. - Under Columns, add
title(Text) andurl(Text). - Save it.
Every row also has a key of its own. We'll use the story's id as the key, so the same story can't be saved twice.
Step 2: Create the flow and open the page
- Studio βΊ Flows βΊ New flow, name it
Save stories, then Create. - Add first step βΊ Manual.
- + on Manual βΊ Open URL. In URL, type
https://news.ycombinator.com.
Step 3: Read every story
- + on Open URL's Next βΊ Extract.
- Mode: List of items.
- Element:
tr.athing. That's one story row. - Under List fields, add three fields:
| Name | Selector | Attribute |
|---|---|---|
id | (empty: the row itself) | id |
title | .titleline > a | (empty: its text) |
url | .titleline > a | href |
- Limit:
30(the front page shows 30).
Right-click Extract βΊ Run from here (or run the flow with Test run) and open its Output. You'll see one item holding a list:
{
"items": [
{ "id": "41923456", "title": "Show HN: β¦", "url": "https://example.org/β¦" },
{ "id": "41923311", "title": "β¦", "url": "https://news.ycombinator.com/item?id=41923311" }
]
}
Step 4: Go through the list one story at a time
Extract gives one item with a list inside. Loop over items turns it into one story at a time.
- + on Extract's Next βΊ Loop over items.
- Go through: A list.
- List: type
{{and pick Extract'sitems. It reads{{ nodes.extract.output.items }}. - Maximum items:
30.
Loop has two output dots:
- Item: once per story. Connect the steps to repeat here, and connect the last of them back into the Loop.
- Done: once, after the last story. Connect what comes after here.
Step 5: Save each story
- + on Loop's Item dot βΊ Data table.
- Table:
Stories. - Operation: Change or add. It adds a row, or updates the one with the same key, so you never get duplicates.
- Where (column: value, or id):
{ "key": "{{ nodes.loop.output.item.id }}" }
- Data (column: value):
{
"key": "{{ nodes.loop.output.item.id }}",
"title": "{{ nodes.loop.output.item.title }}",
"url": "{{ nodes.loop.output.item.url }}"
}
- Now close the loop: drag from Data table's Next dot back onto the Loop over items card's input dot.
nodes.loop.output.item is the story the loop is on right now.
Step 6: Say when it's done
- + on Loop's Done dot βΊ Notify.
- Title:
Stories saved. - Message:
{{ item.count }} stories checked.
Your canvas:
Manual β Open URL β Extract β Loop over items βItemβ Data table ββ
β² β
ββββββββββββββββββββββββββββββββ
ββDoneβ Notify
Step 7: Test it, then run it for real
- Press Test run. The loop card shows
Γ30and the status card saysLoop over items: item 12 of 30as it goes. - Open Dataset βΊ Tables βΊ Stories. The rows are there, marked as test rows, kept apart from real ones.
- Press Clear test data in the table to remove them.
- Back in the flow, press Run and confirm Run for real?. This time the rows are real.
- Press Run again. The rows are updated, not doubled: same key, same row.
Make it yours
The same five nodes work on any listing page. Change the URL, the row selector and the fields:
| Site type | Element | Fields |
|---|---|---|
| Online shop | .product-card | name h3, price .price, link a β href |
| Blog | article | title h2, date time β datetime, link a β href |
| Job board | [data-job-id] | id (empty) β data-job-id, role h2, company .company |
Need more than one page of results? Add Scroll (Until enough elements) before Extract on infinite-scroll pages. On numbered pages, open each page address in its own loop.
Next: .
FAQ
Why do I need Loop over items? Doesn't a node run once per item?
It does, but Extract gives one item with a list inside it, not one item per story. Loop over items hands the stories on one by one, and Done tells you when every story is through.
Why does the last step connect back into the loop?
That's how the loop knows a story is finished and takes the next one. If you forget the line back, the loop stops after the first story.
Can I save only new stories?
Yes. Before Data table, add another Data table with Find rows and Where { "key": "{{ nodes.loop.output.item.id }}" }. Its Nothing found dot leads to the save, and its Next dot goes straight back into the loop.
Did the test run write to my table?
Yes, but only as test rows. A test run keeps its rows apart, so it never touches real rows. Clear test data removes them.