<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.jrg9.com/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.jrg9.com/blog/" rel="alternate" type="text/html" /><updated>2024-11-29T22:13:25+00:00</updated><id>https://www.jrg9.com/blog/feed.xml</id><title type="html">Blog of Jorge L Castro</title><subtitle>Blog of my journey into a Data Science career</subtitle><author><name>Jorge L Castro</name></author><entry><title type="html">Comparativas hdparm</title><link href="https://www.jrg9.com/blog/2024/11/29/Comparativas-hdparm.html" rel="alternate" type="text/html" title="Comparativas hdparm" /><published>2024-11-29T00:00:00+00:00</published><updated>2024-11-29T00:00:00+00:00</updated><id>https://www.jrg9.com/blog/2024/11/29/Comparativas%20hdparm</id><content type="html" xml:base="https://www.jrg9.com/blog/2024/11/29/Comparativas-hdparm.html"><![CDATA[<p>comando:</p>

<h3 id="raspberry-pi-4">Raspberry pi 4</h3>
<p><code class="language-plaintext highlighter-rouge">sudo hdparm -tT /dev/mmcblk0</code></p>

<p>Resultado:
<code class="language-plaintext highlighter-rouge">/dev/mmcblk0:</code>
` Timing cached reads:   1858 MB in  2.00 seconds = 929.98 MB/sec<code class="language-plaintext highlighter-rouge">
</code> Timing buffered disk reads: 104 MB in  3.03 seconds =  34.32 MB/sec`</p>

<h3 id="raspberry-pi-5">Raspberry pi 5</h3>
<p>sudo hdparm -tT /dev/nvme0n1p2</p>

<p>Resultado:
<code class="language-plaintext highlighter-rouge">/dev/nvme0n1p2:</code>
 <code class="language-plaintext highlighter-rouge">Timing cached reads:   9144 MB in  2.00 seconds = 4576.47 MB/sec</code>
 <code class="language-plaintext highlighter-rouge">Timing buffered disk reads: 2658 MB in  3.00 seconds = 885.48 MB/sec</code></p>

<h3 id="lap-hp">Lap HP</h3>
<p><code class="language-plaintext highlighter-rouge">/dev/mapper/ubuntu--vg-ubuntu--lv</code></p>

<p>Resultado:
<code class="language-plaintext highlighter-rouge">/dev/mapper/ubuntu--vg-ubuntu--lv:</code>
 <code class="language-plaintext highlighter-rouge">Timing cached reads:   26312 MB in  2.00 seconds = 13184.55 MB/sec</code>
 <code class="language-plaintext highlighter-rouge">Timing buffered disk reads: 306 MB in  3.01 seconds = 101.68 MB/sec</code></p>]]></content><author><name>Jorge L Castro</name></author><summary type="html"><![CDATA[comando:]]></summary></entry><entry><title type="html">Scraping inicial terminado.md</title><link href="https://www.jrg9.com/blog/2024/04/05/Scraping-Inicial-terminado.md.html" rel="alternate" type="text/html" title="Scraping inicial terminado.md" /><published>2024-04-05T00:00:00+00:00</published><updated>2024-04-05T00:00:00+00:00</updated><id>https://www.jrg9.com/blog/2024/04/05/Scraping%20Inicial%20terminado.md</id><content type="html" xml:base="https://www.jrg9.com/blog/2024/04/05/Scraping-Inicial-terminado.md.html"><![CDATA[<p>Terminé la parte de hacer scraping a la página inicial de un área en Airbnb, de hecho usé 4 zonas del área de Mazatlán, Sinaloa, para aumentar la cantidad de listings para hacer scraping.</p>
<p>El archivo con el que se inicia es <code>scrape_page.py</code>, el cual toma 4 links de Airbnb y les hace el scraping tanto a la página inicial como hasta 10 páginas máximo del paginado; se mandan parámetros de 30 días en el futuro, 3 noches de estancia y 2 huéspedes.</p>
<p>Para obtener el código donde residen los datos de los listings, ví que se manda dentro de un script en formato json:</p>
<p><code>scripts = soup_html.find_all("script", attrs={"type":"application/json", "id":"data-injector-instances"})</code></p>
<p>Y cada listing se obtiene en el siguiente nodo:</p>
<pre><code>results = node["root &gt; core-guest-spa"][1][1]["niobeMinimalClientData"][1][1]["data"]["presentation"]["staysSearch"]["results"]["searchResults"]
</code></pre>
<p>Así se ve el listing procesado a json:<br />
<a href="https://postimg.cc/HVW9C36y"><img src="https://i.postimg.cc/WbgWgHrX/temp-Imager-Pi-Uyd.avif" alt="temp-Imager-Pi-Uyd.avif" /></a></p>
<p>Después de hacer el scraping completo de las 4 páginas base, se obtuvo un total de 1,692 registros, con los que haré Exploratory Data Analisys (EDA) en los siguientes posts, en los cuales inicialmente tendré que realizar las siguientes actividades:</p>
<ul>
<li>Ver que los acentos se vean correctamente cuando los cargue en un DataFrame</li>
<li>estandarizar el campo roomTypeCategory</li>
<li>separar los valores del campo rating (calificación y evaluaciones)</li>
<li>análizar el campo de camas</li>
<li>cambiar el valor de price a número</li>
<li>analizar valores repetidos</li>
</ul>]]></content><author><name>Jorge L Castro</name></author><summary type="html"><![CDATA[Terminé la parte de hacer scraping a la página inicial de un área en Airbnb, de hecho usé 4 zonas del área de Mazatlán, Sinaloa, para aumentar la cantidad de listings para hacer scraping. El archivo con el que se inicia es scrape_page.py, el cual toma 4 links de Airbnb y les hace el scraping tanto a la página inicial como hasta 10 páginas máximo del paginado; se mandan parámetros de 30 días en el futuro, 3 noches de estancia y 2 huéspedes. Para obtener el código donde residen los datos de los listings, ví que se manda dentro de un script en formato json: scripts = soup_html.find_all("script", attrs={"type":"application/json", "id":"data-injector-instances"}) Y cada listing se obtiene en el siguiente nodo: results = node["root &gt; core-guest-spa"][1][1]["niobeMinimalClientData"][1][1]["data"]["presentation"]["staysSearch"]["results"]["searchResults"] Así se ve el listing procesado a json: Después de hacer el scraping completo de las 4 páginas base, se obtuvo un total de 1,692 registros, con los que haré Exploratory Data Analisys (EDA) en los siguientes posts, en los cuales inicialmente tendré que realizar las siguientes actividades: Ver que los acentos se vean correctamente cuando los cargue en un DataFrame estandarizar el campo roomTypeCategory separar los valores del campo rating (calificación y evaluaciones) análizar el campo de camas cambiar el valor de price a número analizar valores repetidos]]></summary></entry><entry><title type="html">Actualizando scraping inicial de airbnb</title><link href="https://www.jrg9.com/blog/2024/04/03/Actualizando-scraping-inicial-de-Airbnb.html" rel="alternate" type="text/html" title="Actualizando scraping inicial de airbnb" /><published>2024-04-03T00:00:00+00:00</published><updated>2024-04-03T00:00:00+00:00</updated><id>https://www.jrg9.com/blog/2024/04/03/Actualizando%20scraping%20inicial%20de%20Airbnb</id><content type="html" xml:base="https://www.jrg9.com/blog/2024/04/03/Actualizando-scraping-inicial-de-Airbnb.html"><![CDATA[<p>Ok, cuando inicié el proyecto de scraping de Airbnb (aprox. agosto 2023), Airbnb mandaba datos distintos en la página inicial de un área geográfica, “pintaba” directamente en cards los textos de los listings, pero al día de hoy esto cambió y ahora manda los datos primero en un script en formato json y luego con javascript los pinta en el html de la página. Por la forma en la que hago scraping (requests + BeautifulSoup) tengo que extraer los datos del script/json.</p>

<p>Por tanto, tuve que ver de nuevo cómo se hace el scraping de este nuevo código, por lo que hice la siguiente página <code class="language-plaintext highlighter-rouge">openhtml.py</code>, que lee el html del request de una página y procesa los datos, ya con esto se puede integrar de nuevo a esta parte del proyecto.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from bs4 import BeautifulSoup
import os
import json

path_file_ini = './data/pages/1-a040284b-1310-4af7-b429-1039cfd22971.html'
html = ''
listings=[]

if os.path.isfile(path_file_ini):
    print("from disk")
    with open(path_file_ini, "r", encoding="utf-8") as file:
        html = file.read()

        soup_html = BeautifulSoup(html, "html.parser")
        scripts = soup_html.find_all("script", attrs={"type":"application/json", "id":"data-injector-instances"})

        if(len(scripts) &gt;= 1):
            node = json.loads(scripts[0].text)
            results = node["root &gt; core-guest-spa"][1][1]["niobeMinimalClientData"][1][1]["data"]["presentation"]["staysSearch"]["results"]["searchResults"]
            
            for result in results:
                listing = result["listing"]
                print(f'{type(listing)} {listing["id"]}')

                room = {}
                room["id"] = listing["id"]
                room["title"] = listing["title"]
                room["name"] = listing["name"]
                room["roomTypeCategory"] = listing["roomTypeCategory"]
                room["latitude"] = listing["coordinate"]["latitude"]
                room["longitude"] = listing["coordinate"]["longitude"]
                room["rating"] = listing["avgRatingLocalized"]
                room["beds"] = ""

                if listing["structuredContent"]["primaryLine"] is not None and len(listing["structuredContent"]["primaryLine"]) &gt; 0:
                    if "body" in listing["structuredContent"]["primaryLine"][0]:
                        room["beds"] = listing["structuredContent"]["primaryLine"][0]["body"]

                if "price" in result["pricingQuote"]["structuredStayDisplayPrice"]["primaryLine"]:
                    room["price"] = result["pricingQuote"]["structuredStayDisplayPrice"]["primaryLine"]["price"]
                else:
                    if "discountedPrice":
                        room["price"] = result["pricingQuote"]["structuredStayDisplayPrice"]["primaryLine"]["discountedPrice"]

                room["price"] = room["price"].replace('\xa0',' ')

                print(room)

                listings.append(room)

print(f"\ntotal listings found: {len(listings)}")
</code></pre></div></div>

<p>Al ejecutar el script genera el siguiente resultado:</p>

<p><img src="https://www.jrg9.com/blog/assets/images/img-airbnb-1-2.png" alt="Screenshot de ejecución de script" /></p>

<p>El siguiente paso sobre este html es obtener los links de las demás páginas del “paginado”, hacer el request de esas páginas (máximo 10 páginas) y repetir el scraping sobre esos request; este paso también es nuevo, porque parece que los links de páginas en la páginación vienen también en el json del script, ya veremos…</p>]]></content><author><name>Jorge L Castro</name></author><summary type="html"><![CDATA[Ok, cuando inicié el proyecto de scraping de Airbnb (aprox. agosto 2023), Airbnb mandaba datos distintos en la página inicial de un área geográfica, “pintaba” directamente en cards los textos de los listings, pero al día de hoy esto cambió y ahora manda los datos primero en un script en formato json y luego con javascript los pinta en el html de la página. Por la forma en la que hago scraping (requests + BeautifulSoup) tengo que extraer los datos del script/json.]]></summary></entry><entry><title type="html">Proyecto DataScience/Airbnb/Scraping - Parte 1</title><link href="https://www.jrg9.com/blog/2024/04/02/Proyecto-DataScience-Airbnb-Scraping.html" rel="alternate" type="text/html" title="Proyecto DataScience/Airbnb/Scraping - Parte 1" /><published>2024-04-02T00:00:00+00:00</published><updated>2024-04-02T00:00:00+00:00</updated><id>https://www.jrg9.com/blog/2024/04/02/Proyecto%20DataScience%20-%20Airbnb%20Scraping</id><content type="html" xml:base="https://www.jrg9.com/blog/2024/04/02/Proyecto-DataScience-Airbnb-Scraping.html"><![CDATA[<p>En este proyecto pretendo hacer scraping de los datos de Airbnb para la zona hotelera de Mazatlán, Sinaloa, México. La idea es tener una base de datos que me permita analizar:</p>
<ol>
  <li>Cuál es la tasa de ocupación de los listings disponibles en la zona</li>
  <li>Cuál es el precio promedio de los listings publicados</li>
  <li>Cuáles son las palabras claves de los listings más exitosos en el área</li>
  <li>Cuáles son las características de los listings más exitosos en el área</li>
</ol>

<p>En esta primer etapa intentaré hacer lo siguiente:</p>
<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Hacer scraping de la página inicial de Airbnb para obtener listado de los listings disponibles en el área</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Hacer scraping de la página principal del listing para oibtener los datos más importantes del listing</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Guardar la información scrapeada en archivos json de cada listing</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Guardar la información scrapeada en un archivo csv</li>
</ul>]]></content><author><name>Jorge L Castro</name></author><summary type="html"><![CDATA[En este proyecto pretendo hacer scraping de los datos de Airbnb para la zona hotelera de Mazatlán, Sinaloa, México. La idea es tener una base de datos que me permita analizar: Cuál es la tasa de ocupación de los listings disponibles en la zona Cuál es el precio promedio de los listings publicados Cuáles son las palabras claves de los listings más exitosos en el área Cuáles son las características de los listings más exitosos en el área]]></summary></entry><entry><title type="html">Scraping mainpage airbnb</title><link href="https://www.jrg9.com/blog/2024/04/02/Scraping-mainpage-Airbnb.html" rel="alternate" type="text/html" title="Scraping mainpage airbnb" /><published>2024-04-02T00:00:00+00:00</published><updated>2024-04-02T00:00:00+00:00</updated><id>https://www.jrg9.com/blog/2024/04/02/Scraping%20mainpage%20Airbnb</id><content type="html" xml:base="https://www.jrg9.com/blog/2024/04/02/Scraping-mainpage-Airbnb.html"><![CDATA[<p>En este post explico los primeros pasos para hacer scraping de la página inicial de un área geográfica en Airbnb y extraer los listings que se muestren en esa página.</p>

<h2 id="scraping-de-la-página-inicial-de-un-área-geográfica-en-airbnb">Scraping de la página inicial de un área geográfica en Airbnb</h2>

<p>Manualmente tomé las 4 siguientes urls de base, ya que sé que son las distintas áreas de Mazatlán, así que buscaré en las 10 primeras páginas de estas páginas base.</p>
<ul>
  <li>https://www.airbnb.mx/s/Mazatlan–Sinaloa–Mexico/</li>
  <li>https://www.airbnb.mx/s/Palos-Prietos–Mazatl%C3%A1n–Sin.–M%C3%A9xico/</li>
  <li>https://www.airbnb.mx/s/Centro–Mazatl%C3%A1n–Sin.–M%C3%A9xico/</li>
  <li>https://www.airbnb.mx/s/cerritos–Mazatl%C3%A1n–Sin.–M%C3%A9xico/</li>
</ul>

<h3 id="estableciendo-parámetros-iniciales-del-scraping">Estableciendo parámetros iniciales del scraping</h3>
<p>Sobre estas urls, mando llamar la función <code class="language-plaintext highlighter-rouge">extract_listings</code> con la url base y 3 parámetros preestablecidos para la búsqueda:</p>
<ul>
  <li>fecha: 20 días posteriores a la fecha actual</li>
  <li>2 huéspedes</li>
  <li>3 noches</li>
  <li>se establece un máximo de 10 páginas de cada url base para extraer los listings</li>
</ul>

<p>La página inicial con la que se hace el scraping es como la de la siguiente imagen:</p>

<p><img src="http://www.jrg9.com/blog/assets/images/img-airbnb-1.jpeg" alt="Página base para extraer listings de un área" /></p>

<h3 id="scraping-de-página-principal-de-listing-de-airbnb">Scraping de página principal de listing de Airbnb</h3>
<p>Esta es la función que recibe la URL y hace un scraping de los primeros listings de la página con la función <code class="language-plaintext highlighter-rouge">parseCards</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def extract_listings(first_page_url, max_pages_scrape):

    listings = []
    print (f"{first_page_url}")

    url = first_page_url

    for i in range(1, max_pages_scrape+1):
        print(f"getting url {i}/{max_pages_scrape} {url[0:30]}...")

        try:
            r = requests.get(url)
            html = r.text

            name_file = f"./data/pages/{i}-{str(uuid.uuid4())}.html"
            with open(name_file, "w",encoding="utf-8") as file_json:
                file_json.write(html)

            print(f"got response: {len(html)/1024} KB")

            cards = parseCards(html)

            print(f'cards obtained: {len(cards)}')

            cards_to_txt(cards)

            for item in cards:
                listings.append(item)

            #get next url
            soup = BeautifulSoup(html, 'lxml')

            # Use the beautiful soup find function to get the links from the Next symbol html tag.
            np = soup.find('a', class_ = "l1ovpqvx c1ytbx3a dir dir-ltr")

            if np is None:
                break

            np = np.get("href")
            
            #create a new link with AirBNB.com as the host and concatenate the next page link.
            cnp = "https://www.airbnb.com" + np
            url = cnp

            wait = random.randint(3,8)

            print(f"\nnew url {url[0:50]}  w:{wait}")

            sleep(wait)
        
        except Exception as inst:
            print(f'error getting url...')
            print(type(inst))
            print(inst.args)     # arguments stored in .args
            print(inst) 
        
    return listings
</code></pre></div></div>]]></content><author><name>Jorge L Castro</name></author><summary type="html"><![CDATA[En este post explico los primeros pasos para hacer scraping de la página inicial de un área geográfica en Airbnb y extraer los listings que se muestren en esa página.]]></summary></entry><entry><title type="html">Lenguajes de programación que uso</title><link href="https://www.jrg9.com/blog/2023/07/28/lenguajes.html" rel="alternate" type="text/html" title="Lenguajes de programación que uso" /><published>2023-07-28T10:04:10+00:00</published><updated>2023-07-28T10:04:10+00:00</updated><id>https://www.jrg9.com/blog/2023/07/28/lenguajes</id><content type="html" xml:base="https://www.jrg9.com/blog/2023/07/28/lenguajes.html"><![CDATA[<h1 id="título-1">Título 1</h1>

<h2 id="título-2">título 2</h2>

<h3 id="título-3">título 3</h3>

<p><strong>negritas</strong></p>]]></content><author><name>Jorge L Castro</name></author><category term="Development" /><category term="C#" /><category term="SQL" /><category term="HTML" /><category term="CSS" /><category term="RStudio" /><category term="Adobe" /><summary type="html"><![CDATA[Post hecho cn StackEdit desde la web.]]></summary></entry></feed>