WEBVTT

1
00:00:00.160 --> 00:00:02.640
<v Speaker 1>Imagine it is, I don't know, like four point five

2
00:00:02.720 --> 00:00:04.559
<v Speaker 1>to five pm on a Friday.

3
00:00:04.240 --> 00:00:06.440
<v Speaker 2>The worst possible time, right.

4
00:00:06.360 --> 00:00:10.119
<v Speaker 1>At the absolute worst, and your boss drops by your

5
00:00:10.119 --> 00:00:14.359
<v Speaker 1>desk and hands you what sounds like an incredibly simple assignment.

6
00:00:14.359 --> 00:00:16.440
<v Speaker 1>They're like, hey, I need you to go to the

7
00:00:16.519 --> 00:00:20.640
<v Speaker 1>Yahoo Finance technology page and just pull the data for

8
00:00:20.879 --> 00:00:23.719
<v Speaker 1>every single tech stock listed in their main table.

9
00:00:23.879 --> 00:00:26.559
<v Speaker 3>It is a quick favor before the weekend, exactly.

10
00:00:26.640 --> 00:00:30.160
<v Speaker 1>And for every single company you need to grab four

11
00:00:30.199 --> 00:00:32.840
<v Speaker 1>specific things. You need the company name, the intra day

12
00:00:32.880 --> 00:00:36.039
<v Speaker 1>stock price, the stock symbol, and then the actual URL

13
00:00:36.079 --> 00:00:37.960
<v Speaker 1>that links to the company's full profile.

14
00:00:38.679 --> 00:00:40.600
<v Speaker 2>I mean, on the surface, that sounds like a five

15
00:00:40.600 --> 00:00:43.479
<v Speaker 2>minute task. You know, you open a spreadsheet, you open

16
00:00:43.520 --> 00:00:45.000
<v Speaker 2>your web browser, and you just get to.

17
00:00:44.960 --> 00:00:47.960
<v Speaker 1>Work, right, But then reality actually sets in because you're

18
00:00:48.039 --> 00:00:50.920
<v Speaker 1>highlighting the first company's name, you're hitting copy, tabbing over

19
00:00:50.920 --> 00:00:53.920
<v Speaker 1>to your spreadsheet, hitting paste. Yeah, then you're tabbing back

20
00:00:54.240 --> 00:00:56.799
<v Speaker 1>highlighting the price, copy tab paste, And you know, doing

21
00:00:56.880 --> 00:00:59.320
<v Speaker 1>that for one company is completely fine, but doing it

22
00:00:59.359 --> 00:01:03.479
<v Speaker 1>for a company, well, it's brutal. You are making hundreds

23
00:01:03.560 --> 00:01:07.719
<v Speaker 1>of highly repetitive, like precision clicks, Your risk starts aching,

24
00:01:07.799 --> 00:01:10.840
<v Speaker 1>your eyes are completely glazing over, and inevitably you start

25
00:01:10.840 --> 00:01:13.959
<v Speaker 1>making mistakes. You paste a price into the symbol column

26
00:01:14.000 --> 00:01:15.000
<v Speaker 1>by accident.

27
00:01:14.719 --> 00:01:16.640
<v Speaker 2>Which throws off the whole sheet exactly.

28
00:01:16.680 --> 00:01:20.120
<v Speaker 1>It is the kind of mind numbing, soul crushing manual

29
00:01:20.280 --> 00:01:23.640
<v Speaker 1>data entry that really makes you question your career choices.

30
00:01:23.799 --> 00:01:27.439
<v Speaker 2>It really does. But you know, humans are just fundamentally

31
00:01:28.040 --> 00:01:33.040
<v Speaker 2>unsuited for repetitive, high precision tasks over long durations. We

32
00:01:33.200 --> 00:01:36.560
<v Speaker 2>just lose focus. Computers however, I mean they thrive on

33
00:01:36.640 --> 00:01:37.680
<v Speaker 2>that exact type of work.

34
00:01:37.719 --> 00:01:39.480
<v Speaker 1>You don't get bored, No, not at all.

35
00:01:39.799 --> 00:01:43.439
<v Speaker 2>And this is the precise friction point where programming becomes

36
00:01:43.640 --> 00:01:45.120
<v Speaker 2>frankly practically.

37
00:01:44.640 --> 00:01:47.400
<v Speaker 1>Magic, which perfectly brings us to our mission for this

38
00:01:47.480 --> 00:01:50.599
<v Speaker 1>deep dive today. We're going to build a mental blueprint

39
00:01:50.719 --> 00:01:54.040
<v Speaker 1>of an automated data extraction pipeline, and we're looking really

40
00:01:54.040 --> 00:01:56.159
<v Speaker 1>closely at a Python framework called screepy.

41
00:01:56.319 --> 00:01:58.480
<v Speaker 3>Oh yeah, Scrapy is amazing for this, right.

42
00:01:58.519 --> 00:02:01.120
<v Speaker 1>It basically serves as the ultimate engine for this kind

43
00:02:01.159 --> 00:02:01.920
<v Speaker 1>of web scraping.

44
00:02:02.280 --> 00:02:03.599
<v Speaker 3>It really is a powerhouse.

45
00:02:03.920 --> 00:02:06.319
<v Speaker 2>And you know, our goal here for everyone listening isn't

46
00:02:06.359 --> 00:02:08.400
<v Speaker 2>just to talk about writing a quick duty script that

47
00:02:08.479 --> 00:02:11.719
<v Speaker 2>haphazardly yanks text off a page and calls.

48
00:02:11.479 --> 00:02:11.879
<v Speaker 3>It a day.

49
00:02:12.000 --> 00:02:13.080
<v Speaker 1>Right, we want to go deeper.

50
00:02:13.520 --> 00:02:14.919
<v Speaker 3>Exactly, we are.

51
00:02:14.840 --> 00:02:20.280
<v Speaker 2>Going to architect a robust, professional grade data pipeline. So

52
00:02:20.319 --> 00:02:23.560
<v Speaker 2>we will start by examining how to test raw code

53
00:02:23.639 --> 00:02:26.960
<v Speaker 2>in an isolated sandbox, figure out how to scale that

54
00:02:27.159 --> 00:02:30.599
<v Speaker 2>up to crawl entire pages, and eventually build a system

55
00:02:30.680 --> 00:02:35.000
<v Speaker 2>that automatically cleans and formats the data before saving it

56
00:02:35.039 --> 00:02:36.439
<v Speaker 2>into a pristine spreadsheet.

57
00:02:36.599 --> 00:02:40.439
<v Speaker 1>Okay, let's unpack this. Because whether you are a developer

58
00:02:40.520 --> 00:02:44.000
<v Speaker 1>prepping for a major data project, or you know, maybe

59
00:02:44.039 --> 00:02:46.400
<v Speaker 1>a self taught code or trying to automate your own life,

60
00:02:46.560 --> 00:02:49.400
<v Speaker 1>or just someone curious about how data actually moves around

61
00:02:49.439 --> 00:02:53.599
<v Speaker 1>the Internet, understanding this architecture gives you a whole new superpower.

62
00:02:53.840 --> 00:02:55.919
<v Speaker 1>So where do we even begin? Because if I'm staring

63
00:02:55.960 --> 00:02:58.960
<v Speaker 1>at that Yahoo Finance page, my first instinct is to just,

64
00:02:59.080 --> 00:03:00.960
<v Speaker 1>I don't know, write a man subscript and hope it

65
00:03:01.000 --> 00:03:01.840
<v Speaker 1>grabs the right number.

66
00:03:01.960 --> 00:03:04.479
<v Speaker 2>Yeah, and plunging straight into writing a massive script is

67
00:03:04.479 --> 00:03:06.120
<v Speaker 2>the fastest way to get completely.

68
00:03:05.840 --> 00:03:07.199
<v Speaker 1>Overwhelmed, I can imagine.

69
00:03:07.319 --> 00:03:10.879
<v Speaker 2>Because before building a factory, you need to test if

70
00:03:10.919 --> 00:03:13.800
<v Speaker 2>the raw materials are even usable. You need a testing

71
00:03:13.800 --> 00:03:15.960
<v Speaker 2>ground to see if the data you want is accessible

72
00:03:15.960 --> 00:03:18.000
<v Speaker 2>in the way you think it is, and in the

73
00:03:18.039 --> 00:03:22.800
<v Speaker 2>scrape ecosystem, this isolated environment is called the scrape shell.

74
00:03:22.919 --> 00:03:26.560
<v Speaker 1>The screepy shell. Okay, so I'm picturing like a digital sandbox.

75
00:03:26.840 --> 00:03:28.000
<v Speaker 3>That's a great way to look at it.

76
00:03:28.080 --> 00:03:30.520
<v Speaker 1>So you boot up this shell in your computer's terminal,

77
00:03:30.879 --> 00:03:33.680
<v Speaker 1>and you feed it the specific web address, like our

78
00:03:33.759 --> 00:03:37.240
<v Speaker 1>Yaku finance page, and it basically goes out, grabs the

79
00:03:37.319 --> 00:03:41.080
<v Speaker 1>underlying HTML of that page and downloads it right into

80
00:03:41.120 --> 00:03:42.199
<v Speaker 1>your sandbox exactly.

81
00:03:42.280 --> 00:03:43.479
<v Speaker 3>It pulls the raw code.

82
00:03:43.560 --> 00:03:46.800
<v Speaker 1>So now you can experiment with extracting the data without

83
00:03:46.840 --> 00:03:50.000
<v Speaker 1>the pressure of running a full automated program that might

84
00:03:50.039 --> 00:03:51.039
<v Speaker 1>break at any second.

85
00:03:51.120 --> 00:03:53.000
<v Speaker 2>Right, the sandbox isolates the problem.

86
00:03:53.039 --> 00:03:53.840
<v Speaker 3>You can just tinker.

87
00:03:54.360 --> 00:03:56.680
<v Speaker 2>But once you have the page data in there, you

88
00:03:56.759 --> 00:03:59.800
<v Speaker 2>need a designated place to actually put the specific fragments

89
00:03:59.840 --> 00:04:04.039
<v Speaker 2>of information you plan to extract. Okay, So the source

90
00:04:04.080 --> 00:04:07.599
<v Speaker 2>material introduces a really foundational concept here called a.

91
00:04:07.520 --> 00:04:11.879
<v Speaker 1>Scrapy item, Okay, an item. The way the documentation describes

92
00:04:11.919 --> 00:04:14.639
<v Speaker 1>this item, it actually reminds me of a bento box.

93
00:04:14.919 --> 00:04:15.560
<v Speaker 3>Oh I like that.

94
00:04:15.719 --> 00:04:18.399
<v Speaker 1>Yeah, because you have this container, but you don't just

95
00:04:18.519 --> 00:04:21.600
<v Speaker 1>dump all your food into one big, messy pile. You

96
00:04:21.680 --> 00:04:26.079
<v Speaker 1>have very specific pre labeled compartments. A compartment for the rice,

97
00:04:26.360 --> 00:04:27.480
<v Speaker 1>a compartment for the fish.

98
00:04:27.600 --> 00:04:28.800
<v Speaker 3>Right, it's structured.

99
00:04:28.600 --> 00:04:32.079
<v Speaker 1>Exactly in Python terms. It's like a highly structured dictionary.

100
00:04:32.639 --> 00:04:35.959
<v Speaker 1>We define our compartments or feels basically up front. So

101
00:04:36.000 --> 00:04:39.040
<v Speaker 1>we create a label for company name, one for inter

102
00:04:39.160 --> 00:04:41.879
<v Speaker 1>day price, one for symbol, and one for link.

103
00:04:42.040 --> 00:04:46.000
<v Speaker 2>The Bento box analogy perfectly captures the strict structural nature

104
00:04:46.040 --> 00:04:49.240
<v Speaker 2>of the item based class. When you first instantiate this

105
00:04:49.319 --> 00:04:52.519
<v Speaker 2>item in scrapy, it exists in memory as a completely

106
00:04:52.560 --> 00:04:56.480
<v Speaker 2>empty shell. The compartments are there, but they contain absolutely nothing.

107
00:04:56.519 --> 00:04:57.879
<v Speaker 1>You're just waiting for data, right.

108
00:04:58.360 --> 00:05:01.079
<v Speaker 2>Filling those compartments requires it to look at the underlined

109
00:05:01.120 --> 00:05:04.160
<v Speaker 2>structure of the website itself and extract the actual data.

110
00:05:04.240 --> 00:05:06.600
<v Speaker 1>Okay, and this is where it gets a little abstract,

111
00:05:06.639 --> 00:05:10.079
<v Speaker 1>I think, but it really is the core mechanism of webscreeping.

112
00:05:10.680 --> 00:05:13.560
<v Speaker 1>How do we actually tell our computer, hey, go look

113
00:05:13.560 --> 00:05:16.319
<v Speaker 1>at this massive wall of code and grab the words

114
00:05:16.519 --> 00:05:17.680
<v Speaker 1>Microsoft Corporation.

115
00:05:18.120 --> 00:05:19.800
<v Speaker 2>Yeah, it's not like you can just point at the screen.

116
00:05:20.160 --> 00:05:23.000
<v Speaker 2>So we use a mechanism called an XPath selector.

117
00:05:22.680 --> 00:05:24.399
<v Speaker 3>An XPath selector right.

118
00:05:24.639 --> 00:05:27.360
<v Speaker 2>To understand why XPath is necessary, we have to look

119
00:05:27.360 --> 00:05:30.439
<v Speaker 2>at how websites are actually built. HTML is not just

120
00:05:30.480 --> 00:05:34.519
<v Speaker 2>a flat text document. It is a complex, nested hierarchy

121
00:05:34.639 --> 00:05:35.879
<v Speaker 2>like a tree exactly.

122
00:05:35.920 --> 00:05:36.839
<v Speaker 3>It's a tree of elements.

123
00:05:37.000 --> 00:05:40.360
<v Speaker 2>You have this massive HTML trunk which branches off into

124
00:05:40.360 --> 00:05:44.399
<v Speaker 2>body tags, which branch off into dip containers, down into tables, rows,

125
00:05:44.600 --> 00:05:48.279
<v Speaker 2>and finally individual data cells. So to a computer, a

126
00:05:48.279 --> 00:05:51.199
<v Speaker 2>webpage looks like a massive set of Russian mesting dolls.

127
00:05:51.319 --> 00:05:54.160
<v Speaker 1>Okay, so an XPath is essentially like a set of

128
00:05:54.240 --> 00:05:57.680
<v Speaker 1>navigation directions through that specific family tree. Yes, you are

129
00:05:57.680 --> 00:05:59.800
<v Speaker 1>telling the scraper, okay, go into the table container of

130
00:06:00.199 --> 00:06:03.759
<v Speaker 1>the rows and look inside the cell at index two, right, and.

131
00:06:03.720 --> 00:06:06.240
<v Speaker 2>You've hit on a really vital detail there with index two.

132
00:06:06.319 --> 00:06:10.000
<v Speaker 2>Oh really, yeah, because in programming we generally start counting from.

133
00:06:10.000 --> 00:06:13.560
<v Speaker 1>Zero ah right, zero based indexing exactly.

134
00:06:13.639 --> 00:06:15.720
<v Speaker 2>So if the company name is in the third column

135
00:06:15.759 --> 00:06:18.279
<v Speaker 2>of the visual tail you see on the screen, it's

136
00:06:18.399 --> 00:06:20.399
<v Speaker 2>index in the actual code is two.

137
00:06:20.680 --> 00:06:21.160
<v Speaker 1>Wow.

138
00:06:21.560 --> 00:06:22.480
<v Speaker 3>Okay, yeah, if.

139
00:06:22.399 --> 00:06:24.920
<v Speaker 2>You tell your scraper to look at index three, you

140
00:06:24.959 --> 00:06:27.600
<v Speaker 2>are going to pull the entirely wrong column of data,

141
00:06:27.920 --> 00:06:30.160
<v Speaker 2>which is a very common trap when people first start

142
00:06:30.199 --> 00:06:31.319
<v Speaker 2>testing in the scrapey shell.

143
00:06:31.360 --> 00:06:34.240
<v Speaker 1>That would be so frustrating. Okay, so I write my

144
00:06:34.279 --> 00:06:37.959
<v Speaker 1>expath directions, I target index two. Does the shell just

145
00:06:38.160 --> 00:06:42.160
<v Speaker 1>like hand me the text Microsoft Corporation right then and there?

146
00:06:42.399 --> 00:06:43.319
<v Speaker 3>Uh No, it does not.

147
00:06:43.480 --> 00:06:44.480
<v Speaker 1>Oh it does. No.

148
00:06:44.680 --> 00:06:48.399
<v Speaker 2>The XPath selector merely returns a match. It basically hands

149
00:06:48.399 --> 00:06:51.399
<v Speaker 2>you a selector object, essentially a pointer that says, hey,

150
00:06:51.439 --> 00:06:52.360
<v Speaker 2>I found the digital.

151
00:06:52.160 --> 00:06:54.920
<v Speaker 1>Nesting doll you asked for, but it hasn't opened it yet.

152
00:06:54.959 --> 00:06:57.800
<v Speaker 2>Exactly the text you actually want is still sealed inside

153
00:06:57.879 --> 00:07:00.480
<v Speaker 2>that doll. So to reach in and extra the human

154
00:07:00.519 --> 00:07:04.000
<v Speaker 2>readable data, you have to execute a specific function on

155
00:07:04.079 --> 00:07:05.040
<v Speaker 2>that select or object.

156
00:07:05.079 --> 00:07:07.480
<v Speaker 1>Okay, looking at the material, it seems we use functions

157
00:07:07.519 --> 00:07:08.439
<v Speaker 1>like get for this.

158
00:07:08.600 --> 00:07:09.959
<v Speaker 3>Yes, get is the one.

159
00:07:10.120 --> 00:07:13.439
<v Speaker 1>So the workflow is basically, use x path to point

160
00:07:13.439 --> 00:07:16.199
<v Speaker 1>at the cell, then used get to physically pull the

161
00:07:16.199 --> 00:07:18.879
<v Speaker 1>string of text out, and once we have that text,

162
00:07:18.879 --> 00:07:21.279
<v Speaker 1>we place it neatly into the company name compartment of

163
00:07:21.319 --> 00:07:22.120
<v Speaker 1>our Bento box.

164
00:07:22.199 --> 00:07:22.680
<v Speaker 3>You got it.

165
00:07:23.519 --> 00:07:27.079
<v Speaker 2>That completes the entire cycle for a single data point.

166
00:07:27.800 --> 00:07:31.759
<v Speaker 2>We've successfully navigated the HTML tree, extracted the raw text,

167
00:07:31.800 --> 00:07:34.839
<v Speaker 2>and structured it. But we did this inside an isolated

168
00:07:34.879 --> 00:07:37.399
<v Speaker 2>sandbox for one single company.

169
00:07:37.600 --> 00:07:40.959
<v Speaker 1>Right, And here's the fatal flaw with staying in the sandbox.

170
00:07:41.279 --> 00:07:43.879
<v Speaker 1>We are still manually pointing it at one company at

171
00:07:43.920 --> 00:07:47.240
<v Speaker 1>a time. If we stop here, we haven't actually automated anything,

172
00:07:47.279 --> 00:07:49.800
<v Speaker 1>have we. We have just changed the interface from copy

173
00:07:49.879 --> 00:07:52.519
<v Speaker 1>pasting in a web browser to typing manual commands in

174
00:07:52.560 --> 00:07:53.040
<v Speaker 1>a terminal.

175
00:07:53.160 --> 00:07:54.720
<v Speaker 3>Exactly. It's the same amount of work.

176
00:07:54.759 --> 00:07:56.839
<v Speaker 1>So to build a factory floor that can do this

177
00:07:56.879 --> 00:07:58.759
<v Speaker 1>one hundred times a second, we need a way to

178
00:07:58.800 --> 00:07:59.600
<v Speaker 1>scale the logic.

179
00:07:59.680 --> 00:08:03.240
<v Speaker 2>Yeah, moving from testing to actual automation requires building a spider.

180
00:08:03.360 --> 00:08:04.399
<v Speaker 1>A spider right.

181
00:08:04.560 --> 00:08:06.839
<v Speaker 2>When you are ready to scale, you create a full

182
00:08:06.879 --> 00:08:11.120
<v Speaker 2>scrapy project. Running a simple setup command generates an entire

183
00:08:11.240 --> 00:08:15.040
<v Speaker 2>architecture of folders and files. It essentially lays the concrete

184
00:08:15.079 --> 00:08:16.079
<v Speaker 2>for your factory floor.

185
00:08:16.399 --> 00:08:19.480
<v Speaker 1>Okay, so inside that new folder structure, we have a

186
00:08:19.519 --> 00:08:23.000
<v Speaker 1>file called items dot pie. I assume this is where

187
00:08:23.000 --> 00:08:26.360
<v Speaker 1>we officially encode the blueprint for our Bento box. Right,

188
00:08:26.439 --> 00:08:29.040
<v Speaker 1>listing out those four specific fields we want to fill.

189
00:08:29.160 --> 00:08:31.399
<v Speaker 2>Yes, you define your item there, but the actual end

190
00:08:31.480 --> 00:08:33.799
<v Speaker 2>of the thing doing the crawling lives in a separate file,

191
00:08:33.919 --> 00:08:37.080
<v Speaker 2>maybe something we call a companydetailseem dot.

192
00:08:36.919 --> 00:08:37.679
<v Speaker 3>Pie got it.

193
00:08:37.759 --> 00:08:39.840
<v Speaker 1>And that is the spider file exactly.

194
00:08:39.879 --> 00:08:43.240
<v Speaker 2>And the logic you encode inside the spider is incredibly

195
00:08:43.279 --> 00:08:45.919
<v Speaker 2>elegant because it relies on loops ah loops.

196
00:08:46.279 --> 00:08:46.559
<v Speaker 3>Yeah.

197
00:08:47.240 --> 00:08:50.519
<v Speaker 2>Instead of writing separate XPath directions for every single row

198
00:08:50.559 --> 00:08:53.600
<v Speaker 2>on the Yahoo finance page, you write a generalized set

199
00:08:53.600 --> 00:08:56.879
<v Speaker 2>of instructions. You instruct the spider to target the entire

200
00:08:56.919 --> 00:09:00.279
<v Speaker 2>table first, then you tell it to iterate. So row

201
00:09:00.320 --> 00:09:03.039
<v Speaker 2>by row right, you say, look at row one, perform

202
00:09:03.080 --> 00:09:05.320
<v Speaker 2>these actions, then move to row two and repeat.

203
00:09:05.440 --> 00:09:08.480
<v Speaker 1>Okay, so for row one, it instantiates a brand new

204
00:09:08.559 --> 00:09:11.360
<v Speaker 1>empty Bento box. It runs the x path directions to

205
00:09:11.360 --> 00:09:14.480
<v Speaker 1>grab the name, price, symbol, and link. It packs them

206
00:09:14.519 --> 00:09:16.679
<v Speaker 1>all into the box. But then it uses a command

207
00:09:16.720 --> 00:09:19.279
<v Speaker 1>called yield. Yes, yield, And here is where I need

208
00:09:19.279 --> 00:09:22.960
<v Speaker 1>to clarify something, because yield sounds a bit mysterious. If

209
00:09:22.960 --> 00:09:27.080
<v Speaker 1>I tell the program to yield my carefully packed box,

210
00:09:27.799 --> 00:09:30.360
<v Speaker 1>am I just throwing it out the window into the void?

211
00:09:30.480 --> 00:09:33.000
<v Speaker 1>Like how are we actually capturing this data.

212
00:09:33.080 --> 00:09:36.399
<v Speaker 2>It's a very common point of confusion, actually, because in

213
00:09:36.559 --> 00:09:40.600
<v Speaker 2>standard Python functions, people are really used to the return command. Right.

214
00:09:40.679 --> 00:09:42.440
<v Speaker 1>Return just gives you the answer and stops.

215
00:09:42.600 --> 00:09:45.720
<v Speaker 2>Exactly, it hands back a value and immediately kills the function.

216
00:09:46.519 --> 00:09:50.120
<v Speaker 2>But yield is fundamentally different. It creates what's called a generator.

217
00:09:50.240 --> 00:09:50.960
<v Speaker 1>A generator.

218
00:09:51.080 --> 00:09:54.759
<v Speaker 2>Okay, so when the spider yields the item, it hands

219
00:09:54.799 --> 00:09:58.559
<v Speaker 2>the Bento box up to the Scrapy engine, basically pauses

220
00:09:58.600 --> 00:10:01.240
<v Speaker 2>its current state, and then immediately turns back to the

221
00:10:01.279 --> 00:10:02.639
<v Speaker 2>loop to process road too.

222
00:10:02.759 --> 00:10:04.840
<v Speaker 1>Oh I see, so it operates almost like a worker

223
00:10:04.879 --> 00:10:05.759
<v Speaker 1>on an assembly line.

224
00:10:05.840 --> 00:10:06.919
<v Speaker 3>Yeah, perfect analogy.

225
00:10:07.279 --> 00:10:09.240
<v Speaker 1>They finish packing a box, they hand it to the

226
00:10:09.279 --> 00:10:12.159
<v Speaker 1>supervisor standing directly behind them, and then instantly turn back

227
00:10:12.200 --> 00:10:14.200
<v Speaker 1>to the conveyor belt to pack the next one. They

228
00:10:14.200 --> 00:10:16.240
<v Speaker 1>don't clock out and go home just because one single

229
00:10:16.279 --> 00:10:17.120
<v Speaker 1>box is done.

230
00:10:17.480 --> 00:10:18.039
<v Speaker 3>Exactly.

231
00:10:18.480 --> 00:10:22.000
<v Speaker 2>The supervisor in your analogy is Scrapy itself. If you

232
00:10:22.039 --> 00:10:25.080
<v Speaker 2>go to your terminal and simply tope screaby crawl company

233
00:10:25.120 --> 00:10:28.960
<v Speaker 2>details item, Scrapey spins up the spider, The spider starts

234
00:10:29.000 --> 00:10:32.799
<v Speaker 2>iterating yielding those boxes, and Scrapey just prints the resulting

235
00:10:32.879 --> 00:10:36.360
<v Speaker 2>Jason objects right there on your screen, cascading down the terminal.

236
00:10:36.480 --> 00:10:38.679
<v Speaker 1>I mean, seeing the matrix code fall down the screen

237
00:10:38.759 --> 00:10:41.879
<v Speaker 1>is really fun. But data printed in a terminal basically

238
00:10:41.919 --> 00:10:44.240
<v Speaker 1>disappears the second you close the window. We need a

239
00:10:44.240 --> 00:10:46.399
<v Speaker 1>physical spadsheet we can actually send to our boss.

240
00:10:46.399 --> 00:10:51.080
<v Speaker 2>Oh absolutely, And scrapey makes saving the data almost shockingly simple.

241
00:10:51.279 --> 00:10:53.679
<v Speaker 2>Really yeah, you do not need to write complex file

242
00:10:53.720 --> 00:10:57.000
<v Speaker 2>handling code inside your spider at all. You simply modify

243
00:10:57.120 --> 00:10:59.559
<v Speaker 2>the terminal command you just ran. Oh nice, By adding

244
00:10:59.600 --> 00:11:04.279
<v Speaker 2>an out put flag, specifically appending augiocompanydetails dot csv to

245
00:11:04.360 --> 00:11:07.399
<v Speaker 2>the end of your command, scrape basically catches every single

246
00:11:07.440 --> 00:11:10.720
<v Speaker 2>item the spider yields and dynamically appends into a neatly

247
00:11:10.759 --> 00:11:12.039
<v Speaker 2>formatted spreadsheet file.

248
00:11:12.279 --> 00:11:16.000
<v Speaker 1>Wait, really, so one simple terminal flag replaces dozens of

249
00:11:16.039 --> 00:11:18.360
<v Speaker 1>lines of file saving logic just one flag.

250
00:11:18.440 --> 00:11:18.840
<v Speaker 3>That's it.

251
00:11:19.080 --> 00:11:21.799
<v Speaker 1>That is amazing. We run the command, the spider crawls

252
00:11:21.840 --> 00:11:24.240
<v Speaker 1>the page, and boom, we have a CSV file sitting

253
00:11:24.279 --> 00:11:26.679
<v Speaker 1>on our hard drive. But you know, if we open

254
00:11:26.720 --> 00:11:28.639
<v Speaker 1>that spreadsheet right now, I have a feeling it is

255
00:11:28.679 --> 00:11:32.080
<v Speaker 1>going to be a disaster. The web is inherently messy,

256
00:11:32.159 --> 00:11:36.519
<v Speaker 1>right and raw scraped data is rarely usable right out

257
00:11:36.519 --> 00:11:37.080
<v Speaker 1>of the box.

258
00:11:37.159 --> 00:11:40.960
<v Speaker 2>Oh, it's almost always unusable. Raw data is rough. The

259
00:11:41.000 --> 00:11:44.480
<v Speaker 2>source material points out two glaring formatting issues. You will

260
00:11:44.559 --> 00:11:48.000
<v Speaker 2>immediately encounter when scraping that Yahoo Finance page.

261
00:11:48.080 --> 00:11:49.120
<v Speaker 1>Okay, what's the first one.

262
00:11:49.279 --> 00:11:51.360
<v Speaker 2>The first problem has to do with the URLs we

263
00:11:51.399 --> 00:11:54.360
<v Speaker 2>are extracting for the company profiles. They are what developers

264
00:11:54.360 --> 00:11:55.759
<v Speaker 2>call relative.

265
00:11:55.320 --> 00:11:59.120
<v Speaker 1>Links, a relative links, meaning they don't start with HTP

266
00:11:59.399 --> 00:12:02.879
<v Speaker 1>or wa ww. The HTML might just say something like

267
00:12:03.039 --> 00:12:07.159
<v Speaker 1>quote MSFT exactly because websites do this to save space, right, yeah,

268
00:12:07.200 --> 00:12:09.799
<v Speaker 1>they assume the browser already knows you are sitting on

269
00:12:09.799 --> 00:12:13.039
<v Speaker 1>the Yahoo Finance domain. But if you drop that relative

270
00:12:13.080 --> 00:12:15.799
<v Speaker 1>link into an offline Excel file and click it, your

271
00:12:15.840 --> 00:12:18.320
<v Speaker 1>computer has literally no idea where to go. It's a

272
00:12:18.320 --> 00:12:19.799
<v Speaker 1>completely broken link.

273
00:12:19.639 --> 00:12:22.720
<v Speaker 2>Right, The spreadsheet has completely lost the context of the website.

274
00:12:23.000 --> 00:12:26.519
<v Speaker 2>So that is the first major hurdle, appending the base

275
00:12:26.639 --> 00:12:28.200
<v Speaker 2>domain to every single link on.

276
00:12:28.200 --> 00:12:29.000
<v Speaker 1>The second issue.

277
00:12:29.039 --> 00:12:32.320
<v Speaker 2>The second issue is a weird quirk of how Scrape's

278
00:12:32.360 --> 00:12:36.320
<v Speaker 2>extraction functions work. By default, when you tell scrape to

279
00:12:36.360 --> 00:12:39.399
<v Speaker 2>extract text, it doesn't just hand you a clean string.

280
00:12:39.759 --> 00:12:41.720
<v Speaker 2>It returns a Python list object.

281
00:12:41.759 --> 00:12:44.120
<v Speaker 1>Oh I see. It assumes there might be a multiple

282
00:12:44.120 --> 00:12:46.440
<v Speaker 1>matches for your expath, so it wraps everything in a

283
00:12:46.480 --> 00:12:47.240
<v Speaker 1>list just to be.

284
00:12:47.320 --> 00:12:49.240
<v Speaker 3>Safe, exactly, just in case.

285
00:12:49.039 --> 00:12:52.440
<v Speaker 1>Which means our spreadsheet doesn't say Microsoft Corporation. It says

286
00:12:52.600 --> 00:12:57.960
<v Speaker 1>bracket quote Microsoft Corporation quote bracket like it's literally trapped

287
00:12:57.960 --> 00:12:59.480
<v Speaker 1>inside Microsoft Corporation.

288
00:12:59.639 --> 00:13:01.720
<v Speaker 2>Yeah, and if you try to hand a spreadsheet full

289
00:13:01.720 --> 00:13:04.399
<v Speaker 2>of bracketed list objects to a data analyst, they will

290
00:13:04.399 --> 00:13:05.000
<v Speaker 2>send it right.

291
00:13:04.919 --> 00:13:05.320
<v Speaker 3>Back to you.

292
00:13:05.480 --> 00:13:06.000
<v Speaker 1>I would too.

293
00:13:06.240 --> 00:13:09.240
<v Speaker 2>You cannot perform basic database functions on text that's trapped

294
00:13:09.240 --> 00:13:11.320
<v Speaker 2>in a list format. We need a way to refine

295
00:13:11.320 --> 00:13:15.320
<v Speaker 2>this data systematically, and this introduces a vital scrapy component

296
00:13:15.399 --> 00:13:16.399
<v Speaker 2>called the item loader.

297
00:13:16.720 --> 00:13:19.360
<v Speaker 1>The item loader. Okay, so instead of the spider just

298
00:13:19.360 --> 00:13:22.799
<v Speaker 1>stuffing raw, dirty data directly into our bento box fields,

299
00:13:23.200 --> 00:13:26.519
<v Speaker 1>an item loader acts as an intelligent populator. Yes, we

300
00:13:26.600 --> 00:13:30.200
<v Speaker 1>feed the raw XPath data into the loader and it processes, it,

301
00:13:30.240 --> 00:13:33.279
<v Speaker 1>cleans it, and formats it before permanently sealing the box.

302
00:13:33.840 --> 00:13:36.960
<v Speaker 1>And based on the documentation, it achieves this using two

303
00:13:37.200 --> 00:13:40.840
<v Speaker 1>distinct mechanisms, input processors and output processor.

304
00:13:41.000 --> 00:13:41.440
<v Speaker 3>You've got it.

305
00:13:41.519 --> 00:13:45.480
<v Speaker 2>Let's examine the input processor first. Okay, This mechanism intercepts

306
00:13:45.480 --> 00:13:48.200
<v Speaker 2>the data the exact millisecond it is scraped off the

307
00:13:48.240 --> 00:13:51.320
<v Speaker 2>page before it even touches the item. Think about our

308
00:13:51.399 --> 00:13:53.120
<v Speaker 2>prokin relative URL.

309
00:13:52.879 --> 00:13:55.320
<v Speaker 1>Problem right, the quote MSFT problem.

310
00:13:55.399 --> 00:13:58.840
<v Speaker 2>Right In our blueprint file items dot piy, we can

311
00:13:58.840 --> 00:14:01.679
<v Speaker 2>attach an input process a specifically to the link field.

312
00:14:02.120 --> 00:14:05.120
<v Speaker 2>And that documentation highlights a really powerful object for this

313
00:14:05.200 --> 00:14:07.080
<v Speaker 2>called map compose map composed.

314
00:14:07.120 --> 00:14:08.840
<v Speaker 1>I mean it sounds a bit complicated, but the way

315
00:14:08.840 --> 00:14:11.279
<v Speaker 1>I understand it, it is essentially a midair interceptor.

316
00:14:11.440 --> 00:14:11.919
<v Speaker 3>I like that.

317
00:14:12.080 --> 00:14:15.080
<v Speaker 1>Yes, So you write a tiny helper function let's just

318
00:14:15.159 --> 00:14:17.960
<v Speaker 1>name it pullings ah. And the only job of pullinks

319
00:14:18.080 --> 00:14:20.360
<v Speaker 1>is to take a broken piece of text like quote

320
00:14:20.480 --> 00:14:24.080
<v Speaker 1>MSFT and just gluefinance dot yahoo dot com to the

321
00:14:24.080 --> 00:14:25.240
<v Speaker 1>front of it exactly.

322
00:14:25.600 --> 00:14:28.720
<v Speaker 2>And map compose allows you to seamlessly map that custom

323
00:14:28.759 --> 00:14:32.240
<v Speaker 2>pullings function to your incoming data stream. So the raw

324
00:14:32.279 --> 00:14:34.879
<v Speaker 2>relative link comes off the web page, map composed catches

325
00:14:34.879 --> 00:14:37.759
<v Speaker 2>it in midair, feeds it through your helper function, and

326
00:14:37.799 --> 00:14:41.600
<v Speaker 2>the fully repaired absolute URL is what actually gets placed

327
00:14:41.600 --> 00:14:42.480
<v Speaker 2>into the Bento box.

328
00:14:42.559 --> 00:14:45.039
<v Speaker 1>That is so clean, So that handles the data on

329
00:14:45.080 --> 00:14:48.279
<v Speaker 1>the way in. But what about the bracket problem that

330
00:14:48.440 --> 00:14:51.279
<v Speaker 1>messy list format the Microsoft Corporation issue?

331
00:14:51.360 --> 00:14:51.480
<v Speaker 2>Right?

332
00:14:51.519 --> 00:14:53.639
<v Speaker 1>I assume that is where output processors step in. If

333
00:14:53.679 --> 00:14:56.080
<v Speaker 1>the input processor is washing the ingredients before they go

334
00:14:56.120 --> 00:14:58.679
<v Speaker 1>into the box. The output processor operates at the very

335
00:14:58.759 --> 00:15:01.679
<v Speaker 1>end of the line, right before the spider yields the

336
00:15:01.720 --> 00:15:02.440
<v Speaker 1>final product.

337
00:15:02.480 --> 00:15:06.919
<v Speaker 2>Precisely, output processors handle the final data transformation, and Scrapie

338
00:15:06.960 --> 00:15:11.240
<v Speaker 2>actually provides a built in output processor explicitly designed to

339
00:15:11.320 --> 00:15:13.000
<v Speaker 2>solve this exact list problem.

340
00:15:13.000 --> 00:15:14.720
<v Speaker 3>Oh really, yeah, it'll call take first.

341
00:15:14.960 --> 00:15:16.759
<v Speaker 1>Take first. I was actually trying to think of an

342
00:15:16.759 --> 00:15:18.960
<v Speaker 1>analogy for this earlier. It's almost like shucking an oyster.

343
00:15:19.120 --> 00:15:21.440
<v Speaker 2>Shucking an oyster. Okay, how so, Well.

344
00:15:21.279 --> 00:15:24.120
<v Speaker 1>The data you want is the pearl, but it's trapped

345
00:15:24.159 --> 00:15:29.240
<v Speaker 1>inside this totally useless hardshell the list brackets. The take

346
00:15:29.320 --> 00:15:33.000
<v Speaker 1>first processor prize open, the list reaches in, takes the

347
00:15:33.120 --> 00:15:35.799
<v Speaker 1>very first item it finds, and just hands you the clean,

348
00:15:36.240 --> 00:15:38.240
<v Speaker 1>unencumbered pearl of text.

349
00:15:38.639 --> 00:15:40.360
<v Speaker 3>That is a perfect analogy. Yes.

350
00:15:40.639 --> 00:15:44.320
<v Speaker 2>By setting take first as the default output processor for

351
00:15:44.360 --> 00:15:48.720
<v Speaker 2>your item loader, every single field, the company, name, the price,

352
00:15:49.080 --> 00:15:52.799
<v Speaker 2>the symbol is automatically shucked from those annoying brackets. Nice.

353
00:15:52.840 --> 00:15:55.240
<v Speaker 2>They all become clean, plain strengths. So now when you

354
00:15:55.279 --> 00:15:58.440
<v Speaker 2>save to your CSV, the spreadsheet looks completely professional.

355
00:15:58.559 --> 00:16:01.559
<v Speaker 1>Okay, I am really loving this architecture. Item loaders give

356
00:16:01.639 --> 00:16:04.200
<v Speaker 1>us structural cleaning on the fly. But let's push this

357
00:16:04.279 --> 00:16:04.840
<v Speaker 1>even further.

358
00:16:05.000 --> 00:16:05.559
<v Speaker 3>Let's do it.

359
00:16:05.759 --> 00:16:08.759
<v Speaker 1>What if we want to apply actual business logic, Like,

360
00:16:08.799 --> 00:16:11.279
<v Speaker 1>what if we aren't just formatting text, but we want

361
00:16:11.279 --> 00:16:14.440
<v Speaker 1>to make active decisions based on the data itself after

362
00:16:14.480 --> 00:16:16.120
<v Speaker 1>the whole extraction process is complete.

363
00:16:16.200 --> 00:16:19.720
<v Speaker 2>Well, structural cleaning is one thing, but applying business logic

364
00:16:19.840 --> 00:16:23.679
<v Speaker 2>requires the final and perhaps most powerful piece of this

365
00:16:23.720 --> 00:16:26.200
<v Speaker 2>scrapy architecture. Data pipelines.

366
00:16:26.720 --> 00:16:30.799
<v Speaker 1>Data pipelines. I visualize a pipeline as a quality assurance

367
00:16:30.840 --> 00:16:32.759
<v Speaker 1>conveyor belt on a factory floor.

368
00:16:32.840 --> 00:16:33.879
<v Speaker 3>Oh absolutely so.

369
00:16:33.919 --> 00:16:37.879
<v Speaker 1>Our item loaders have packed these perfectly formatted bento boxes.

370
00:16:38.480 --> 00:16:42.080
<v Speaker 1>Now those completed boxes are rolling down a long conveyor belt,

371
00:16:42.519 --> 00:16:45.879
<v Speaker 1>and positioned along this belt are different QA stations. As

372
00:16:45.919 --> 00:16:49.360
<v Speaker 1>a box rolls up to a station, an inspector opens it,

373
00:16:49.399 --> 00:16:53.000
<v Speaker 1>looks at the data inside based on very strict mathematical rules,

374
00:16:53.240 --> 00:16:55.799
<v Speaker 1>and decides what to do. They can modify the data,

375
00:16:55.879 --> 00:16:58.279
<v Speaker 1>they can drop the box entirely into the trash, or

376
00:16:58.320 --> 00:17:00.320
<v Speaker 1>they can simply wave it through to the next station.

377
00:17:00.559 --> 00:17:04.640
<v Speaker 2>The conveyor belt analogy is incredibly accurate in your scraping project.

378
00:17:04.680 --> 00:17:07.599
<v Speaker 2>These pipelines live in their own dedicated file simply named

379
00:17:07.640 --> 00:17:10.559
<v Speaker 2>pipelines dot pi makes sense, and inside this file you

380
00:17:10.559 --> 00:17:13.200
<v Speaker 2>can construct as many of these QA stations as you need.

381
00:17:13.440 --> 00:17:16.319
<v Speaker 2>Each station is written as a standard Python class, and

382
00:17:16.359 --> 00:17:20.640
<v Speaker 2>each class must contain a specific mandatory function called process item.

383
00:17:20.839 --> 00:17:25.119
<v Speaker 1>Because its entire existence is dedicated to processing the item currently.

384
00:17:24.960 --> 00:17:26.559
<v Speaker 3>Rolling down the belt exactly.

385
00:17:26.880 --> 00:17:30.359
<v Speaker 1>The source material actually provides a highly practical example of

386
00:17:30.400 --> 00:17:33.960
<v Speaker 1>this business logic involving the stock prices. Let's walk through

387
00:17:33.960 --> 00:17:34.640
<v Speaker 1>how we build that.

388
00:17:35.000 --> 00:17:35.319
<v Speaker 3>Sure.

389
00:17:35.400 --> 00:17:38.680
<v Speaker 2>So imagine you are building a tool for a financial

390
00:17:38.720 --> 00:17:42.960
<v Speaker 2>analyst who only cares about extreme stock price movements. They

391
00:17:43.000 --> 00:17:45.759
<v Speaker 2>want to flag any stock over one hundred dollars or

392
00:17:45.799 --> 00:17:48.880
<v Speaker 2>under fifty dollars. Okay, we can build two separate stations

393
00:17:48.920 --> 00:17:51.559
<v Speaker 2>on our conveyor belt. We define our first class and

394
00:17:51.640 --> 00:17:53.359
<v Speaker 2>name it above one hundred price check.

395
00:17:53.519 --> 00:17:56.920
<v Speaker 1>Station one is operational the item rolls up. What actually

396
00:17:56.920 --> 00:17:58.960
<v Speaker 1>happens inside that process item function.

397
00:17:59.160 --> 00:18:01.319
<v Speaker 2>First, it looks at the inter day price field. Now,

398
00:18:01.359 --> 00:18:03.799
<v Speaker 2>remember the price is currently stored as a string of text.

399
00:18:04.240 --> 00:18:06.799
<v Speaker 2>You cannot perform mathematical operations on text.

400
00:18:06.559 --> 00:18:08.720
<v Speaker 1>Right, Python would just throw an error exactly.

401
00:18:09.000 --> 00:18:10.920
<v Speaker 2>So the first thing the function does is parse that

402
00:18:10.960 --> 00:18:13.559
<v Speaker 2>text and convert it into a numerical float. Once it

403
00:18:13.640 --> 00:18:15.960
<v Speaker 2>is a real number, it as a simple logical question,

404
00:18:16.680 --> 00:18:18.480
<v Speaker 2>is this value greater than one hundred?

405
00:18:18.559 --> 00:18:20.880
<v Speaker 1>Okay, let's say the extracted price is a one oh

406
00:18:20.960 --> 00:18:24.119
<v Speaker 1>five point fifty. The answer is yes. What does the

407
00:18:24.160 --> 00:18:25.079
<v Speaker 1>station actually do?

408
00:18:25.559 --> 00:18:29.000
<v Speaker 2>It actively overwrites the scrape data. It modifies the item,

409
00:18:29.200 --> 00:18:31.440
<v Speaker 2>changing the price field from one oh five point fifty

410
00:18:31.680 --> 00:18:34.039
<v Speaker 2>to a hard coded string that simply reads one hundred.

411
00:18:34.519 --> 00:18:36.920
<v Speaker 1>Oh wow, so it replaces the number entirely.

412
00:18:37.000 --> 00:18:37.240
<v Speaker 3>Yeah.

413
00:18:37.279 --> 00:18:40.119
<v Speaker 2>It categorizes the data, and once the modification is done,

414
00:18:40.240 --> 00:18:41.640
<v Speaker 2>it passes the item down the belt.

415
00:18:41.680 --> 00:18:43.799
<v Speaker 1>Okay, So the item continues rolling and arrives at our

416
00:18:43.839 --> 00:18:47.680
<v Speaker 1>second class below fifty price check station two. I assume

417
00:18:47.720 --> 00:18:50.319
<v Speaker 1>the logic mirror is the first. It converts the price

418
00:18:50.359 --> 00:18:52.880
<v Speaker 1>to a number and checks if it is under fifty dollars. So,

419
00:18:52.920 --> 00:18:55.279
<v Speaker 1>if the stock is trading at say forty dollars, it

420
00:18:55.319 --> 00:18:57.599
<v Speaker 1>overwrites the field to read fifty precisely.

421
00:18:57.680 --> 00:19:00.400
<v Speaker 2>But the really fascinating part of this pipeline is what

422
00:19:00.440 --> 00:19:02.559
<v Speaker 2>happens to the data that followed perfectly in the middle.

423
00:19:03.160 --> 00:19:06.160
<v Speaker 2>Consider a stock trading at exactly seventy five dollars.

424
00:19:06.240 --> 00:19:08.559
<v Speaker 1>Okay, So the seventy five dollars box rolls up to

425
00:19:08.599 --> 00:19:12.400
<v Speaker 1>station one. The above one hundred check runs seventy five

426
00:19:12.480 --> 00:19:14.759
<v Speaker 1>is not greater than one hundred, so the inspector does nothing.

427
00:19:15.480 --> 00:19:18.839
<v Speaker 1>The box passes through completely untouched. It reaches station two.

428
00:19:18.880 --> 00:19:21.599
<v Speaker 1>The below fifty check runs seventy five is not less

429
00:19:21.640 --> 00:19:23.960
<v Speaker 1>than fifty. Again, the inspector does nothing, and.

430
00:19:23.920 --> 00:19:26.200
<v Speaker 2>So the seventy five dollars item arrives at the very

431
00:19:26.319 --> 00:19:29.720
<v Speaker 2>end of the conveyor belt completely untouched, retaining its original

432
00:19:29.880 --> 00:19:31.400
<v Speaker 2>precise numerical value.

433
00:19:31.480 --> 00:19:32.799
<v Speaker 1>That is so cool.

434
00:19:32.960 --> 00:19:36.079
<v Speaker 2>You see, you are not just blindly scraping data anymore.

435
00:19:36.400 --> 00:19:40.920
<v Speaker 2>You are dynamically categorizing and filtering information in real time.

436
00:19:41.359 --> 00:19:44.160
<v Speaker 1>And if you are listening to this and wondering why

437
00:19:44.519 --> 00:19:47.640
<v Speaker 1>go through all this trouble, why not just dump the

438
00:19:47.759 --> 00:19:51.559
<v Speaker 1>raw numbers into Excel and run a simple filter formula later.

439
00:19:51.759 --> 00:19:52.920
<v Speaker 3>Right? People always ask.

440
00:19:52.799 --> 00:19:56.279
<v Speaker 1>That it's because of automation. By building this logic directly

441
00:19:56.319 --> 00:19:59.319
<v Speaker 1>into the pipeline, this script can run unattended on a

442
00:19:59.359 --> 00:20:02.680
<v Speaker 1>server every single day for a year. You wake up

443
00:20:02.720 --> 00:20:07.000
<v Speaker 1>and your perfectly categorized, cleaned spreadsheet is just sitting there

444
00:20:07.039 --> 00:20:09.680
<v Speaker 1>waiting for you, no manual cleanup required.

445
00:20:09.759 --> 00:20:12.480
<v Speaker 2>Ever, it's huge it's just your time from cleaning data

446
00:20:12.759 --> 00:20:15.599
<v Speaker 2>to actually analyzing it exactly. But building a pipeline with

447
00:20:15.680 --> 00:20:19.440
<v Speaker 2>multiple stations introduces a really critical logistical problem.

448
00:20:19.559 --> 00:20:20.680
<v Speaker 1>Oh what's that?

449
00:20:21.119 --> 00:20:23.440
<v Speaker 2>Well, if you have a massive pipeline with twenty different

450
00:20:23.440 --> 00:20:27.599
<v Speaker 2>stations doing complex transformations, the order in which those stations.

451
00:20:27.240 --> 00:20:28.359
<v Speaker 3>Operate is paramount.

452
00:20:28.480 --> 00:20:29.240
<v Speaker 1>Oh I see.

453
00:20:29.319 --> 00:20:29.480
<v Speaker 3>Yeah.

454
00:20:29.519 --> 00:20:32.000
<v Speaker 2>If station one deletes a piece of data entirely, station

455
00:20:32.079 --> 00:20:33.880
<v Speaker 2>two cannot check it, it's gone.

456
00:20:34.039 --> 00:20:36.839
<v Speaker 1>Okay, So how does scrapee manage the traffic? Like, how

457
00:20:36.839 --> 00:20:38.720
<v Speaker 1>does it know that the above one hundred check should

458
00:20:38.759 --> 00:20:40.480
<v Speaker 1>run before the blow fifty check?

459
00:20:40.880 --> 00:20:44.519
<v Speaker 2>Scrapeye requires you to explicitly declare the order in a

460
00:20:44.559 --> 00:20:48.960
<v Speaker 2>configuration file called settings dot pie. Now, by default, Scrapeye

461
00:20:49.000 --> 00:20:51.680
<v Speaker 2>is a very lightweight crawler, so pipelines are turned off

462
00:20:51.680 --> 00:20:52.400
<v Speaker 2>to save memory.

463
00:20:52.559 --> 00:20:53.640
<v Speaker 1>Oh I didn't realize that.

464
00:20:53.839 --> 00:20:57.240
<v Speaker 2>Yeah, So to activate your conveyor belt, you must open

465
00:20:57.359 --> 00:21:02.799
<v Speaker 2>settings dot pie and actually uncomment a specific dictionary named itempipelines.

466
00:21:02.920 --> 00:21:05.640
<v Speaker 1>Ah. So settings dot pie is essentially the control room

467
00:21:05.640 --> 00:21:08.119
<v Speaker 1>of the factory. You uncomment the code to power up

468
00:21:08.119 --> 00:21:09.000
<v Speaker 1>the conveyor.

469
00:21:08.599 --> 00:21:10.680
<v Speaker 2>Belt exactly, and inside that dictionary you list have the

470
00:21:10.759 --> 00:21:13.240
<v Speaker 2>names of your classes, your QA stations, and next to

471
00:21:13.279 --> 00:21:16.759
<v Speaker 2>each class name, you assigned an integer a priority number. Okay,

472
00:21:16.880 --> 00:21:19.759
<v Speaker 2>and Scrape operates on a very strict rule. Here, a

473
00:21:19.839 --> 00:21:22.319
<v Speaker 2>lower number dictates a higher priority.

474
00:21:22.000 --> 00:21:24.240
<v Speaker 1>So it's exactly like a race. First place gets the

475
00:21:24.279 --> 00:21:25.559
<v Speaker 1>number one, so they go first.

476
00:21:25.599 --> 00:21:26.039
<v Speaker 3>Exactly.

477
00:21:26.119 --> 00:21:28.119
<v Speaker 1>So if I assign above one hundred price check a

478
00:21:28.119 --> 00:21:31.160
<v Speaker 1>priority number of one hundred and below fifty price check

479
00:21:31.200 --> 00:21:34.680
<v Speaker 1>a priority number of two hundred, Scrape basically guarantees that

480
00:21:34.720 --> 00:21:37.599
<v Speaker 1>the one hundred check executes first every single time.

481
00:21:37.799 --> 00:21:41.640
<v Speaker 2>Yeap, you hold absolute control over the sequence of transformations.

482
00:21:41.920 --> 00:21:44.000
<v Speaker 2>You can inject new stations, you can reorder them or

483
00:21:44.000 --> 00:21:46.640
<v Speaker 2>turn them off completely, all from the central settings dot

484
00:21:46.720 --> 00:21:50.160
<v Speaker 2>PI file without ever having to touch your underlying spider code.

485
00:21:50.440 --> 00:21:52.559
<v Speaker 1>Man, let's zoom out and look at what we have

486
00:21:52.640 --> 00:21:56.039
<v Speaker 1>constructed today. We didn't just write a script. We architected

487
00:21:56.039 --> 00:21:58.039
<v Speaker 1>a complete resilient system.

488
00:21:58.160 --> 00:21:58.759
<v Speaker 3>We really did.

489
00:21:59.160 --> 00:22:02.279
<v Speaker 1>We started in the scriptshall testing the HTML dawntree to

490
00:22:02.319 --> 00:22:06.720
<v Speaker 1>figure out our XPath navigation. We built a structural blueprint

491
00:22:06.720 --> 00:22:10.079
<v Speaker 1>for our data using the item bento box. We deployed

492
00:22:10.079 --> 00:22:13.200
<v Speaker 1>a spider to loop through rows and continually yield items.

493
00:22:13.799 --> 00:22:17.319
<v Speaker 1>We utilized item loaders acting as mid air interceptors and

494
00:22:17.359 --> 00:22:20.759
<v Speaker 1>oyster shuckers to clean up broken URLs and messy brackets,

495
00:22:21.119 --> 00:22:24.279
<v Speaker 1>and finally we routed everything through a QA conveyor belt

496
00:22:24.319 --> 00:22:26.960
<v Speaker 1>in the pipeline to apply custom business logic.

497
00:22:27.240 --> 00:22:30.640
<v Speaker 2>Moving from a manual task to a fully automated self

498
00:22:30.680 --> 00:22:34.680
<v Speaker 2>cleaning data pipeline completely alters how you viewed data on

499
00:22:34.720 --> 00:22:35.240
<v Speaker 2>the Internet.

500
00:22:35.319 --> 00:22:38.119
<v Speaker 1>It really does. So to make sure the core mechanisms

501
00:22:38.160 --> 00:22:40.440
<v Speaker 1>of this architecture really stick with you, let's see if

502
00:22:40.480 --> 00:22:43.079
<v Speaker 1>we actually internalize the details. A quick review question for

503
00:22:43.079 --> 00:22:45.640
<v Speaker 1>everyone listening. What's your if I run my spider and

504
00:22:45.680 --> 00:22:47.880
<v Speaker 1>I open my CSV file and I find that my

505
00:22:47.920 --> 00:22:52.000
<v Speaker 1>spreadsheet is full of data trapped inside those annoying list brackets,

506
00:22:52.839 --> 00:22:55.079
<v Speaker 1>what is the one word fix I forgot to implement

507
00:22:55.119 --> 00:22:56.000
<v Speaker 1>in my item loader?

508
00:22:56.119 --> 00:22:59.200
<v Speaker 2>You forgot your oyster shuck the take first output processor

509
00:22:59.319 --> 00:22:59.960
<v Speaker 2>take first.

510
00:23:00.400 --> 00:23:02.920
<v Speaker 1>It is such a tiny detail in the grand architecture,

511
00:23:02.960 --> 00:23:05.680
<v Speaker 1>but you know, knowing the default tools available in the

512
00:23:05.680 --> 00:23:09.880
<v Speaker 1>framework is exactly what separates a fragile, messy script from

513
00:23:09.960 --> 00:23:12.319
<v Speaker 1>a professional, production ready pipeline.

514
00:23:12.400 --> 00:23:16.480
<v Speaker 2>Absolutely, a professional pipeline is designed to be resilient, but

515
00:23:16.640 --> 00:23:18.880
<v Speaker 2>you know there is an external factor that even the

516
00:23:18.880 --> 00:23:21.519
<v Speaker 2>best pipeline cannot inherently control.

517
00:23:21.240 --> 00:23:22.440
<v Speaker 1>The web itself.

518
00:23:22.160 --> 00:23:26.359
<v Speaker 2>Exactly the web itself. Our entire beautifully calibrated system relies

519
00:23:26.359 --> 00:23:30.279
<v Speaker 2>on XPath selectors. We gave our spider rigid directions based

520
00:23:30.319 --> 00:23:32.079
<v Speaker 2>on the current lay out of the website. We told

521
00:23:32.079 --> 00:23:34.720
<v Speaker 2>it navigate into the table, drop down into the rows,

522
00:23:34.799 --> 00:23:36.440
<v Speaker 2>find the solid index too, right.

523
00:23:36.519 --> 00:23:39.680
<v Speaker 1>So what happens when Yahoo Finance decides to just refresh

524
00:23:39.680 --> 00:23:42.640
<v Speaker 1>their brand overnight, like they roll out massive UI redesign.

525
00:23:42.920 --> 00:23:46.000
<v Speaker 1>They ditch HTML tables entirely and move to a modern

526
00:23:46.000 --> 00:23:46.640
<v Speaker 1>grid layout.

527
00:23:46.880 --> 00:23:49.480
<v Speaker 2>The moment they push that update, the structure of the

528
00:23:49.640 --> 00:23:54.599
<v Speaker 2>HTML tree fundamentally changes. Your XPath directions become completely useless.

529
00:23:55.200 --> 00:23:57.680
<v Speaker 2>The spider navigates to where index two used to be

530
00:23:58.039 --> 00:24:01.720
<v Speaker 2>and finds nothing or worse. Or worse, it finds entirely

531
00:24:01.720 --> 00:24:03.720
<v Speaker 2>different data, like grabbing the market caap instead of the

532
00:24:03.759 --> 00:24:07.160
<v Speaker 2>company name, and blindly feeds that bad data straight through

533
00:24:07.200 --> 00:24:09.480
<v Speaker 2>your beautiful pipeline into your final spreadsheet.

534
00:24:09.599 --> 00:24:12.759
<v Speaker 1>The pipeline executed perfectly, but the map it used was

535
00:24:12.799 --> 00:24:16.039
<v Speaker 1>completely obsolete. It highlights a massive challenge in this field,

536
00:24:16.519 --> 00:24:18.640
<v Speaker 1>because now that you understand how to build a scripey

537
00:24:18.720 --> 00:24:22.880
<v Speaker 1>pipeline that collects cleans and transforms data. The next logical

538
00:24:22.920 --> 00:24:26.319
<v Speaker 1>frontier is resiliency. How do you design systems that don't

539
00:24:26.319 --> 00:24:29.640
<v Speaker 1>just extract data based on today's layout, but can intelligently

540
00:24:29.720 --> 00:24:32.720
<v Speaker 1>hunt for that data tomorrow, adapting seamlessly when the digital

541
00:24:32.759 --> 00:24:35.759
<v Speaker 1>landscape shifts completely underneath them. Something to think about.
