首页 > 解决方案 > 为什么 BeautifulSoup 会不断返回带有类 id 的元素,而不是我传递的元素?

问题描述

我正在尝试使用 BeautifulSoup 来解析包含韩国新闻文章的 iframe 并打印出文章中的每个单独的正文段落。因为韩文段落内容位于其自己的 td 标记中的 ap 标记中,其类 id 为“tlTD”,所以我想我可以使用该类名遍历每个 td 并打印 p 标记,如下所示:

link ="https://gloss.dliflc.edu/GlossHtml/GlossHTML.html?disableBrowserLockout=true&gloss=true&glossLoXmlFileName=/GlossHtml/templates/linksLO/glossLOs/kp_cul312.xml&glossMediaPathRoot=https://gloss.dliflc.edu/products/gloss/"
base_url = "https://oda.dliflc.edu"

driver = webdriver.Chrome()
driver.get(link)
python_button = driver.find_element_by_id("gloss_link_source")
python_button.click() 

source_src= driver.find_element_by_id("glossIframe").get_attribute("src")
source_url = urljoin(base_url, source_src) 
driver.get(source_url)

soup = BeautifulSoup(driver.page_source, "lxml") 
for td in soup.find_all("td", class_="tlTD"):   
    print(soup.find("p").getText())

问题是,代码没有打印正文段落,而是重复打印出位于它自己的 td 中的文章标题,标题为“title tlTD”。我尝试使用 lambda 表达式和正则表达式来使类名更加独占,但我一直得到相同的结果。改成soup.find("p")afind_all成功让代码打印了我想要的,但是也打印了一堆我不想要的英文版内容。

我可以理解为什么会打印文章标题内容,因为它在类名中包含“tlTD”,但我对英文内容的来源感到困惑。当我在谷歌浏览器中检查页面时,它没有包含任何英文正文段落,那么为什么 BeautifulSoup 会抓取它?谁能帮我解释一下这里发生了什么以及如何让这个代码只打印韩文正文段落内容?

标签: pythonpython-3.xseleniumbeautifulsoup

解决方案


tlTDiframe 中的类td tag,您可以轻松访问 iframe 数据,例如:

xpath 来定位 iframe :

iframe = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//iframe[@id='glossIframe']")))

然后切换到 iframe:

driver.switch_to.frame(iframe)

以下是如何切换回默认内容(在 之外):

driver.switch_to.default_content()

显式等待更多细节

前任:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup

driver = webdriver.Chrome()
link = "https://gloss.dliflc.edu/GlossHtml/GlossHTML.html?disableBrowserLockout=true&gloss=true&glossLoXmlFileName=/GlossHtml/templates/linksLO/glossLOs/kp_cul312.xml&glossMediaPathRoot=https://gloss.dliflc.edu/products/gloss/"

driver.get(link)

source_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "gloss_link_source")))
source_button.click()

#switch iframe
iframe = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//iframe[@id='glossIframe']")))
driver.switch_to.frame(iframe)
 
soup = BeautifulSoup(driver.page_source, "lxml")
#scrape iframe data
for td in soup.find_all("td", class_="tlTD"):
    print(td.find("p").getText())

推荐阅读