Finds the pages on a site from its sitemap or front page, reads each one, and adds a row per page to your sheet.
Uses
Google Sheets
Jina AI
OpenAI
Read a whole site into spreadsheet rows
siteUrl to blank.Set siteUrl to blank.fieldsToExtract to blank.Set fieldsToExtract to blank.spreadsheetUrl to blank.Set spreadsheetUrl to blank.sheetName to Sheet1.Set sheetName to Sheet1.sitemapUrl to blank.Set sitemapUrl to blank.maxPages to 20.Set maxPages to 20.pageCeiling to 50.Set pageCeiling to 50.maxPageCharacters to 12000.Set maxPageCharacters to 12000.columnSeparator to |||.Set columnSeparator to |||.siteUrl split by :// and save it as siteScheme.Get the first item of siteUrl split by :// and save it as siteScheme.siteUrl split by :// and save it as siteHostAndPath.Get the last item of siteUrl split by :// and save it as siteHostAndPath.siteHostAndPath split by / and save it as siteHost.Get the first item of siteHostAndPath split by / and save it as siteHost.siteHost is emptyIf siteHost is emptyYes
No
No steps
siteRoot to siteScheme://siteHost/.Set siteRoot to siteScheme://siteHost/.sitemapUrl is emptyIf sitemapUrl is emptyYes
sitemapUrl to siteRootsitemap.xml.Change sitemapUrl to siteRootsitemap.xml.No
No steps
maxPages multiplied by 1 to the nearest integer and save it as pageLimit.Round maxPages multiplied by 1 to the nearest integer and save it as pageLimit.pageLimit is less than 1If pageLimit is less than 1Yes
No
No steps
pageLimit is greater than pageCeilingIf pageLimit is greater than pageCeilingYes
pageLimit to pageCeiling.Change pageLimit to pageCeiling.pageCeiling as text pages, so 'maxPages' was treated as pageCeiling as text. Run it again to pick up where it left off.Show in the output: One run never reads more than pageCeiling as text pages, so 'maxPages' was treated as pageCeiling as text. Run it again to pick up where it left off.No
No steps
maxPageCharacters multiplied by 1 to the nearest integer and save it as pageCharacterLimit.Round maxPageCharacters multiplied by 1 to the nearest integer and save it as pageCharacterLimit.discovered to an empty list.Set discovered to an empty list.sitemapErrorIf a step below fails, save the error as sitemapErrorTry
sitemapUrl and save it as sitemapResponse.Fetch sitemapUrl and save it as sitemapResponse.sitemapResponse.ok is yesIf sitemapResponse.ok is yesYes
sitemapResponse.body and save it as sitemapText.Trim sitemapResponse.body and save it as sitemapText.sitemapText in lowercase doesn't contain <sitemapindexIf sitemapText in lowercase doesn't contain <sitemapindexYes
sitemapText and save it as discovered.Extract all web addresses from sitemapText and save it as discovered.discovered as text address(es) listed in it.Show in the output: Read the sitemap and found the length of discovered as text address(es) listed in it.No
The sitemap is an index of other sitemaps rather than a list of pages, so the links on the front page are used instead..Show in the output: The sitemap is an index of other sitemaps rather than a list of pages, so the links on the front page are used instead..No
No steps
On error
sitemapError.message with sitemapUrl replaced by the sitemap address.Show in the output: Could not read the sitemap: sitemapError.message with sitemapUrl replaced by the sitemap address.discovered is emptyIf discovered is emptyYes
frontPageErrorIf a step below fails, save the error as frontPageErrorTry
siteUrl with Jina. Save it as frontPage.Read the page at siteUrl with Jina. Save it as frontPage.frontPageLink in frontPage.links:For each frontPageLink in frontPage.links:frontPageLink.url to the end of discovered and save it as discovered. Add frontPageLink.url to the end of discovered and save it as discovered.discovered as text link(s) on the front page.Show in the output: Found the length of discovered as text link(s) on the front page.On error
frontPageError.message with siteUrl replaced by the site address.Show in the output: Could not read the front page to find its links: frontPageError.message with siteUrl replaced by the site address.No
No steps
discovered is emptyIf discovered is emptyYes
No
No steps
alreadyInTheSheet to an empty list.Set alreadyInTheSheet to an empty list.sheetErrorIf a step below fails, save the error as sheetErrorTry
sheetName in spreadsheetUrl. Save it as recordedPages.Read column 1 of sheetName in spreadsheetUrl. Save it as recordedPages.recordedPages.values into one list and save it as alreadyInTheSheet.Combine [] and recordedPages.values into one list and save it as alreadyInTheSheet.On error
Could not read the page addresses already in the sheet, so every page found will be read this run..Show in the output: Could not read the page addresses already in the sheet, so every page found will be read this run..candidatePages to an empty list.Set candidatePages to an empty list.siteRoot] and discovered into one list and save it as everythingFound.Combine a list of [siteRoot] and discovered into one list and save it as everythingFound.foundLink in everythingFound with duplicates removed:For each foundLink in everythingFound with duplicates removed:linkErrorIf a step below fails, save the error as linkErrorTry
foundLink and save it as trimmedLink.Trim foundLink and save it as trimmedLink.trimmedLink split by # and save it as pageAddress.Get the first item of trimmedLink split by # and save it as pageAddress.pageAddress/ doesn't start with siteRoot (ignoring case)If pageAddress/ doesn't start with siteRoot (ignoring case)Yes
No
No steps
pageAddress ends with .xml (ignoring case) is yesIf pageAddress ends with .xml (ignoring case) is yesYes
No
No steps
alreadyInTheSheet contains pageAddress is yesIf alreadyInTheSheet contains pageAddress is yesYes
No
No steps
candidatePages contains pageAddress is yesIf candidatePages contains pageAddress is yesYes
No
No steps
pageAddress to the end of candidatePages and save it as candidatePages.Add pageAddress to the end of candidatePages and save it as candidatePages.On error
Skipped one discovered link because it had no address..Show in the output: Skipped one discovered link because it had no address..candidatePages is emptyIf candidatePages is emptyYes
No
No steps
pageLimit items of candidatePages and save it as pagesToRead.Take the first pageLimit items of candidatePages and save it as pagesToRead.candidatePages as text page(s) on this site that are not in the sheet yet; reading the length of pagesToRead as text of them this run.Show in the output: Found the length of candidatePages as text page(s) on this site that are not in the sheet yet; reading the length of pagesToRead as text of them this run.rowsWritten to 0.Set rowsWritten to 0.pagesWithoutRows to an empty list.Set pagesWithoutRows to an empty list.pageAddress in pagesToRead:For each pageAddress in pagesToRead:pageErrorIf a step below fails, save the error as pageErrorTry
pageAddress with Jina. Save it as page.Read the page at pageAddress with Jina. Save it as page.page.content and save it as pageText.Trim page.content and save it as pageText.pageTitle to blank.Set pageTitle to blank.titleErrorIf a step below fails, save the error as titleErrorTry
page.title and save it as pageTitle.Trim page.title and save it as pageTitle.On error
pageTitle to blank.Change pageTitle to blank.pageText isn't emptyIf pageText isn't emptyYes
promptTask to You are reading one page of a website and filling in one row of a spreadsheet.Set promptTask to You are reading one page of a website and filling in one row of a spreadsheet.
Pull out these details, in this exact order:
fieldsToExtract.promptRules to Set promptRules to
Reply with ONE line and nothing else. Separate the values with columnSeparator in the order listed above. Do not repeat the field names, do not add headings, bullets, numbering or any commentary, and do not wrap values in quotes. Write n/a for anything the page does not say.promptPage to Set promptPage to
Page address: pageAddress
Page title: pageTitle
Page content:
pageText truncated to pageCharacterLimit characters.prompt to promptTask plus promptRules plus promptPage.Set prompt to promptTask plus promptRules plus promptPage.prompt. Save it as extraction.Ask OpenAI: prompt. Save it as extraction.extraction.response_text and save it as answerLine.Trim extraction.response_text and save it as answerLine.pageAddress, pageTitle] and save it as row.Create a list of [pageAddress, pageTitle] and save it as row.extractedValue in answerLine split by columnSeparator:For each extractedValue in answerLine split by columnSeparator:extractedValue to the end of row and save it as row. Add extractedValue to the end of row and save it as row.sheetName in spreadsheetUrl.Add a row to sheetName in spreadsheetUrl.rowsWritten.Add 1 to rowsWritten.No
pageAddress to the end of pagesWithoutRows and save it as pagesWithoutRows.Add pageAddress to the end of pagesWithoutRows and save it as pagesWithoutRows.On error
pageAddress to the end of pagesWithoutRows and save it as pagesWithoutRows.Add pageAddress to the end of pagesWithoutRows and save it as pagesWithoutRows.pageError.message.Show in the output: Could not read '@pageAddress': pageError.message.rowsWritten as text row(s) to '@sheetName'.Show in the output: Finished. Wrote rowsWritten as text row(s) to '@sheetName'.pagesWithoutRows isn't emptyIf pagesWithoutRows isn't emptyYes
pagesWithoutRows joined by , .Show in the output: No row was written for: pagesWithoutRows joined by , .No
No steps