sobre Web Scraping

---------------------------------------------------------------------------------------------------------------

pip install requests ; para hacer requerimientos a un servidor

pip install beautifulsoup4 : para parcer los HTML

pip install lxml : para parcer los HTML

pip install selenium : para hacer extracciones dinámicas

pip install Pillow : para hacer extracciones de imágenes

pip install pymongo : para hacer guardado de información en base de datos

si hay problemas usar --user al final, da permisos de administrador, sudo para linux

pip install scrapy

---------------------------------------------------------------------------------------------------------------

tipos de web-scraping

nivel 1: tipo estático, donde toda la información permanece en una página web y no hay cargas del tipo dinámico.

librerías a usar:

  1. requests: para hacer requerimientos (pip install requests)
  2. xml y BeautifulSoup para parcear los requerimientos y extraer informacion
  3. scrapy para realizar requerimientos, parcearlos y extraer información
nivel 2: tipo estático con varias paginas con el mismo dominio, puede ser horizontal(llamado crollin horizontal) que es cuando tiene varias páginas en la parte inferior y se dirige a una página del mismo dominio y crollin vertical que es cuando de va accediendo al detalle de los elementos de la misma página.

librerías a usar:

  1. scrapy para realizar requerimientos, parcearlos y extraer información

nivel 3:tipo dinámico, donde se automatiza las acciones de un navegador (mediante python por ej) 

librerías a usar:

  1. Selenium python
nivel 4: usos de apis

nivel 5: donde se expande este mundo con
  • Autenticación
  • captchas
  • iFrames 

pasos a seguir para hacer web scraping 

  1. Se define una URL semilla, la pagina principal de donde se extraen los datos
  2. Realizar los requerimientos (requests)
  3. Obtener respuesta del servidor (en formato HTML)
  4. Se extrae la información deseada del HTML
  5. Se repite el paso 2 con otras URL del mismo dominio (dentro del crollin vertical/horizontal)

para el paso 4, como se extrae la información del HTML mediante XPATH
    XPATH: es un lenguaje que nos permite construir expresiones que recorren y procesan un documento XML. un HTML es un documento del tipo XML

al momento de armar un xpath se tienen en cuenta
  • los ejes (axis) da pie donde se realizará la búsqueda (ej: mediante // se busca en TODO el documento, con  / solo en la raíz y con ./ es una búsqueda relativa al lugar en el que se está)
  • el nodo de búsqueda (step) que es el nombre del tag del elemento en el que hacemos foco.
  • se definen los predicador, para pulir mas la búsqueda, por medio del usos de los atributos del tag, los atributos tienen un nombre y un valor  

ejemplo



para seleccionar page con el titulo matemáticas , puede hacerse mediante

//page[@title='Clase']/page[@title='2005']/page[@title='Matemáticas']
apretando shift y posando el mouse sobre la palabra sugiere...
//page[2]/page[2]/page[2]/@title 

el eje(axis) es el //, el nodo(step) el page y los predicados van dentro de [ ]  habiendo claro, muchas formas de construirlos. Se pueden indexar las búsquedas.

si van a la pagina de práctica y usan el siguiente código...
-------------------------------------- inicio codigo --------------------------------------
<app>
    <welcome-message>Hi! This is xpather beta...</welcome-message>
    <abstract>
        This web app enables you to query XML/HTML documents with your
browser in real time. It can generate queries for you too! 
    </abstract>
    <description>
        <subject>
You can enter your xpath query in the top-left panel 
and it will be instantly executed against this document.
Once some results are displayed on the right, you can 
scroll to them by clicking on them. 
</subject>
<subject>
To generate an xpath query for a specific element,
please hold CTRL and hover over it.
An xpath is generated heuristically with the aim
to be unambiguous and the shortest possible.
</subject>
    </description>
<extra-notes>
<note>
None of entered documents leave your computer because all
the processing is done by your powerful browser!
(of course as long as you do not save your input)
</note>
        <note>
This application is in an early beta version so please
be forgiving. XPath 2.0 is supported but namespaces are
still being added and they may not fully work yet. 
Please send your comments to: xpather.com@gmail.com
</note>
<note>
By default XML mode is used but if a document cannot
be parsed as XML then HTML mode kicks in.
</note>
<note>
Pasting documents bigger than 500kb may cause your
browser become sluggish or unresponsive.
</note>
</extra-notes>
</app>
-------------------------------------- fin codigo --------------------------------------
y quieren extraer el texto del último note pueden hacerlo mediante //note[last()]/text() acá se observa el uso de función como last() y text()
hay otros como...
position()=<numero>
contains(<tag(ej. @id)>,<cadena string(ej. "Matem")>) #si dentro de un tag contiene un tipo de cadena de string.
not # para negar un predicado
text() # extrae el texto

mas info en https://developer.mozilla.org/es/docs/Web/XPath/Functions (algunas entradas fallan)

webs de interés sobre xml y xpath

Probar expresiones en caliente
al apretar F12 podemos inspeccionar la pagina en la que estemos, en console podemos usar... 
$x("<expresion XPATH>")


mecanismos
teniendo...
import requests
from lxml import html

encabezados = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
}

url = "https://www.wikipedia.org/"

respuesta = requests.get(url, headers=encabezados)
requests = respuesta.text #solo lo convierte a texto plano
parser = html.fromstring(requests) #convierte el requests en un parceador, para extraer datos.
dato = parser.get_element_by_id("Matemática") # obtener elemento con id = "Matemática", entrega objeto de tipo elemento porque es una clase
dato_texto = dato.text_content() #para extrar el dato "Matemática" y poder imprimirlo, por ej.


# extraccion de datos usando beautifulSoup
import requests
from bs4 import BeautifulSoup

encabezados = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
}
# primer paso, definimos URL semilla
url = 'https://stackoverflow.com/questions'
respuesta = requests.get(url, headers=encabezados)
soup = BeautifulSoup(respuesta.text)
contenedor_de_preguntas = soup.find(id='questions')
lista_de_preguntas = contenedor_de_preguntas.find_all('div', class_='question-summary')
for pregunta in lista_de_preguntas:
titulo_pregunta = pregunta.find('h3').text
descripcion_pregunta = pregunta.find(class_='excerpt').text
descripcion_pregunta = descripcion_pregunta.replace('\n', '').replace('\r', '').strip()
soup.find() #busca según determinado parámetro
contenedor_de_preguntas.find_all() #busca todos los elementos que cumplan la función, entrega una lista.
se usa class_ porque class es una palabra reservada de python.
descripcion_pregunta.replace('\n', '').replace('\r', '').strip() #mediante estos códigos se limpia el resultado

INDICE