No se pueden analizar elementos de un sitio web que contiene datos tabulares (iframe)

Dec 21 2020

Estamos intentando analizar los hrefatributos del DOM de un sitio web de empleo . Queremos conseguir uno hrefpor cada trabajo.

Usualmente usamos rutas CSS y las pasamos al find_elements_by_cssmétodo de Selenium .

Desafortunadamente, hemos notado que el complemento del navegador SelectorGadget tuvo problemas para proporcionarnos una ruta CSS. Procedimos a usar una ruta CSS usando Google Chrome (ctrl + shift + c). Chrome podría extraer una ruta, pero ni Selenium ni BeautifulSoup pueden trabajar con esas rutas.

Después de muchos intentos fallidos de extraer los elementos utilizando diferentes clases y etiquetas, creemos que algo está completamente mal con nuestro enfoque o con el sitio web. Suponemos que los elementos deseados son imposibles de analizar por Selenium y BeautifulSoup por alguna razón. ¿Podrían las iframeetiquetas en el DOM ser una fuente de error (consulte esta pregunta SO )? ¿Qué hace que falle el análisis aquí? ¿Hay alguna manera de solucionar este problema? Una fuente de problemas relacionada con el sitio web también explicaría por qué el Selector Gadget no pudo obtener una ruta en primer lugar. Nuestra conclusión sería utilizar expresiones regulares para extraer los hrefatributos que necesitamos. Esta sería solo una solución de último recurso.

Para germano-hablantes, por favor nota thatthere es un error de ortografía en los elementos de destino: <div class="stellenagebot">. Por favor, no se deje confundir por ellos (como lo hicimos nosotros).

No tuve suerte con BeautifulSoup:

import re
import requests
from bs4 import BeautifulSoup


url = 'https://www.artemiskliniken.de/Karriere/%C3%84rzte/'

page = requests.get(url)

soup = BeautifulSoup(page.text, 'html.parser')

print(soup.prettify())
# Out: ...

#<div class="col-md-4 wow fadeInUp">
# <div class="stellenagebot">
#  <h3>
#   Facharzt (m/w/d) für Augenheilkunde in Voll- oder Teilzeit
#  </h3>
#  <h4>
#   Erfurt
#  </h4>
#  <a class="btn btn-default" href="/Stellenangebot/Facharzt_Augenheilkunde_Erfurt/">
#   Mehr
#  </a>
# </div>
#</div>
#<div class="col-md-4 wow fadeInUp">
# <div class="stellenagebot">
#  <h3>
#   Facharzt (m/w/d) für Augenheilkunde in Voll- oder Teilzeit
#  </h3>
#  <h4>
#   Eschwege
#  </h4>
#  <a class="btn btn-default" href="/Stellenangebot/Facharzt_Augenheilkunde_Eschwege/">
#   Mehr
#  </a>
# </div>
#</div>

# ...

print(soup.find_all('.stellenagebot'))
# Out: []

print(soup.find_all(string=re.compile("Stellenangebot")))
# ['Stellenangebote Facharzt für Augenheilkunde und Karrierewege für Ärzte', '<h3>Zur Verst&auml;rkung unseres Teams suchen wir:</h3>\n\n<p class="hyphenate" lang="de">&nbsp;</p>\n\n<div id=\'jobauflistung\' class=\'row\'><div class=\'col-md-4 wow  fadeInUp\'><div class="stellenagebot">\n<h3>Facharzt (m/w/d) für Augenheilkunde in Voll- oder Teilzeit</h3>\n\n<h4>Aachen</h4>\n<a class="btn btn-default" href="/Stellenangebot/Facharzt_Augenheilkunde_Aachen/">Mehr</a></div></div><div class=\'col-md-4 wow  fadeInUp\'><div class="stellenagebot">\n<h3>Facharzt (m/w/d) fü
# ...
# ></div>\n</div>\n</div>\n</div>\n</footer>\n</div><!-- AUF ALLEN SEITEN IN DEN BODY-TAG EINFÜGEN ']

print(len(soup.find_all(string=re.compile("Stellenangebot"))))
# Out: 2

Así que no hay suerte con Selenium:

from selenium import webdriver

from job_scraper.configuration import CHROMEDRIVER_VERSION, ROOT_PATH, \
    CHROME_OPTIONS


driver = webdriver.Chrome(
    ROOT_PATH / f'assets/chrome_drivers/{CHROMEDRIVER_VERSION}',
    options=CHROME_OPTIONS
)
driver.maximize_window()
driver.get(url)
driver.find_elements_by_css_selector('.stellenagebot')
# Out: []

Respuestas

3 KunduK Dec 21 2020 at 23:25

El elemento que estás buscando está adentro comments. primero debe tener esta información de etiqueta y luego convertirla en una cadena y luego analizarla nuevamente para obtener el valor.

from bs4 import Comment
import requests

url = 'https://www.artemiskliniken.de/Karriere/%C3%84rzte/'
page = requests.get(url)
soup = BeautifulSoup(page.text, 'html.parser')
#Capture Comments element
comments = soup.find_all(text=lambda text:isinstance(text, Comment))
Newsoup = BeautifulSoup(''.join(comments), 'html.parser')
for item in Newsoup.select('[href*="Stellenangebot"]'):
    print(item['href'])

Salida:

/Stellenangebot/Facharzt_Augenheilkunde_Aachen/
/Stellenangebot/Facharzt_Augenheilkunde_Bad_Berleburg/
/Stellenangebot/Facharzt_Augenheilkunde_Bad_Hersfeld/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Beckum/
/Stellenangebot/Facharzt_Augenheilkunde_Beckum/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Dieburg/
/Stellenangebot/Facharzt_Augenheilkunde_Dieburg /
/Stellenangebot/Facharzt_Augenheilkunde_Dillenburg/
/Stellenangebot/Facharzt_Augenheilkunde_Duisburg/
/Stellenangebot/Facharzt_Augenheilkunde_Erfurt/
/Stellenangebot/Facharzt_Augenheilkunde_Eschwege/
/Stellenangebot/Facharzt_Augenheilkunde_Frankfurt/
/Stellenangebot/Facharzt_Augenheilkunde_Helmstedt/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Heppenheim/
/Stellenangebot/Facharzt_Augenheilkunde_Herborn/
/Stellenangebot/Facharzt_Augenheilkunde_Hoyerswerda/
/Stellenangebot/Facharzt_Augenheilkunde_Koeln/
/Stellenangebot/Facharzt_Anaesthesie/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Leverkusen/
/Stellenangebot/Facharzt_Augenheilkunde_Limburg/
/Stellenangebot/Facharzt_Augenheilkunde_Mainz/
/Stellenangebot/Facharzt_Augenheilkunde_Marburg/
/Stellenangebot/Facharzt_Augenheilkunde_Melsungen/
/Stellenangebot/Facharzt_Augenheilkunde_Moers/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Moers/
/Stellenangebot/Facharzt_Augenheilkunde_Moerfelden/
/Stellenangebot/Facharzt_Augenheilkunde_Muehlhausen/
/Stellenangebot/Facharzt_Augenheilkunde_Isenburg/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Oberhausen/
/Stellenangebot/Facharzt_Augenheilkunde_Oberhausen/
/Stellenangebot/Facharzt_Augenheilkunde_Obertshausen/
/Stellenangebot/Facharzt_Augenheilkunde_Oberursel/
/Stellenangebot/Facharzt_Augenheilkunde_Offenbach/
/Stellenangebot/Weiterbildungsarzt_Augenheilkunde_Offenbach/
/Stellenangebot/Facharzt_Augenheilkunde_Ruesselsheim/
/Stellenangebot/Facharzt_Augenheilkunde_Salzkotten/
/Stellenangebot/Facharzt_Augenheilkunde_Wetzlar/
/Stellenangebot/Facharzt_Augenheilkunde_Wiesbaden/