Impossible d'analyser les éléments d'un site Web contenant des données tabulaires (iframe)

Dec 21 2020

Nous essayons d'analyser les hrefattributs du DOM d'un site Web d'emploi . Nous voulons obtenir un hrefpour chaque emploi.

Nous utilisons généralement des chemins CSS et les transmettons à la find_elements_by_cssméthode Selenium .

Malheureusement, nous avons remarqué que le plugin de navigateur SelectorGadget avait du mal à nous fournir un chemin CSS. Nous avons continué à utiliser un chemin CSS en utilisant Google Chrome (ctrl + shift + c). Chrome pourrait extraire un chemin, mais ni Selenium ni BeautifulSoup ne peuvent travailler avec ces chemins.

Après de nombreuses tentatives infructueuses d'extraire les éléments en utilisant différentes classes et balises, nous pensons que quelque chose ne va pas du tout avec notre approche ou le site Web. Nous émettons l'hypothèse que les éléments souhaités sont impossibles à analyser par Selenium et BeautifulSoup pour une raison quelconque? Les iframebalises dans le DOM pourraient-elles être une source d'erreur (voir cette question SO )? Qu'est-ce qui fait que l'analyse échoue ici et existe-t-il un moyen de contourner ce problème? Une source de problème liée au site Web expliquerait également pourquoi le gadget de sélection n'a pas pu obtenir un chemin en premier lieu. Notre conclusion serait d'utiliser des expressions régulières pour extraire les hrefattributs dont nous avons besoin. Ce ne serait qu'une solution de dernier recours.

Pour les germanophones, s'il vous plaît thatthere note est une erreur d'orthographe dans les éléments cibles: <div class="stellenagebot">. Ne vous laissez pas confondre avec ceux-ci (comme nous l'avons fait)

Pas de chance avec 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

Donc pas de chance avec 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: []

Réponses

3 KunduK Dec 21 2020 at 23:25

L'élément que vous recherchez est à l'intérieur comments. vous devez d'abord disposer de ces informations de balise, puis les convertir en chaîne, puis les analyser à nouveau pour obtenir la valeur.

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'])

Production:

/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/