Skip to content

Commit 71c5ff5

Browse files
Ejemplo de web scraping con Selenium
1 parent f9a0364 commit 71c5ff5

1 file changed

Lines changed: 378 additions & 1 deletion

File tree

src/Cap2/scrap.ipynb

Lines changed: 378 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,378 @@
1-
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Big Data con Python\n",
8+
"\n",
9+
"#### Rafael Caballero, Enrique Martín y Adrián Riesco. Editorial RC libros\n",
10+
"\n",
11+
"## Capítulo 2: ejemplo de web scraping. Acceso a los datos del catastro\n"
12+
]
13+
},
14+
{
15+
"cell_type": "markdown",
16+
"metadata": {},
17+
"source": [
18+
"El propósito de este notebook es mostrar como hacer web scraping de datos de una página, en este ejemplo del catastro, que nos exige introducir previamente datos e interaccionar, en este caso seleccionando pestañas y pulsando botones.\n",
19+
"\n",
20+
"En particular utilizaremos la biblioteca *Selenium* que nos permite obtener automáticamente datos de páginas web dinámicas. Selenium está pensado realmente para automatizar pruebas de entornos web, pero a nosotros nos servirá para nuestro propósito de hacer web scraping.\n",
21+
"\n",
22+
"En particular, lo que vamos a hacer es arrancar google Chrome y manejarlo automáticamente desde Python.\n",
23+
"\n",
24+
"\n",
25+
"\n",
26+
"**Preparación**\n",
27+
"\n",
28+
"\n",
29+
"Para ello necesitamos 3 cosas:\n",
30+
"\n",
31+
"1.- Tener google Chrome\n",
32+
"\n",
33+
"2.- Instalar la biblioteca selenium (pip install selenium)\n",
34+
"\n",
35+
"3.- Tener un fichero controlador, un driver, de nombre *chromedriver.exe*. En nuestro caso supondremos que se encuentra en la carpeta c:/hlocal/tdm. El driver correspondiente a la versión de Chrome que tengamos se puede descargar de https://sites.google.com/a/chromium.org/chromedriver/downloads"
36+
]
37+
},
38+
{
39+
"cell_type": "markdown",
40+
"metadata": {},
41+
"source": [
42+
"\n",
43+
"#### Paso 1: abrir navegador\n",
44+
"Comenzamos abriendo una sesión de Chrome de forma automática\n",
45+
"\n",
46+
"\n",
47+
"**Errores comunes**\n",
48+
"\n",
49+
"Es posible que al ejecutar este código obtengamos un error del tipo:\n",
50+
" \n",
51+
" SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 87. Current browser version is 90.0.4430.212 with binary path.....\n",
52+
" \n",
53+
" o similar. Esto indica que nuestra versión del driver no corresponde con la de nuestro navegador. La versión de Chrome, aunque nos la da el mensaje, la podemos consultar en el propio navegador, en *Configuración* (dentro del menú que se abre al hacer click sobre los 3 puntitos verticales, arriba a la derecha) + *Información de Chrome*.\n",
54+
" \n",
55+
" Con esta información iremos a https://sites.google.com/a/chromium.org/chromedriver/downloads y descargaremos y descomprimiremos el fichero chromedriver correspondiente y ponemos el path correspondiente en la variable chromedriver\n",
56+
" \n",
57+
" \n",
58+
" Otro error que podemos obtener es alguno del tipo *FileNotFound* que se deberá, casi con seguridad a que debemos cambiar el path almacenado en la variable chromedriver del siguiente código\n",
59+
"\n",
60+
"\n",
61+
"**Importante**\n",
62+
"Una vez que logremos ques e abra el navegador no debemos teclear nada en él, el control lo llevaremos desde el programa en Python"
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": 1,
68+
"metadata": {},
69+
"outputs": [],
70+
"source": [
71+
"chromedriver = \"c:/hlocal/tdm/chromedriver.exe\" # cambiar esta variable con el path a nuestro chromedriver\n",
72+
"import os\n",
73+
"from selenium import webdriver # si da error, desde anaconda prompt hacer pip install --user selenium\n",
74+
"os.environ[\"webdriver.chrome.driver\"] = chromedriver\n",
75+
"chrome_options = webdriver.ChromeOptions()\n",
76+
"chrome_options.add_argument('--no-sandbox')\n",
77+
"driver = webdriver.Chrome(executable_path=chromedriver,options=chrome_options)"
78+
]
79+
},
80+
{
81+
"cell_type": "markdown",
82+
"metadata": {},
83+
"source": [
84+
"### Paso 2: cargar página\n",
85+
"Una vez abierto el navegador lo siguiente es cargar la página que deseemos, en este caso la del catastro. Debemos ver cómo se carga la página correspondiente"
86+
]
87+
},
88+
{
89+
"cell_type": "code",
90+
"execution_count": 8,
91+
"metadata": {},
92+
"outputs": [],
93+
"source": [
94+
"url = 'https://www1.sedecatastro.gob.es/CYCBienInmueble/OVCBusqueda.aspx'\n",
95+
"driver.get(url)"
96+
]
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"metadata": {},
101+
"source": [
102+
"### Paso 3, interacción con la página\n",
103+
"\n",
104+
"Ahora queremos seleccionar la pestaña coordenadas, ya que vamos a introducir las coordenadas de un lugar concreto. Esto se hace en dos fases: primero se selecciona el elemento y luego interaccionamos con él. En este caso comprobamos viendo el código fuente que la etiqueta COORDENADAS es un enlace, sobre el que deseamos hacer click\n"
105+
]
106+
},
107+
{
108+
"cell_type": "code",
109+
"execution_count": 9,
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"coord = driver.find_element_by_link_text(\"COORDENADAS\")\n",
114+
"coord.click()"
115+
]
116+
},
117+
{
118+
"cell_type": "markdown",
119+
"metadata": {},
120+
"source": [
121+
"Ya en la pestaña, introducimos las coordenadas y hacemos click para buscar la información. En este ejemplo hemos puesto las coordenadas long=1.893817, lat=41.545639, pero pueden ser otras cualesquiera"
122+
]
123+
},
124+
{
125+
"cell_type": "code",
126+
"execution_count": 10,
127+
"metadata": {},
128+
"outputs": [],
129+
"source": [
130+
"lat = driver.find_element_by_id(\"ctl00_Contenido_txtLatitud\")\n",
131+
"lon = driver.find_element_by_id(\"ctl00_Contenido_txtLongitud\")\n",
132+
"latitud = \"41.545639 \"\n",
133+
"longitud = \"1.893817\"\n",
134+
"lat.send_keys(latitud)\n",
135+
"lon.send_keys(longitud)\n",
136+
"\n",
137+
"datos = driver.find_element_by_id(\"ctl00_Contenido_btnDatos\")\n",
138+
"datos.click()"
139+
]
140+
},
141+
{
142+
"cell_type": "code",
143+
"execution_count": null,
144+
"metadata": {},
145+
"outputs": [],
146+
"source": [
147+
"Ahora supongamos que queremos saber el uso principal de este inmueble, para ellos buscamos "
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": 11,
153+
"metadata": {},
154+
"outputs": [
155+
{
156+
"name": "stdout",
157+
"output_type": "stream",
158+
"text": [
159+
"7801701DF0070S0001QY \n",
160+
"Religioso\n"
161+
]
162+
}
163+
],
164+
"source": [
165+
"xpath = \"//*[./span/text()='Referencia catastral']//label\"\n",
166+
"etiqs = driver.find_element_by_xpath(xpath)\n",
167+
"print(etiqs.text)\n",
168+
"xpath = \"//*[./span/text()='Uso principal']//label\"\n",
169+
"etiqs = driver.find_element_by_xpath(xpath)\n",
170+
"print(etiqs.text)"
171+
]
172+
},
173+
{
174+
"cell_type": "markdown",
175+
"metadata": {},
176+
"source": [
177+
"### Otras pruebas"
178+
]
179+
},
180+
{
181+
"cell_type": "markdown",
182+
"metadata": {},
183+
"source": [
184+
"Texto de la página"
185+
]
186+
},
187+
{
188+
"cell_type": "code",
189+
"execution_count": null,
190+
"metadata": {},
191+
"outputs": [],
192+
"source": [
193+
"html = driver.find_element_by_xpath(\"/html\")\n",
194+
"print(html.text)"
195+
]
196+
},
197+
{
198+
"cell_type": "markdown",
199+
"metadata": {},
200+
"source": [
201+
"Caminos absolutos"
202+
]
203+
},
204+
{
205+
"cell_type": "code",
206+
"execution_count": null,
207+
"metadata": {},
208+
"outputs": [],
209+
"source": [
210+
"head = driver.find_element_by_xpath(\"/html/head\")\n",
211+
"body = driver.find_element_by_xpath(\"/html/body\")\n",
212+
"html2 = body.find_element_by_xpath(\"/html\")"
213+
]
214+
},
215+
{
216+
"cell_type": "markdown",
217+
"metadata": {},
218+
"source": [
219+
"Hijos de un elemento"
220+
]
221+
},
222+
{
223+
"cell_type": "code",
224+
"execution_count": null,
225+
"metadata": {},
226+
"outputs": [],
227+
"source": [
228+
"hijos = driver.find_elements_by_xpath(\"/html/body/*\")\n",
229+
"for element in hijos:\n",
230+
" print(element.tag_name)"
231+
]
232+
},
233+
{
234+
"cell_type": "markdown",
235+
"metadata": {},
236+
"source": [
237+
"Camino relativo"
238+
]
239+
},
240+
{
241+
"cell_type": "code",
242+
"execution_count": null,
243+
"metadata": {},
244+
"outputs": [],
245+
"source": [
246+
"divs = driver.find_elements_by_xpath(\"/html/body/*/div\")\n",
247+
"print(len(divs))"
248+
]
249+
},
250+
{
251+
"cell_type": "code",
252+
"execution_count": null,
253+
"metadata": {},
254+
"outputs": [],
255+
"source": [
256+
"divs = body.find_elements_by_xpath(\"./*/div\")\n",
257+
"print(len(divs))"
258+
]
259+
},
260+
{
261+
"cell_type": "markdown",
262+
"metadata": {},
263+
"source": [
264+
"Saltar pasos intermedios"
265+
]
266+
},
267+
{
268+
"cell_type": "code",
269+
"execution_count": null,
270+
"metadata": {},
271+
"outputs": [],
272+
"source": [
273+
"divs = driver.find_elements_by_xpath(\"/html/body//div\")\n",
274+
"print(len(divs))"
275+
]
276+
},
277+
{
278+
"cell_type": "code",
279+
"execution_count": null,
280+
"metadata": {},
281+
"outputs": [],
282+
"source": [
283+
"labels = driver.find_elements_by_xpath(\"//label\")\n",
284+
"print(len(labels))"
285+
]
286+
},
287+
{
288+
"cell_type": "markdown",
289+
"metadata": {},
290+
"source": [
291+
"Insertar texto"
292+
]
293+
},
294+
{
295+
"cell_type": "code",
296+
"execution_count": null,
297+
"metadata": {},
298+
"outputs": [],
299+
"source": [
300+
"id = \"ctl00_Contenido_tblInmueble\"\n",
301+
"div = driver.find_element_by_id(id)\n",
302+
"label = div.find_element_by_xpath(\"//label\")\n",
303+
"print(label.text)"
304+
]
305+
},
306+
{
307+
"cell_type": "code",
308+
"execution_count": null,
309+
"metadata": {},
310+
"outputs": [],
311+
"source": [
312+
"xpath = \"//*[./span/text()='Referencia catastral']//label\"\n",
313+
"etiqs = driver.find_element_by_xpath(xpath)\n",
314+
"print(etiqs.text)"
315+
]
316+
},
317+
{
318+
"cell_type": "code",
319+
"execution_count": null,
320+
"metadata": {},
321+
"outputs": [],
322+
"source": [
323+
"clase = driver.find_elements_by_xpath(\"(//label)[position()=3]\")\n",
324+
"print(clase[0].text)\n",
325+
"\n",
326+
"etiqs = driver.find_elements_by_xpath(\"//label\")\n",
327+
"print(etiqs[2].text)\n",
328+
"\n",
329+
"ulti = driver.find_elements_by_xpath(\"(//label)[last()]\")\n",
330+
"print(ulti[0].text)\n"
331+
]
332+
},
333+
{
334+
"cell_type": "code",
335+
"execution_count": null,
336+
"metadata": {},
337+
"outputs": [],
338+
"source": [
339+
"driver.close()"
340+
]
341+
},
342+
{
343+
"cell_type": "markdown",
344+
"metadata": {},
345+
"source": [
346+
"Por Rafael Caballero. Del libro \"Big data con Python\""
347+
]
348+
},
349+
{
350+
"cell_type": "code",
351+
"execution_count": null,
352+
"metadata": {},
353+
"outputs": [],
354+
"source": []
355+
}
356+
],
357+
"metadata": {
358+
"kernelspec": {
359+
"display_name": "Python 3",
360+
"language": "python",
361+
"name": "python3"
362+
},
363+
"language_info": {
364+
"codemirror_mode": {
365+
"name": "ipython",
366+
"version": 3
367+
},
368+
"file_extension": ".py",
369+
"mimetype": "text/x-python",
370+
"name": "python",
371+
"nbconvert_exporter": "python",
372+
"pygments_lexer": "ipython3",
373+
"version": "3.8.5"
374+
}
375+
},
376+
"nbformat": 4,
377+
"nbformat_minor": 2
378+
}

0 commit comments

Comments
 (0)