1
00:00:00,180 --> 00:00:02,460
Instructor: Now that we've seen how we can get started

2
00:00:02,460 --> 00:00:06,510
using Selenium WebDriver to automate our browser,

3
00:00:06,510 --> 00:00:10,380
the next step is to figure out how to use Selenium to find

4
00:00:10,380 --> 00:00:14,973
and locate specific HTML elements on the webpage.

5
00:00:16,170 --> 00:00:19,170
Just between where we quit our driver

6
00:00:19,170 --> 00:00:22,350
and where we get hold of a particular page,

7
00:00:22,350 --> 00:00:24,840
I'm gonna show you how easy it is to complete

8
00:00:24,840 --> 00:00:29,840
the previous task in day 47 where we tried to get hold

9
00:00:30,300 --> 00:00:33,843
of the price of a particular item on amazon.com.

10
00:00:34,950 --> 00:00:37,050
This was the item that we were interested in.

11
00:00:37,050 --> 00:00:40,470
This was the Instant Pot, and this is the price.

12
00:00:40,470 --> 00:00:43,200
So if I go ahead and take this URL

13
00:00:43,200 --> 00:00:48,060
and replace this previous just amazon.com URL

14
00:00:48,060 --> 00:00:51,090
with the URL that takes us to this page,

15
00:00:51,090 --> 00:00:55,590
then we can start inspecting on this particular element.

16
00:00:55,590 --> 00:00:58,590
Now, if we take a look at the HTML,

17
00:00:58,590 --> 00:01:01,830
we can see that we've got the price showing.

18
00:01:01,830 --> 00:01:03,690
And at the time of recording,

19
00:01:03,690 --> 00:01:07,200
the price is split into two parts.

20
00:01:07,200 --> 00:01:11,160
So you've got a class called a-price-whole

21
00:01:11,160 --> 00:01:13,230
which is the number of dollars

22
00:01:13,230 --> 00:01:18,230
and a class called a-price-fraction, which are the cents.

23
00:01:18,840 --> 00:01:23,070
So Amazon can obviously change their website at any time.

24
00:01:23,070 --> 00:01:24,690
Previously, for example, the price

25
00:01:24,690 --> 00:01:29,690
used to be inside an element with the ID price block price.

26
00:01:30,150 --> 00:01:33,840
So you have to look inside which element the price is in

27
00:01:33,840 --> 00:01:36,690
by right-clicking inspect element

28
00:01:36,690 --> 00:01:40,804
and then checking to see what the ID is called

29
00:01:40,804 --> 00:01:44,130
because Amazon can change this set any time.

30
00:01:44,130 --> 00:01:45,660
Now, once you've noted down

31
00:01:45,660 --> 00:01:49,500
if you want a particular class or a particular ID,

32
00:01:49,500 --> 00:01:53,730
take a look at the Selenium locator strategies.

33
00:01:53,730 --> 00:01:56,370
You can see here in the Selenium Docs,

34
00:01:56,370 --> 00:01:59,820
there's many ways that we can find different elements

35
00:01:59,820 --> 00:02:02,160
on a page Using Selenium.

36
00:02:02,160 --> 00:02:04,110
You can see that Selenium provides support

37
00:02:04,110 --> 00:02:07,110
for these eight traditional location strategies.

38
00:02:07,110 --> 00:02:09,389
In our case, we're looking for the price element

39
00:02:09,389 --> 00:02:14,250
on Amazon's page by selecting on a particular class name.

40
00:02:14,250 --> 00:02:15,900
Now the Selenium docs are pretty good

41
00:02:15,900 --> 00:02:18,120
and include handy little code snippets

42
00:02:18,120 --> 00:02:19,740
for everything you wanna do.

43
00:02:19,740 --> 00:02:22,770
So for example here, you can see how to find an element

44
00:02:22,770 --> 00:02:27,300
by class name, and that's exactly what we need to do.

45
00:02:27,300 --> 00:02:31,230
And you can do that by using the find_element method.

46
00:02:31,230 --> 00:02:34,080
Depending on whether if you're looking to find an element

47
00:02:34,080 --> 00:02:39,080
by class name or by ID, we need to use a class called by.

48
00:02:39,420 --> 00:02:43,800
And it has helpers such as by.class_name.

49
00:02:43,800 --> 00:02:45,990
And then all we need to do is just to specify

50
00:02:45,990 --> 00:02:49,500
the name of the class that we're interested in finding.

51
00:02:49,500 --> 00:02:54,500
So the first thing I'll do is to import the by class

52
00:02:54,630 --> 00:02:59,630
and that's just from selenium.webdriver.com.common.by.

53
00:03:00,720 --> 00:03:02,253
And then import_By.

54
00:03:04,110 --> 00:03:07,770
And then we can create a variable called price_dollar

55
00:03:07,770 --> 00:03:10,140
to hold onto the dollar price element

56
00:03:10,140 --> 00:03:11,553
from the Amazon page.

57
00:03:16,260 --> 00:03:19,200
The value, we'll grab the class name of the span

58
00:03:19,200 --> 00:03:20,790
from the Amazon page.

59
00:03:20,790 --> 00:03:23,940
So the class is called a-price-whole

60
00:03:23,940 --> 00:03:26,880
and we're gonna paste it into our code.

61
00:03:26,880 --> 00:03:29,610
And it's probably easier just so you don't make any typos

62
00:03:29,610 --> 00:03:31,440
to just copy the name of that class

63
00:03:31,440 --> 00:03:33,033
and paste it into our code.

64
00:03:33,900 --> 00:03:35,340
Next, let's do the same thing

65
00:03:35,340 --> 00:03:38,133
for the second part of the price, the cents on the dollar.

66
00:03:38,133 --> 00:03:41,850
So we'll create a variable called price_cents

67
00:03:41,850 --> 00:03:46,470
and we'll use driver.find_element by.class_name

68
00:03:46,470 --> 00:03:49,200
and then set the class name value to equal

69
00:03:49,200 --> 00:03:51,723
to a-price-fraction.

70
00:03:53,220 --> 00:03:54,840
Again, these things can change.

71
00:03:54,840 --> 00:03:56,963
At the time of recording, it's called a-price-fraction

72
00:03:56,963 --> 00:04:01,020
but be sure to check what the live situation is

73
00:04:01,020 --> 00:04:02,823
when you are doing this exercise.

74
00:04:03,750 --> 00:04:07,620
Now let's print out the full price as an F string.

75
00:04:07,620 --> 00:04:11,520
We'll write print f, and then the price is,

76
00:04:11,520 --> 00:04:13,413
and we'll insert the price dollar,

77
00:04:16,920 --> 00:04:19,353
dot, and then the price_cents.

78
00:04:22,230 --> 00:04:24,060
Now what's gonna happen here

79
00:04:24,060 --> 00:04:28,320
if you try to run this code is we've actually found

80
00:04:28,320 --> 00:04:31,560
the element by class_name, but right now,

81
00:04:31,560 --> 00:04:35,280
price_dollar and price-cent are actually an HTML element.

82
00:04:35,280 --> 00:04:39,660
So if we want to have the text that's inside those elements,

83
00:04:39,660 --> 00:04:42,270
we have to access the text content.

84
00:04:42,270 --> 00:04:44,580
And you can see here in the Selenium Docs,

85
00:04:44,580 --> 00:04:46,620
to get the text content,

86
00:04:46,620 --> 00:04:49,860
all we need to do is just write .text

87
00:04:49,860 --> 00:04:52,140
after we found the element.

88
00:04:52,140 --> 00:04:56,820
So we can add dot text to the price_dollar and price_cent.

89
00:04:56,820 --> 00:04:59,280
So now we can actually get hold

90
00:04:59,280 --> 00:05:03,060
of the content that's inside those HTML elements.

91
00:05:03,060 --> 00:05:06,960
Now all we need to do is uncomment our driver.quit

92
00:05:06,960 --> 00:05:08,880
because otherwise, we're gonna have a new instance

93
00:05:08,880 --> 00:05:11,380
of Chrome running every time I hit the run button.

94
00:05:12,360 --> 00:05:16,980
And now if I hit run, you'll see our browser open up briefly

95
00:05:16,980 --> 00:05:19,719
to the page with the Instant Pot, and then it'll close down

96
00:05:19,719 --> 00:05:23,520
and you can see the price printed right here.

97
00:05:23,520 --> 00:05:27,840
Now the reason why this is so much shorter than what you did

98
00:05:27,840 --> 00:05:31,950
in the last project is because we're driving a browser.

99
00:05:31,950 --> 00:05:35,310
So the browser's ready, sending all of those headers,

100
00:05:35,310 --> 00:05:38,550
all of the information that Amazon would expect

101
00:05:38,550 --> 00:05:43,500
from a actual user, instead of using a get request

102
00:05:43,500 --> 00:05:45,750
using the request package.

103
00:05:45,750 --> 00:05:47,550
In only three lines,

104
00:05:47,550 --> 00:05:51,570
we can do so much more than we could do with BeautifulSoup.

105
00:05:51,570 --> 00:05:53,190
Essentially, if you think about it

106
00:05:53,190 --> 00:05:56,730
BeautifulSoup was really good for just grabbing

107
00:05:56,730 --> 00:06:00,720
and scraping pieces of data from an HTML website

108
00:06:00,720 --> 00:06:03,567
but it gets stuck when that website is being rendered

109
00:06:03,567 --> 00:06:07,200
using JavaScript or Angular or React

110
00:06:07,200 --> 00:06:12,200
and the content that was HTML was taking time to load

111
00:06:13,680 --> 00:06:18,120
or it requires certain conditions to load.

112
00:06:18,120 --> 00:06:19,260
Whereas in this case,

113
00:06:19,260 --> 00:06:22,470
we're effectively doing exactly the same thing

114
00:06:22,470 --> 00:06:24,570
as we would as a human.

115
00:06:24,570 --> 00:06:26,580
Going to this particular URL

116
00:06:26,580 --> 00:06:30,430
and then looking at this element and its value

117
00:06:31,740 --> 00:06:33,120
I wanted to show you a couple

118
00:06:33,120 --> 00:06:36,210
of other ways that you could find elements.

119
00:06:36,210 --> 00:06:38,550
You can see there's a whole bunch of ways

120
00:06:38,550 --> 00:06:41,970
of finding elements and there's a lot more methods

121
00:06:41,970 --> 00:06:44,790
than you have with BeautifulSoup.

122
00:06:44,790 --> 00:06:47,760
One that I wanna show you that's quite useful

123
00:06:47,760 --> 00:06:50,580
is find element by name.

124
00:06:50,580 --> 00:06:54,000
If we go to python.org, you'll remember

125
00:06:54,000 --> 00:06:56,850
from your lessons on HTML and CSS

126
00:06:56,850 --> 00:06:59,880
that most forms, these input forms

127
00:06:59,880 --> 00:07:02,850
will have a name attribute.

128
00:07:02,850 --> 00:07:06,180
So if I go ahead and inspect on this search bar,

129
00:07:06,180 --> 00:07:08,617
you can see it's got an ID, it's got a name,

130
00:07:08,617 --> 00:07:10,987
it's got a type, it's got a role, it's got a class

131
00:07:10,987 --> 00:07:13,620
it's got a whole bunch of attributes.

132
00:07:13,620 --> 00:07:17,493
Now I'm gonna search for it by this name, which is Q.

133
00:07:19,410 --> 00:07:23,790
So all I need to do here is call the find_element method.

134
00:07:23,790 --> 00:07:26,220
And for our by helper class,

135
00:07:26,220 --> 00:07:29,310
I specify that I want to search by name.

136
00:07:29,310 --> 00:07:31,560
So the name of the element

137
00:07:31,560 --> 00:07:35,943
and then I provide the name of the search bar, which is Q.

138
00:07:38,160 --> 00:07:41,010
Now of course, I'll have to change this URL

139
00:07:41,010 --> 00:07:43,743
to actually python.org.

140
00:07:45,060 --> 00:07:49,320
And now, once we've found our element by name,

141
00:07:49,320 --> 00:07:51,273
we'll call it the search bar.

142
00:07:54,240 --> 00:07:58,053
And then we'll go ahead and print out this search bar.

143
00:08:00,600 --> 00:08:02,010
And then we'll comment out our code

144
00:08:02,010 --> 00:08:04,653
that we used for Amazon and then hit run.

145
00:08:06,330 --> 00:08:09,270
When Selenium locates a particular element,

146
00:08:09,270 --> 00:08:12,660
it won't actually print out the actual HTML.

147
00:08:12,660 --> 00:08:17,370
It'll give it to you as a selenium element like this.

148
00:08:17,370 --> 00:08:18,420
Now if you wanna tap

149
00:08:18,420 --> 00:08:23,420
into its various attributes or text or tag name,

150
00:08:23,520 --> 00:08:26,790
then you'll actually have to do that using a dot.

151
00:08:26,790 --> 00:08:29,310
So we can say search_bar.tag_name

152
00:08:29,310 --> 00:08:34,309
and it will give us that that is an input tag.

153
00:08:34,350 --> 00:08:36,520
Or we could say search_bar.get_attribute

154
00:08:37,830 --> 00:08:41,789
and we can specify the attribute that we want the value for.

155
00:08:41,789 --> 00:08:42,690
So for example,

156
00:08:42,690 --> 00:08:45,630
if I wanted to know what the placeholder value was,

157
00:08:45,630 --> 00:08:49,320
then all I have to do is put get_attribute placeholder

158
00:08:49,320 --> 00:08:51,240
and then we can print that out

159
00:08:51,240 --> 00:08:55,110
and it will tell us that the placeholder says search.

160
00:08:55,110 --> 00:08:57,990
So that is something that you'll find people commonly use

161
00:08:57,990 --> 00:09:00,450
with Selenium find element by name.

162
00:09:00,450 --> 00:09:04,290
And it's really useful when it comes to filling in web forms

163
00:09:04,290 --> 00:09:08,010
because most forms will have elements that are organized

164
00:09:08,010 --> 00:09:10,920
by name because when the form is submitted,

165
00:09:10,920 --> 00:09:15,423
that name is carried along with the value of the inputs.

166
00:09:16,800 --> 00:09:19,980
In addition to find element by name and class name,

167
00:09:19,980 --> 00:09:22,620
you can of course find an element by id.

168
00:09:22,620 --> 00:09:24,630
So for example, the submit button

169
00:09:24,630 --> 00:09:28,421
next to the search bar has the ID of submit.

170
00:09:28,421 --> 00:09:31,500
And once again, we need to use the find element method

171
00:09:31,500 --> 00:09:32,850
but this time, we specify

172
00:09:32,850 --> 00:09:35,913
that we wanna find the element by ID.

173
00:09:36,810 --> 00:09:40,653
And we can add in the value of the ID, which is submit.

174
00:09:41,970 --> 00:09:43,530
So the code looks like this.

175
00:09:43,530 --> 00:09:47,880
Button equals driver.find_element by.id

176
00:09:47,880 --> 00:09:52,560
and then we insert the value of that ID, which is submit.

177
00:09:52,560 --> 00:09:54,960
And similar to before, once we've found the element,

178
00:09:54,960 --> 00:09:57,090
we can get hold of various properties.

179
00:09:57,090 --> 00:10:00,360
For example, we can even print out the size of the element.

180
00:10:00,360 --> 00:10:01,530
Let's see what it is.

181
00:10:01,530 --> 00:10:05,010
Let's go ahead and print button that we found that element

182
00:10:05,010 --> 00:10:08,280
and then we use .size to see what's its height.

183
00:10:08,280 --> 00:10:09,870
And if we print it out, we can see

184
00:10:09,870 --> 00:10:13,950
that it has a height of 40 and a width of 46.

185
00:10:13,950 --> 00:10:16,740
So Selenium is really powerful

186
00:10:16,740 --> 00:10:20,940
and the ability to use their helper methods to find element

187
00:10:20,940 --> 00:10:25,200
by ID name or class name allows us to pretty much reach

188
00:10:25,200 --> 00:10:29,130
into any website and get hold of any element that we want.

189
00:10:29,130 --> 00:10:30,990
And then by using these properties

190
00:10:30,990 --> 00:10:34,770
such as .size or .text, we can access whichever parts

191
00:10:34,770 --> 00:10:36,543
of the element we're interested in.

192
00:10:38,670 --> 00:10:41,160
So you can see that we can do a lot more

193
00:10:41,160 --> 00:10:44,043
with Selenium than we could with BeautifulSoup.

194
00:10:45,600 --> 00:10:50,013
So that's find_element by ID, by name, by class name.

195
00:10:50,910 --> 00:10:55,910
But there's also of course, find_element by CSS selector.

196
00:10:56,190 --> 00:10:58,620
And this is probably one of the easiest ways

197
00:10:58,620 --> 00:11:01,353
of narrowing down on a particular element.

198
00:11:02,520 --> 00:11:04,050
Let's say that I wanted to get hold

199
00:11:04,050 --> 00:11:06,390
of this link to the docks.

200
00:11:06,390 --> 00:11:07,950
Let's go ahead and inspect it

201
00:11:07,950 --> 00:11:10,410
and it lives inside an anchor tack.

202
00:11:10,410 --> 00:11:12,900
But you can see that this anchor tag has no class,

203
00:11:12,900 --> 00:11:17,370
it has no ID, has no easy way of identification.

204
00:11:17,370 --> 00:11:19,200
So how do we get hold of it?

205
00:11:19,200 --> 00:11:22,860
Well, we can see that it lives in a paragraph element.

206
00:11:22,860 --> 00:11:24,090
And then going further up,

207
00:11:24,090 --> 00:11:27,930
it's inside a div with this particular class.

208
00:11:27,930 --> 00:11:31,680
So this has a class of documentation widget.

209
00:11:31,680 --> 00:11:33,270
So that's pretty specific.

210
00:11:33,270 --> 00:11:34,650
So if we wanted to get hold

211
00:11:34,650 --> 00:11:36,900
of that anchor tag, we could just say,

212
00:11:36,900 --> 00:11:41,010
well inside this div of documentation widget,

213
00:11:41,010 --> 00:11:43,593
let's go ahead and find any anchor tags.

214
00:11:44,460 --> 00:11:47,280
And to express that as a CSS selector

215
00:11:47,280 --> 00:11:50,460
we would specify the class documentation widget.

216
00:11:50,460 --> 00:11:52,830
And then inside the element with that class,

217
00:11:52,830 --> 00:11:55,110
we're looking for an anchor tag.

218
00:11:55,110 --> 00:11:59,013
So this would get us our documentation link.

219
00:12:00,510 --> 00:12:01,890
And now if I go ahead

220
00:12:01,890 --> 00:12:06,750
and print the documentation link .text, you can see

221
00:12:06,750 --> 00:12:11,750
that it's actually getting hold of this particular link.

222
00:12:12,480 --> 00:12:14,760
And this is done even though the actual link

223
00:12:14,760 --> 00:12:19,760
doesn't have any easily identifiable name or class or ID.

224
00:12:21,450 --> 00:12:24,870
Now, on a similar vein, sometimes it's extremely

225
00:12:24,870 --> 00:12:28,980
hard to even find an element even by CSS selector.

226
00:12:28,980 --> 00:12:30,810
So if all else fails,

227
00:12:30,810 --> 00:12:34,410
one that will always work is the XPath.

228
00:12:34,410 --> 00:12:39,410
The XPath is a way of locating a specific HTML element

229
00:12:40,080 --> 00:12:42,420
by a path structure.

230
00:12:42,420 --> 00:12:45,210
So you've seen what paths look like, right?

231
00:12:45,210 --> 00:12:47,966
Users/angela/development, etc.

232
00:12:47,966 --> 00:12:51,480
Well, we can also express the navigation

233
00:12:51,480 --> 00:12:55,380
to a particular element, drilling down from the top

234
00:12:55,380 --> 00:12:59,253
of the tree to a particular node using the XPath.

235
00:13:00,240 --> 00:13:01,620
Let's say I want to get hold

236
00:13:01,620 --> 00:13:04,500
of this link at the bottom, Submit Website Bug.

237
00:13:04,500 --> 00:13:06,900
So let's go ahead and inspect on it.

238
00:13:06,900 --> 00:13:10,230
And you can see it's not particularly unique

239
00:13:10,230 --> 00:13:14,490
in terms of having an ID or a class or a name.

240
00:13:14,490 --> 00:13:17,010
And even in terms of its structure.

241
00:13:17,010 --> 00:13:20,133
It's sort of in this ul and then in li.

242
00:13:20,970 --> 00:13:23,970
And it might not be that easy to get to it.

243
00:13:23,970 --> 00:13:27,150
But here's where our XPath comes in handy.

244
00:13:27,150 --> 00:13:28,448
Let's go ahead and right-click on it

245
00:13:28,448 --> 00:13:31,533
and then go to copy copy XPath.

246
00:13:32,520 --> 00:13:34,170
And now, we can go back

247
00:13:34,170 --> 00:13:38,520
to our code and use it to tap into that element.

248
00:13:38,520 --> 00:13:40,020
So we'll say driver

249
00:13:40,020 --> 00:13:42,757
and then we'll say find_element by.XPath.

250
00:13:43,710 --> 00:13:46,653
And then inside here, we're going to paste our XPath.

251
00:13:49,140 --> 00:13:51,570
Now, notice that the XPath itself

252
00:13:51,570 --> 00:13:53,910
actually has some double quotes.

253
00:13:53,910 --> 00:13:57,780
So we have to change our double quotes into single quotes

254
00:13:57,780 --> 00:14:01,800
so that it doesn't clash with the inner double quotes.

255
00:14:01,800 --> 00:14:03,240
So like this.

256
00:14:03,240 --> 00:14:06,270
Now, once we found our bug link,

257
00:14:06,270 --> 00:14:09,843
then we're going to print out the link,

258
00:14:10,770 --> 00:14:14,073
and I'm going to get hold of the href here.

259
00:14:15,030 --> 00:14:18,540
So now I'm gonna print my bug_link.text

260
00:14:18,540 --> 00:14:20,610
just to prove that this worked.

261
00:14:20,610 --> 00:14:23,430
And if I hit run, you can see it opens up

262
00:14:23,430 --> 00:14:26,730
our browser and you can see it's managed to get hold

263
00:14:26,730 --> 00:14:31,650
of that particular link using this very specific Xpath,

264
00:14:31,650 --> 00:14:33,360
which looks very much

265
00:14:33,360 --> 00:14:36,510
like a file path that we've been using.

266
00:14:36,510 --> 00:14:40,440
But it's essentially the way that we would navigate down

267
00:14:40,440 --> 00:14:43,080
through the divs, the uls, the lis,

268
00:14:43,080 --> 00:14:46,113
all the way down to that particular anchor tag.

269
00:14:47,190 --> 00:14:49,500
And the best part of all is of course,

270
00:14:49,500 --> 00:14:54,500
you can use this button here in Chrome to locate any element

271
00:14:54,630 --> 00:14:57,810
and then that would select its location in the code

272
00:14:57,810 --> 00:14:59,250
and then you can right-click

273
00:14:59,250 --> 00:15:02,100
and then copy its XPath to get hold

274
00:15:02,100 --> 00:15:04,053
of that particular thing.

275
00:15:05,430 --> 00:15:06,300
Now I'm gonna link

276
00:15:06,300 --> 00:15:10,920
to the documentation on XPath from W3 schools.

277
00:15:10,920 --> 00:15:13,080
It goes into a little bit more detail

278
00:15:13,080 --> 00:15:15,870
about how XPaths are constructed

279
00:15:15,870 --> 00:15:19,050
but you don't need to know this in order to work with them.

280
00:15:19,050 --> 00:15:22,770
As I've shown, you can simply use the Chrome developer tools

281
00:15:22,770 --> 00:15:24,090
and it will help you get

282
00:15:24,090 --> 00:15:27,063
to the particular item you're interested in.

283
00:15:28,860 --> 00:15:33,860
Now, we've been looking at finding elements using Selenium

284
00:15:33,960 --> 00:15:35,910
but notice how we've always stuck

285
00:15:35,910 --> 00:15:40,910
to the singular version of that method, find_element.

286
00:15:40,920 --> 00:15:43,702
Now, for every single method that I've shown you,

287
00:15:43,702 --> 00:15:48,702
there's also a counterpart, which is the find_elements.

288
00:15:48,810 --> 00:15:52,770
So for example, find_elements by.CSS_selector.

289
00:15:52,770 --> 00:15:55,500
And of course, this is just going to find you everything

290
00:15:55,500 --> 00:15:58,020
on the screen that matches your criteria

291
00:15:58,020 --> 00:16:00,000
and give it to you in a list.

292
00:16:00,000 --> 00:16:01,966
And there is a version of this

293
00:16:01,966 --> 00:16:06,960
for every single find method that we've shown so far.

294
00:16:06,960 --> 00:16:10,470
In the next lesson, I've got a quick challenge for you

295
00:16:10,470 --> 00:16:12,870
to put into practice what you've learned

296
00:16:12,870 --> 00:16:17,340
and to be able to locate any given element on a webpage.

297
00:16:17,340 --> 00:16:19,380
So for all of that and more,

298
00:16:19,380 --> 00:16:20,980
I'll see you on the next lesson.

