【问题标题】:Unable to parse elements from a website that contains tabular data (iframe)无法从包含表格数据 (iframe) 的网站解析元素
【发布时间】:2021-03-31 08:24:41
【问题描述】:

我们正在尝试从 job website 的 DOM 中解析 href 属性。我们希望为每个工作获得一个href

我们通常使用 CSS 路径并将它们传递给 Selenium 的 find_elements_by_css 方法。

很遗憾,我们注意到浏览器插件SelectorGadget 无法为我们提供 CSS 路径。我们继续使用 Google Chrome (ctrl+shift+c) 的 CSS 路径。 Chrome 可以提取路径,但 Selenium 和 BeautifulSoup 都不能使用这些路径。

在多次尝试使用不同的类和标签提取元素失败后,我们认为我们的方法或网站完全有问题。我们假设 Selenium 和 BeautifulSoup 出于某种原因无法解析所需的元素? DOM 中的iframe 标记是否会成为错误源(请参阅此SO question)?是什么导致解析失败,有没有办法解决这个问题?与网站相关的问题源也可以解释为什么 SelectorGadget 无法首先获得路径。我们的结论是使用正则表达式来提取我们需要的href 属性。这只是万不得已的解决方案。

对于讲德语的人,请注意目标元素中存在拼写错误:<div class="stellenagebot">。请不要让自己被这些混淆(就像我们所做的那样)。

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

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: []

【问题讨论】:

  • 如果元素在iframe 中,则它被视为单独的页面,您必须加载它。 Selenium 甚至有 switch_to.frame(...) 来加载 iframe 中的内容。 BeatifulSoup 不会解析 iframe 中的元素,因为它不是当前页面的一部分,您必须从 iframe 获取 url 并使用 requests 加载它
  • 当我在网络浏览器中检查页面时,我在评论中看到 stellenagebot 仅在 HTML 中 &lt;!-- .... --&gt; 所以 BeautifulSoupSelenium 不会将其视为 HTML,而是将其视为评论中的普通字符串。所以它可能必须从comment 获取文本并单独解析它。
  • 此页面在表格中使用 JavaScript - 所以我在显示的表格中看不到任何 href,因为 URL 隐藏在 JavaScript 中的某处。我只在 HTML 的评论中看到 href
  • 感谢您提供的背景信息! @furas

标签: python html selenium web-scraping beautifulsoup


【解决方案1】:

您要搜索的元素在 comments 内。你需要先有这个标签信息,然后转换成字符串,然后再解析,才能得到值。

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

输出:

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

【讨论】:

    猜你喜欢
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    • 2018-04-26
    • 2015-06-07
    相关资源
    最近更新 更多