wk10-d02-fun-iterations
Chico State
DATA 385 - Fall 2026
October 29, 2026
š„ Functions (22 min) and Iteration (14 min) - code along in wk10-d02
This deck runs on saved copies of the gov.scot pages in notes/data/, so rendering does not request the site each time. The live code is shown, and the results come from the saved copies.
The gov.scot pages were redesigned after the videos were made. The selectors in this deck are the current ones and differ from the video, and the functions have been updated.
html_node() in the video is html_element() herehtml_nodes() in the video is html_elements() heremap_dfr() in the video is map() followed by list_rbind() herestr_c() with the . placeholder in the video is url_absolute() hereEverything starts from a page that links to each of the First Ministerās speeches.
We want a table with one row per speech and six columns: title, date, location, abstract, text and url.
# A tibble: 218 Ć 6
title date location abstract text url
<chr> <date> <chr> <chr> <chr> <chr>
1 Coronavirus (COVID-19) up⦠2021-04-20 St Andr⦠Stateme⦠"Goo⦠httpā¦
2 Coronavirus (COVID-19) up⦠2021-04-13 St Andr⦠Stateme⦠"Tha⦠httpā¦
3 Coronavirus (COVID-19) up⦠2021-04-06 St Andr⦠Stateme⦠"Goo⦠httpā¦
4 Coronavirus (COVID-19) up⦠2021-03-30 St Andr⦠Stateme⦠"Tha⦠httpā¦
5 Coronavirus (COVID-19) up⦠2021-03-24 Scottis⦠Stateme⦠"Tha⦠httpā¦
6 Coronavirus (Covid-19) up⦠2021-03-23 The Sco⦠Stateme⦠"Pre⦠httpā¦
7 Coronavirus (COVID-19) up⦠2021-03-18 Scottis⦠Stateme⦠"Tha⦠httpā¦
8 Coronavirus (COVID-19) up⦠2021-03-17 St Andr⦠Stateme⦠"\nG⦠httpā¦
9 Coronavirus (COVID-19) up⦠2021-03-16 Scottis⦠Stateme⦠"Pre⦠httpā¦
10 Coronavirus (COVID-19) up⦠2021-03-15 St Andr⦠Stateme⦠"\nG⦠httpā¦
11 Coronavirus (COVID-19) up⦠2021-03-11 Scottis⦠Stateme⦠"I c⦠httpā¦
12 Coronavirus (COVID-19) up⦠2021-03-09 Scottis⦠Stateme⦠"Pre⦠httpā¦
13 Coronavirus (COVID-19) up⦠2021-03-05 Scottis⦠Parliam⦠"Hel⦠httpā¦
14 Coronavirus (COVID-19) up⦠2021-03-04 Scottis⦠Parliam⦠"I w⦠httpā¦
15 Coronavirus (COVID-19) up⦠2021-03-02 Scottis⦠Stateme⦠"Pre⦠httpā¦
# ā¹ 203 more rows
www.gov.scot/collections/first-ministers-speeches
The links to each speech are not visible text. The URLs live in the page source, so we have to pull them out.
Each speech page has a title, an abstract, the date, the location, and then the text of the speech.
Scrape title, date, location, abstract, and text from a few COVID-19 speech pages to develop the code
Write a function that scrapes title, date, location, abstract, and text from COVID-19 speech pages
Scrape the urls of COVID-19 speeches from the main page
Use this function to scrape from each individual COVID-19 speech from these urls and create a data frame with the columns title, date, location, abstract, text, and url
Copy the URL from the browser, save it as url, and use read_html() to read the page source into speech_page.
The date comes out as a character string. We want R to know it is a date, so we convert it with dmy(), which reads day, month, year.

The text is many paragraphs, so this time we want every match: html_elements(), plural. We store it as a list so all the paragraphs fit in one cell of our data frame.
[[1]]
[1] " Good afternoon, and thanks for joining us. I want to start with the usual daily report on the COVID statistics."
[2] "The total number of positive cases reported yesterday was 1,122."
[3] "This represents 7.1% of the total number of tests carried out. 428 of the new cases were in Greater Glasgow and Clyde, 274 in Lanarkshire, 105 in Lothian and 97 in Ayrshire and Arran. "
[4] "The remaining cases were spread across the mainland health board regions. "
[5] "The total number of confirmed cases is now 57,874."
[6] "I can also confirm that 1,152 people are in hospital ā that is an increase of 36 from yesterday"
[7] "90 people are in intensive care, which is four more than yesterday."
[8] "And I regret to say that in the last 24 hours, one further death has been registered of a patient who first tested positive over the previous 28 days. It is important though to remember that registration offices tend not to be open as normal over the weekend so the Sunday and Monday figures are often lower."
[9] "We also reported 11 deaths on Saturday, and one yesterday. So since the last briefing on Friday, 13 additional deaths have been registered. That takes the total number of deaths, under this measurement, to 2,701."
[10] "That reminds us again of how dangerous this virus can be and I want to send my condolences to everyone who has lost someone."
[11] "I am joined by the Cabinet Secretary for Health who will say a few words about the Scottish Governmentās revised testing strategy and about preparations for winter."
[12] "Firstly, I will give a brief preview of the week ahead, before updating you on one particular issue."
[13] "On Friday, the Scottish Government published our strategic framework for tackling COVID. The framework includes the proposed levels that will apply to different parts of the country, depending on the prevalence of the virus."
[14] "As you recall on Friday we published our strategic framework for tackling COVID."
[15] "That framework included the proposed levels that will apply to different parts of the country, depending on prevalence of the virus."
[16] "Over the weekend, we've discussed the framework with partners and considered further public health advice. These discussions are continuing as are discussions with local councils."
[17] "There are likely to be some clarifications to the detail of the measures we set out on Friday and so we will publish a revised version, ahead of the parliamentary debate that will take place tomorrow."
[18] " And of course we will keep the detail of the levels under ongoing review as the pandemic develops"
[19] "I will also set out more detail ahead of tomorrow's debate on the factors that will guide decisions on which levels apply to different parts of the country."
[20] "And assuming Parliament agrees the draft framework tomorrow, Ministers will decide later in the week on advice from the national incident management team, and our chief advisors and in consultation with local councils, what levels will initially apply in what parts of the country from Monday November 2."
[21] "And I would remind you that in broad terms, the current restrictions in place in the central belt are equivalent to the proposed level three. And those in the rest of the country, broadly equivalent to level two. So for many places there may be no immediate change."
[22] "For an area to come down a level, we want to see a fall in the prevalence of the virus be sustained, not just seen on one or two days."
[23] "And that I think is important and giving business stability but also in giving people confidence that we are not going to take unnecessary risks when we start to lift restrictions."
[24] "So the next few days will see some important decisions which of course will have an impact on all of us."
[25] "I think it is important for context for all of us to remember, given how tough all of this is, that these decisions are one that Scotland is facing in common with countries across these islands, across Europe, and of course, across the world. Many countries are facing having to impose or re-impose tough restrictions, especially on hospitality, as a second wave of COVID takes hold."
[26] "The purpose of adopting tough restrictions just over two weeks ago here was to try to curb the increase in COVID cases that we were seeing before the virus ran further out of control."
[27] "The daily figures I have been reporting recently as I indicated on Friday suggest that these restrictions are starting to have an effect. We do think that the increase in case numbers is slowing but it's not yet in decline, which is why we can't be complacent, but we should take encouragement from the daily numbers at the moment because they suggest that the sacrifices that everybody is making are starting to work."
[28] "Once the new five levels approach is adopted and once people get more familiar with it, which I know will take a bit of time, I hope people will be better able to understand, on an ongoing basis the spread of COVID in their particular area, and also what measures are necessary to tackle it."
[29] "Hopefully that in turn will underline a key point. The best way of moving to a lower level of restrictions ā and of living more freely ā is to have a lower level of transmission. And the best way we have of driving transmission lower ā and keeping it low ā is for all of us to stick to the rules that are in place at any given time. That is of course a collective responsibility for all of us."
[30] "The second point I want to highlight is that two more walk-through testing sites have opened in the last few days."
[31] "On Thursday, a new site opened in the centre of Greenock in Inverclyde, and on Saturday, one opened at the Highland Council headquarters in Inverness."
[32] "That means that in total we have 11 walk-through testing sites now open to meet the needs of local communities across Scotland and to try to make access to testing easier for people."
[33] "I want to take this opportunity to thank everyone involved in setting up these sites and all those who are helping to run them."
[34] "This walk-through centres are only part of our testing infrastructure but they are an important way to make testing more accessible in Scotlandās towns and cities. So we will continue to work with partners ā including the UK Government - to establish more of them in the weeks and months ahead.."
[35] "It is possible to book a test at a walk-through site by going to the NHS Inform website. Please remember that though they are walk-through sites, you should seek to walk, cycle or drive to them, but do not use public transport to travel to any testing centre."
[36] "If you do not have a car - and cannot walk or cycle - please book a home testing kit through NHS Inform."
[37] "The reason for that, is to ensure you do not transmit the virus on the way to or from the testing centre."
[38] "I would remind everybody again that if you experience an of the symptoms of COVID it is really important to self-isolate immediately and take steps to get tested."
[39] "I want to end, as usual, by stressing the other key rules and guidelines."
[40] "If you live in Lothian, Lanarkshire, Forth Valley, Ayrshire and Arran and Greater Glasgow and Clyde, you should not travel outside those areas unless you have a clear need to do so."
[41] "People living in other parts of Scotland should not travel to these areas unless necessary."
[42] "None of us should be visiting each otherās homes just now, except for very specific purposes such as childcare or looking after a vulnerable person."
[43] "And when we do meet people from other households - outdoors, or at a cafƩ - the maximum group size is 6, from a maximum of two households."
[44] "Avoid car-sharing if you can. Work from home if you can. And remember to download the Protect Scotland app, if you havenāt already done so."
[45] "And finally, remember the FACTS ā the five rules which will help to remind you how to do the right thing."
[46] "If we all stick to these rules then hopefully the encouraging signs we are seeing in the figures that we are reporting every day will not just continue but accelerate, and a slowing of the increase over the weeks to come will become a decline in the number of daily new cases."
[47] "Thank you all very much."

A tibble with one row, because it is one speech, and six columns. The url is the input we started with.

Letās try another one, with the URL for the 23rd.
We saved over speech_page, then ran exactly the same code.
title <- speech_page |>
html_element(".ds_page-header__title") |>
html_text()
date <- speech_page |>
html_element("#sg-meta__publication-date") |>
html_text() |>
dmy()
location <- speech_page |>
html_element(".ds_metadata__item:last-child .ds_metadata__value") |>
html_text()
abstract <- speech_page |>
html_element("p.ds_leader") |>
html_text()
text <- speech_page |>
html_elements("#preamble p") |>
html_text() |>
list()This is getting tiringā¦

When youāve copied and pasted a block of code more than twice.
In the video, a search of the collection page for ācoronavirus covid-19ā found 142 hits. That is a lot of copying and pasting.

Assuming that the page structure is the same for each speech page, how many āthingsā do you need to know for each speech page to scrape the data we want from it?
url_23_oct <- "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-speech-23-october/"
speech_page <- read_html(url_23_oct)
title <- speech_page |>
html_element(".ds_page-header__title") |>
html_text()
date <- speech_page |>
html_element("#sg-meta__publication-date") |>
html_text() |>
dmy()
location <- speech_page |>
html_element(".ds_metadata__item:last-child .ds_metadata__value") |>
html_text()
abstract <- speech_page |>
html_element("p.ds_leader") |>
html_text()
text <- speech_page |>
html_elements("#preamble p") |>
html_text() |>
list()
tibble(
title = title, date = date, location = location,
abstract = abstract, text = text, url = url_23_oct
)Only one thing changes from page to page: the url. Everything else is exactly the same.
function. If we had more the call would look like function(x, y, z).function. If we had more the call would look like function(x, y, z).{ block that immediately follows function(...).scrape_speech()The argument url is used in only two places: to read the page, and to store in the output table.
scrape_speech <- function(url) {
speech_page <- read_html(url)
title <- speech_page |>
html_element(".ds_page-header__title") |>
html_text()
date <- speech_page |>
html_element("#sg-meta__publication-date") |>
html_text() |>
dmy()
location <- speech_page |>
html_element(".ds_metadata__item:last-child .ds_metadata__value") |>
html_text()
abstract <- speech_page |>
html_element("p.ds_leader") |>
html_text()
text <- speech_page |>
html_elements("#preamble p") |>
html_text() |>
list()
tibble(
title = title, date = date, location = location,
abstract = abstract, text = text, url = url
)
}The only thing that changed is the input.
Rows: 1
Columns: 6
$ title <chr> "Coronavirus (COVID-19) update: First Minister's spā¦
$ date <date> 2020-10-26
$ location <chr> "St Andrew's House, Edinburgh"
$ abstract <chr> "Statement given by First Minister Nicola Sturgeonā¦
$ text <list> <" Good afternoon, and thanks for joining us. I wanā¦
$ url <chr> "https://www.gov.scot/publications/coronavirus-coviā¦
Rows: 1
Columns: 6
$ title <chr> "Coronavirus (COVID-19) update: First Minister's spā¦
$ date <date> 2020-10-23
$ location <chr> "St Andrew's House, Edinburgh"
$ abstract <chr> "Statement given by First Minister Nicola Sturgeonā¦
$ text <list> <" Good afternoon everyone. Thank you very much forā¦
$ url <chr> "https://www.gov.scot/publications/coronavirus-coviā¦
Rows: 1
Columns: 6
$ title <chr> "Coronavirus (COVID-19) update: First Minister's spā¦
$ date <date> 2020-10-22
$ location <chr> "St Andrew's House, Edinburgh"
$ abstract <chr> "Statement given by First Minister Nicola Sturgeonā¦
$ text <list> <" Good afternoon, let me start as usual with the dā¦
$ url <chr> "https://www.gov.scot/publications/coronavirus-coviā¦
function. The code that says what to do with them goes in the curly braces.add_2() return?What is going on here?
The calculation happens, but the last thing in the function is 1000, so that is what comes back.
āThere are only two hard things in Computer Science: cache invalidation and naming things.ā - Phil Karlton
snake_case as opposed to camelCase)scrape_page(), scrape_speech() OR str_remove(), str_replace() etc.)We have a function that scrapes one speech, given its URL. Now we need a list of URLs.
# A tibble: 218 Ć 6
title date location abstract text url
<chr> <date> <chr> <chr> <chr> <chr>
1 Coronavirus (COVID-19) up⦠2021-04-20 St Andr⦠Stateme⦠"Goo⦠httpā¦
2 Coronavirus (COVID-19) up⦠2021-04-13 St Andr⦠Stateme⦠"Tha⦠httpā¦
3 Coronavirus (COVID-19) up⦠2021-04-06 St Andr⦠Stateme⦠"Goo⦠httpā¦
4 Coronavirus (COVID-19) up⦠2021-03-30 St Andr⦠Stateme⦠"Tha⦠httpā¦
5 Coronavirus (COVID-19) up⦠2021-03-24 Scottis⦠Stateme⦠"Tha⦠httpā¦
6 Coronavirus (Covid-19) up⦠2021-03-23 The Sco⦠Stateme⦠"Pre⦠httpā¦
7 Coronavirus (COVID-19) up⦠2021-03-18 Scottis⦠Stateme⦠"Tha⦠httpā¦
8 Coronavirus (COVID-19) up⦠2021-03-17 St Andr⦠Stateme⦠"\nG⦠httpā¦
9 Coronavirus (COVID-19) up⦠2021-03-16 Scottis⦠Stateme⦠"Pre⦠httpā¦
10 Coronavirus (COVID-19) up⦠2021-03-15 St Andr⦠Stateme⦠"\nG⦠httpā¦
11 Coronavirus (COVID-19) up⦠2021-03-11 Scottis⦠Stateme⦠"I c⦠httpā¦
12 Coronavirus (COVID-19) up⦠2021-03-09 Scottis⦠Stateme⦠"Pre⦠httpā¦
13 Coronavirus (COVID-19) up⦠2021-03-05 Scottis⦠Parliam⦠"Hel⦠httpā¦
14 Coronavirus (COVID-19) up⦠2021-03-04 Scottis⦠Parliam⦠"I w⦠httpā¦
15 Coronavirus (COVID-19) up⦠2021-03-02 Scottis⦠Stateme⦠"Pre⦠httpā¦
# ā¹ 203 more rows
scrape_speech()scrape_speech <- function(url) {
speech_page <- read_html(url)
title <- speech_page |>
html_element(".ds_page-header__title") |>
html_text()
date <- speech_page |>
html_element("#sg-meta__publication-date") |>
html_text() |>
dmy()
location <- speech_page |>
html_element(".ds_metadata__item:last-child .ds_metadata__value") |>
html_text()
abstract <- speech_page |>
html_element("p.ds_leader") |>
html_text()
text <- speech_page |>
html_elements("#preamble p") |>
html_text() |>
list()
tibble(
title = title, date = date, location = location,
abstract = abstract, text = text, url = url
)
}scrape_speech()# A tibble: 1 Ć 6
title date location abstract text url
<chr> <date> <chr> <chr> <lis> <chr>
1 Coronavirus (COVID-19) upd⦠2020-10-26 St Andr⦠Stateme⦠<chr> httpā¦
# A tibble: 1 Ć 6
title date location abstract text url
<chr> <date> <chr> <chr> <lis> <chr>
1 Coronavirus (COVID-19) upd⦠2020-10-23 St Andr⦠Stateme⦠<chr> httpā¦
You now have a function that will scrape the relevant info on speeches given the URL of the page of the speech. Where can we get a list of URLs of each of the speeches?
So far we have clicked on these links by hand. We want to pull the URLs hidden under the links out of the page source.
Read the page that lists all the speeches, then grab the elements that hold the links.
This time we do not want the text. We want an attribute of the element: href, the hyperlink reference, which is where the URL is saved in the HTML.
[1] "/publications/the-roles-and-functions-of-scotlands-law-officers-first-ministers-statement/"
[2] "/publications/preventing-violence-against-women-for-an-equally-safe-scotland-first-ministers-speech/"
[3] "/publications/programme-for-government-2026-to-2031-first-ministers-speech/"
[4] "/publications/welcome-to-scotland-reception-first-ministers-speech-21-july/"
[5] "/publications/quality-meat-scotland-breakfast-first-ministers-speech-18-june-2026/"
[6] "/publications/prosper-forum-first-ministers-speech-4-june-2026/"
[7] "/publications/ambitious-for-scotland-first-ministers-speech/"
[8] "/publications/cbi-annual-lunch-first-ministers-speech-22-may-2026/"
[9] "/publications/first-minister-nomination-acceptance-speech/"
[10] "/publications/eradicating-child-poverty-first-ministers-speech/"
These are relative links, so the start of the address is missing. The speeches we want all have covid-19 in the address. str_subset() keeps only the strings that contain a pattern. It is like filter(), but for a vector.
[1] "/publications/coronavirus-covid-19-update-first-ministers-speech-tuesday-22-february-2022/"
[2] "/publications/coronavirus-covid-19-update-first-ministers-statement-8-february-2022/"
[3] "/publications/coronavirus-covid-19-update-first-ministers-statement-1-february-2022/"
[4] "/publications/coronavirus-covid-19-update-first-ministers-statement-25-january-2022/"
[5] "/publications/coronavirus-covid-19-update-first-ministers-statement-18-january-2022/"
[6] "/publications/coronavirus-covid-19-update-first-ministers-statement-11-january-2022/"
[7] "/publications/coronavirus-covid-19-update-first-ministers-statement-5-january-2022/"
[8] "/publications/coronavirus-covid-19-update-first-ministers-statement-21-december-2021/"
[9] "/publications/coronavirus-covid-19-update-first-ministers-speech-17-december-2021/"
[10] "/publications/coronavirus-covid-19-update-first-ministers-statement-14-december-2021/"
We still need the beginning of each address. url_absolute() adds the siteās address to each relative link.
The video builds the full address with str_c() and the . placeholder. The native pipe |> does not have the ., so we use url_absolute() instead.
[1] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-speech-tuesday-22-february-2022/"
[2] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-8-february-2022/"
[3] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-1-february-2022/"
[4] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-25-january-2022/"
[5] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-18-january-2022/"
[6] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-11-january-2022/"
[7] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-5-january-2022/"
[8] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-21-december-2021/"
[9] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-speech-17-december-2021/"
[10] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-14-december-2021/"
We will use covid_speech_urls for the rest of the lesson.
[1] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-speech-tuesday-22-february-2022/"
[2] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-8-february-2022/"
[3] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-1-february-2022/"
[4] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-25-january-2022/"
[5] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-18-january-2022/"
[6] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-11-january-2022/"
[7] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-5-january-2022/"
[8] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-21-december-2021/"
[9] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-speech-17-december-2021/"
[10] "https://www.gov.scot/publications/coronavirus-covid-19-update-first-ministers-statement-14-december-2021/"
scrape_speech() function on all COVID-19 speech linksHow can we tell R to apply the scrape_speech() function to each link in covid_speech_urls?
Option 1: Write a for loop, i.e. explicitly tell R to visit a link, apply the function, store the result, then visit the next link, apply the function, append the result to the stored result from the previous link, and so on and so forth.
Option 2: Map the function to each element in the list of links, and let R take care of the storing and appending of results.
Suppose we have exam 1 and exam 2 scores of 4 students stored in a listā¦
ā¦and we find the mean score in each exam. The first argument is what we map over, and the second is the function.
map_somethingā¦and suppose we want the results as a numeric (double) vector
ā¦or as a character string
map_something variantsFunctions for looping over an object and returning a value (of a specific type):
map() - returns a listmap_lgl() - returns a logical vectormap_int() - returns a integer vectormap_dbl() - returns a double vectormap_chr() - returns a character vectormap_df() / map_dfr() - return a data frame by row binding. These are superseded: use map() followed by list_rbind().map_dfc() - returns a data frame by column binding. Superseded: use map() followed by list_cbind().scrape_speech() functioncovid_speech_urlsSave the result, because this takes a while to run.
# A tibble: 218 Ć 6
title date location abstract text url
<chr> <date> <chr> <chr> <chr> <chr>
1 Coronavirus (COVID-19) up⦠2021-04-20 St Andr⦠Stateme⦠"Goo⦠httpā¦
2 Coronavirus (COVID-19) up⦠2021-04-13 St Andr⦠Stateme⦠"Tha⦠httpā¦
3 Coronavirus (COVID-19) up⦠2021-04-06 St Andr⦠Stateme⦠"Goo⦠httpā¦
4 Coronavirus (COVID-19) up⦠2021-03-30 St Andr⦠Stateme⦠"Tha⦠httpā¦
5 Coronavirus (COVID-19) up⦠2021-03-24 Scottis⦠Stateme⦠"Tha⦠httpā¦
6 Coronavirus (Covid-19) up⦠2021-03-23 The Sco⦠Stateme⦠"Pre⦠httpā¦
7 Coronavirus (COVID-19) up⦠2021-03-18 Scottis⦠Stateme⦠"Tha⦠httpā¦
8 Coronavirus (COVID-19) up⦠2021-03-17 St Andr⦠Stateme⦠"\nG⦠httpā¦
9 Coronavirus (COVID-19) up⦠2021-03-16 Scottis⦠Stateme⦠"Pre⦠httpā¦
10 Coronavirus (COVID-19) up⦠2021-03-15 St Andr⦠Stateme⦠"\nG⦠httpā¦
11 Coronavirus (COVID-19) up⦠2021-03-11 Scottis⦠Stateme⦠"I c⦠httpā¦
12 Coronavirus (COVID-19) up⦠2021-03-09 Scottis⦠Stateme⦠"Pre⦠httpā¦
13 Coronavirus (COVID-19) up⦠2021-03-05 Scottis⦠Parliam⦠"Hel⦠httpā¦
14 Coronavirus (COVID-19) up⦠2021-03-04 Scottis⦠Parliam⦠"I w⦠httpā¦
15 Coronavirus (COVID-19) up⦠2021-03-02 Scottis⦠Stateme⦠"Pre⦠httpā¦
# ā¹ 203 more rows
HTTP Error 429 (Too many requests) the server is telling you to slow down. Modify your function to add a random wait (sleep) time between hitting each link.This is a way of being nice to the server. In AE08 we pause between every request from the start, not only after an error. The polite package is a more principled way to do it.
Note
This page adapts material from Data Science in a Box (Unit 2, Decks 21 and 22: āFunctionsā and āIterationā) by Mine Ćetinkaya-Rundel, licensed under CC BY-SA 4.0. Source: tidyverse/datascience-box and tidyverse/datascience-box. Modified: combined the two decks and converted them from xaringan to Quarto revealjs; updated the gov.scot selectors for the redesigned site and run the examples on saved copies of the pages; replaced %>%, html_node(), html_nodes() and map_dfr() with |>, html_element(), html_elements() and map() followed by list_rbind(); replaced str_c() with the . placeholder with url_absolute(); dropped the unused DT package and the library(lubridate) call; named the elements of the exam_scores list.