【问题标题】:Python Beatifulsoup cannot use the result of selenium correctlyPython Beautifulsoup 无法正确使用 selenium 的结果
【发布时间】:2019-09-26 18:08:34
【问题描述】:

我正在尝试使用 beautifulsoup 解析网页。我可以看到页面已使用 chromedriver 在 selenium 中正确加载,但最终结果为 null,当我在 beautifulsoup 中看到解析的页面打印时,它没有显示 selenium 在其自动浏览器中显示的整个页面。

我为此目的使用的代码是:

page_soup = soup(driver.page_source, "html.parser")
print (page_soup)
containers = page_soup.findAll("div", class_="row ploc-l-row--gutterV flex-wrap flex-align-start flex-center-vertical")
print (len(containers))

我需要访问每个合作伙伴的信息,但结果为空。我正在处理的页面是

https://locatr.cloudapps.cisco.com/WWChannels/LOCATR/openBasicSearch.do;jsessionid=8CDF9284D014CFF911CB8E6F81812619

【问题讨论】:

  • 您想使用page_soup.findAll 查找页面上的哪些元素?我已经在您提供的页面链接上运行了您的选择器,但它没有返回任何结果,因此选择器可能是错误的。
  • 如您所知,该页面是具有多个结果的搜索页面。我想访问每个结果。例如,当您搜索中国时,它会在第一页显示 5 个结果,我想访问每个结果。正如我所看到的,每个结果都在一个带有我上面提到的类名的类的 div 中。
  • 我已经根据您提供的内容编写了一些修改后的 BeautifulSoup 代码,并更改了选择器。此代码将检索搜索结果页面上列出的每个合作伙伴的name
  • 加载该链接时未找到任何结果。

标签: python selenium beautifulsoup


【解决方案1】:

结果是使用 javascript 加载的。在抓取之前,您需要等到搜索结果加载完毕。这是一个工作示例,

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

url = 'https://locatr.cloudapps.cisco.com/WWChannels/LOCATR/openBasicSearch.do'
driver = webdriver.Chrome(executable_path='C:/Selenium/chromedriver.exe')
driver.get(url)
SearchString = 'CALIFORNIA'
Location = driver.find_element_by_name("location")
Location.send_keys(SearchString)
#search = WebDriverWait(driver, 10).until(EC.visibility_of_any_elements_located(By.XPATH,"//li//span[contains(text(),'"+SearchString+"')]"))
#search.click()
time.sleep(3)
driver.find_element_by_xpath("//li//span[contains(text(),'"+SearchString+"')]").click()
driver.find_element_by_id("searchBtn").click()

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID,'searchResultsList')))
time.sleep(3)
page_soup = soup(driver.page_source, "html.parser")
print(page_soup.prettify())
containers = page_soup.findAll("div", class_="row ploc-l-row--gutterV flex-wrap flex-align-start flex-center-vertical")
print (len(containers))

driver.close()

结果是5

【讨论】:

  • 谢谢 Suresh,您的代码运行良好!您能帮我在单页中获得所有结果吗?我的意思是所有合作伙伴,而不仅仅是前 5 个。
  • 使用api获取结果会很有效。只需在搜索后观看网络选项卡。有一个包含所有结果的 getsearch 结果。
  • 仅供参考,它是 scraping(和 scrapescrapedscraper)没有报废, “报废”是指把东西像垃圾一样扔掉。
【解决方案2】:

根据您的评论澄清,我有一些东西可以检索搜索结果中显示的每个合作伙伴的合作伙伴名称:

使用 BeautifulSoup 语法:

partnerWebElements = page_soup.findAll(title="View Profile")

仅使用 Selenium 语法:

partnerWebElements = driver.find_elements_by_xpath("//a[@title='View Profile']")

然后您可以像这样获取每个合作伙伴名称的文本:

for partnerWebElement in partnerWebElements:
    print(partnerWebElement.text);

【讨论】:

  • 我不确定 BeautifulSoup 语法是如何与它一起工作的,因为它们不支持 XPath。但是如果你想使用 XPath,你可以使用//a[@title='View Profile']。我正在此页面上进行测试:locatr.cloudapps.cisco.com/WWChannels/LOCATR/…
  • 在查看 BeautifulSoup 文档以获取特定的 findAll 参数后,我用另一个示例进行了更新。我将使用 XPath 更新我的答案并添加另一个 python 示例。
  • 谢谢你,Christine,但我仍然没有得到你的结果。能否请您查看我的代码,我认为我的代码和您的代码有些不同。
  • 我会参考他们发布的@Sureshmani 答案。它看起来像一个完整的示例,它还检索了正确数量的结果。
【解决方案3】:

仅供参考,该页面使用 jQuery,这使得这很容易:

driver.execute_script("return $('div[class=\"row ploc-l-row--gutterV flex-wrap flex-align-start flex-center-vertical\"]').length")

【讨论】:

  • 你也可以通过execute_script来执行jquery? +
  • 是的,在这种情况下,它已包含在页面中,但您也可以inject it,如果它不包含
  • 哇!感谢您的链接。看看这是否适用于 selenium 的语言。这太酷了,从没想过,但完全有道理。
  • 应该,但如果语言有 heredocs(查看 Java)会有所帮助。 jQuery 确实是 html 解析器的黄金标准,这就是为什么当人们将硒与美丽的汤混合时我会慢慢摇头。
猜你喜欢
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 2016-06-10
  • 1970-01-01
  • 2021-10-15
相关资源
最近更新 更多