Desarrollador Full Stack y orgulloso co-organizor de la comunidad Open Source Weekends (OSW)
Colaborador activo en la Comunidad Open Source
Trabaja como freelance, además de ser profesor en Fictizia.
Sin live coding ni ejecución de demos
Sin teoría pesada
Se adapta el nivel para tod@s (mayoría)
Una charla ofrecida por Fictizia sobre el arte de extraer datos de cualquier lugar usando librerías de Web Scraping como X-RAY, Cheerio (Node.js) o Beautiful Soup (Python) y automatizando las tareas más aburridas y repetitivas (login, clicks automáticos, completar formularios…) para hacer cosas útiles con la información obtenida usando Node.js, Python, CRON Jobs…
Web scraping es una técnica utilizada mediante programas de software para extraer información de sitios web. Usualmente, estos programas simulan la navegación de un humano en la World Wide Web ya sea utilizando el protocolo HTTP manualmente, o incrustando un navegador en una aplicación. - Wikipedia
Un rastreador web, indexador web, indizador web o araña web es un programa informático que inspecciona las páginas del World Wide Web de forma metódica y automatizada. Uno de los usos más frecuentes que se les da consiste en crear una copia de todas las páginas web visitadas para su procesado posterior por un motor de búsqueda que indexa las páginas proporcionando un sistema de búsquedas rápido. Las arañas web suelen ser bots. - Wikipedia
Este protocolo es consultivo. Confía en la cooperación de los robots del sitio Web, de modo que marca una o más áreas de un sitio fuera de los límites de búsqueda con el uso de un archivo robots.txt, aunque este no necesariamente garantice aislamiento completo. (...) En algunos casos el incluir un directorio en este archivo le anuncia su presencia a posibles hackers, así ellos pueden determinar fácilmente algunos softwares usados en el sitio mediante buscar "huellas típicas" en el robots.txt. - Wikipedia
User-agent: *
Disallow: /cgi-bin/
Disallow: /images/
Disallow: /tmp/
Disallow: /private/
¿Qué hace un buscador?
Imagen cortesia prowebscraping.com
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│ href │
├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤
│ protocol │ │ auth │ host │ path │ hash │
│ │ │ ├──────────────┬──────┼──────────┬────────────────┤ │
│ │ │ │ hostname │ port │ pathname │ search │ │
│ │ │ │ │ │ ├─┬──────────────┤ │
│ │ │ │ │ │ │ │ query │ │
" https: // user : pass @ sub.host.com : 8080 /p/a/t/h ? query=string #hash "
│ │ │ │ │ hostname │ port │ │ │ │
│ │ │ │ ├──────────────┴──────┤ │ │ │
│ protocol │ │ username │ password │ host │ │ │ │
├──────────┴──┼──────────┴──────────┼─────────────────────┤ │ │ │
│ origin │ │ origin │ pathname │ search │ hash │
├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤
│ href │
└─────────────────────────────────────────────────────────────────────────────────────────────┘
(all spaces in the "" line should be ignored -- they are purely for formatting)
Imagen cortesia MDN
Imagen cortesia Mozilla.org
Este tema, cobró gran importancia en nuestro país allá en el año 2012, a raíz de la Sentencia del Tribunal Supremo de 9 de octubre, nº 572/2012, de RyanAir VS Atrápalo, en la cual se determinó que, en ese caso, el web scraping llevado a cabo por Atrápalo era legal. Si bien esta decisión señaló que no todo web scraping lo era, la importancia de esta sentencia radica en el hecho de que el Tribunal Supremo considerase legales las técnicas de web scraping, siempre y cuando, eso sí, se cumpliesen una serie de condiciones. - ecija.com
Puntos importantes:
Por tanto, y a pesar del atractivo y facilidades en la utilización de las técnicas de web scraping en nuestro negocio para nuestro propio beneficio, antes de decantarnos por su utilización deberemos actuar con cautela, plantearnos una posible confrontación entre nuestra finalidad y la del propio website y realizar un análisis previo de las páginas objeto de scraping así como de sus términos y condiciones de uso, garantizando, en todo caso, que no se está incurriendo en una actividad ilegal en base a todos los puntos anteriormente expuestos. - ecija.com
Consulta los detalles con un abogad@ especialista en esta materia.
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY
Posibles alternativas
La parte genial de esto:
Creando un algoritmo propio
Soluciones Comerciales
Browser automation enables you to programmatically control a browser. For example, you could do some of the following:
- Observe product pricing updates on an online store to discover the best time to purchase a particular product.
- Log into your online banking account to download statements on a periodic basis.
- Write functional tests or acceptance tests against a website you develop, in order to validate user functionality.
- Complete a long and tedious HTML form which typically requires repetitive manual entry.
All modern browsers may be automated, including Chrome, Firefox, Edge & Safari. - Sitepen
Notice that the browser has supporting elements for your use, such as a menu bar, address bar, and toolbar. These items are part of the GUI (Graphical User Interface). A headless browser has no GUI and no visual components. It runs as a process, and will expose a mechanism to enable outside interaction from source code or other software programs. - Sitepen
Juego del gato y el ratón
Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
Documentation | Github | Web
Scrapy - Scrapy, a fast high-level web crawling & scraping framework for Python
Beautiful Soup - Python library for pulling data out of HTML and XML files.
Request - Python HTTP Requests for Humans™
pyspider - A powerful spider system.
PDFMiner - A tool for extracting information from PDF documents.
Ghost.py - wrapper of QtWebKit (requires PyQT)
WikiTeam - Tools for downloading and preserving wikis.
phantomjs - Scriptable Headless WebKit.
slimerjs - A PhantomJS-like tool running Gecko.
casperjs - Navigation scripting & testing utility for PhantomJS and SlimerJS.
zombie - Insanely fast, full-stack, headless browser testing using node.js.
nightmare - Nightmare is a high level wrapper for PhantomJS that lets you automate browser tasks
nightwatch - Automated testing and continous integration framework based on node.js and selenium webdriver
webdriverio - A Node.js bindings implementation for the W3C WebDriver protocol
A headless browser is a web browser without a graphical user interface.
Headless browsers provide automated control of a web page in an environment similar to popular web browsers, but are executed via a command-line interface or using network communication.
chrome \
--headless \ # Runs Chrome in headless mode.
--disable-gpu \ # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \
https://www.chromestatus.com # URL to open. Defaults to about:blank.
const chromeLauncher = require('chrome-launcher');
chromeLauncher.launch({
startingUrl: 'https://google.com',
chromeFlags: ['--headless', '--disable-gpu']
}).then(chrome => {
console.log(`Chrome debugging port running on ${chrome.port}`);
});
The Chrome Developer Tools are a set of web authoring and debugging tools built into Google Chrome. The DevTools provide web developers deep access into the internals of the browser and their web application.
npm i --save chrome-remote-interface
/*
The following snippet loads https://github.com
and dumps every request made
*/
const CDP = require('chrome-remote-interface');
CDP((client) => {
// extract domains
const {Network, Page} = client;
// setup handlers
Network.requestWillBeSent((params) => {
console.log(params.request.url);
});
Page.loadEventFired(() => {
client.close();
});
// enable events then start!
Promise.all([
Network.enable(),
Page.enable()
]).then(() => {
return Page.navigate({url: 'https://github.com'});
}).catch((err) => {
console.error(err);
client.close();
});
}).on('error', (err) => {
// cannot connect to the remote endpoint
console.error(err);
});
Headless Chrome Node API
npm i --save puppeteer
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://fictizia.com');
await page.screenshot({path: 'fictizia.png'});
await browser.close();
})();
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
await page.pdf({path: 'hn.pdf', format: 'A4'});
await browser.close();
})();
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// Get the "viewport" of the page, as reported by the page.
const dimensions = await page.evaluate(() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio
};
});
console.log('Dimensions:', dimensions);
await browser.close();
})();
Buscamos alojamiento en Berlin usando Booking.com, guardamos un screenshot e imprimimos el top 10
/**
* @name Booking.com search
* @see {@link https://github.com/checkly/puppeteer-examples/blob/master/2.%20search/booking.js}
* @desc Finds accommodations in Berlin on Booking.com, takes a screenshot and logs the top 10.
*/
const puppeteer = require('puppeteer')
const screenshot = 'booking_results.png'
try {
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://booking.com')
await page.type('#ss', 'Berlin')
await page.click('.sb-searchbox__button')
await page.waitForSelector('#hotellist_inner')
await page.screenshot({ path: screenshot })
const hotels = await page.evaluate(() => {
const anchors = Array.from(document.querySelectorAll('span.sr-hotel__name'))
return anchors.map(anchor => anchor.textContent.trim()).slice(0, 10)
})
console.log(hotels)
await browser.close()
console.log('See screenshot: ' + screenshot)
})()
} catch (err) {
console.error(err)
}
Logearse en Github y generando un snapshot
/**
* @name Github
* @see {@link https://github.com/checkly/puppeteer-examples/blob/master/3.%20login/github.js}
* @desc Logs into Github. Provide your username and password as environment variables when running the script, i.e:
* `GITHUB_USER=myuser GITHUB_PWD=mypassword node github.js`
*
*/
const puppeteer = require('puppeteer')
const screenshot = 'github.png';
(async () => {
const browser = await puppeteer.launch({headless: true})
const page = await browser.newPage()
await page.goto('https://github.com/login')
await page.type('#login_field', process.env.GITHUB_USER)
await page.type('#password', process.env.GITHUB_PWD)
await page.click('[name="commit"]')
await page.waitForNavigation()
await page.screenshot({ path: screenshot })
browser.close()
console.log('See screenshot: ' + screenshot)
})()
Descargar la documentación de la web de Puppeteer en PDF (A4 Multipagina)
/**
* @name pdf
* @desc Renders a PDF of the Puppeteer API spec. This is a pretty long page and will generate a nice, A4 size multi-page PDF.
* @see {@link https://github.com/checkly/puppeteer-examples/blob/master/1.%20basics/pdf.js}
* @see {@link https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pdf}
*/
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pdf')
await page.pdf({ path: 'api.pdf', format: 'A4' })
await browser.close()
})()
Número de datasets listados en data.gov
# Number of datasets currently listed on data.gov
# https://github.com/stanfordjournalism/search-script-scrape/blob/master/scripts/1.py
from lxml import html
import requests
response = requests.get('http://www.data.gov/')
doc = html.fromstring(response.text)
link = doc.cssselect('small a')[0]
print(link.text)
Número de personas que visitan webs del gobierno americano con IE 6.0
# The number of people who visited a U.S. government website using Internet Explorer 6.0 in the last 90 days
# https://github.com/stanfordjournalism/search-script-scrape/blob/master/scripts/3.py
import requests
r = requests.get("https://analytics.usa.gov/data/live/ie.json")
print(r.json()['totals']['ie_version']['6.0'])
Número de alertas vigentes del departamento de estado de USA para viajes internacionales
# The number of international travel alerts from the U.S. State Department currently in effect
# https://github.com/stanfordjournalism/search-script-scrape/blob/master/scripts/47.py
import requests
from lxml import html
url = 'http://travel.state.gov/content/passports/english/alertswarnings.html'
doc = html.fromstring(requests.get(url).text)
print(len(doc.cssselect('td.alert')))
El número de personas en la Lista de los más buscados del FBI por crímenes de guante blanco
# The number of people on FBI's Most Wanted List for white collar crimes
# https://github.com/stanfordjournalism/search-script-scrape/blob/master/scripts/54.py
import requests
from lxml import html
url = 'http://www.fbi.gov/wanted/wcc/@@wanted-group-listing'
doc = html.fromstring(requests.get(url).text)
print(len(doc.cssselect('.contenttype-FBIPerson')))
La escuela de New York con el ratio más alto de excepciones religiosas para vacunas
# The New York school with the highest rate of religious exemptions to vaccinations
# https://github.com/stanfordjournalism/search-script-scrape/blob/master/scripts/97.py
import requests
url = 'https://health.data.ny.gov/resource/5pme-xbs5.json'
data = requests.get(url).json()
def foo(d):
return float(d['percentreligiousexemptions'])
school = max([r for r in data if '2014' in r['report_period']], key = foo)
print(school['schoolname'])
101 real world web scraping exercises in Python 3 for data journalists
Puppeteer example scripts for running Headless Chrome from Node. Run them at https://trypuppeteer.com
101 real world web scraping exercises in Python 3 for data journalists
APIs externas de inteligencia Artificial (api.ai, GCloud, AWS, Watson, etc...)
IA in the house (Tensorflow, OpenCV, etc...)
Análisis de textos (semántica, expresiones regulares)
Mezclando datos con Datos abiertos
Mezclando datos con APIs específicas (Fullcontact, OWM, etc...)
Montar una API Rest
Utilizar un sistema de WebSockets
Facilitar acceso por Base de datos
Sistema de queries de pago en bases de datos analíticas
Venta de información puntual o cíclica
Servicios Freemium (newsletters, etc..)
Los sueños son sumamente importantes. Nada se hace sin que antes se imagine.
- George Lucas