首页 > 解决方案 > 在 Python 中使用 Selenium 抓取 JavaScript 渲染的内容

问题描述

我对网络抓取非常陌生,并且一直在尝试使用 Selenium 的功能来模拟访问德克萨斯州公共合同网页的浏览器,然后下载嵌入式 PDF。该网站是这样的:http ://www.txsmartbuy.com/sp 。

到目前为止,我已经成功地使用 Selenium 在下拉菜单“机构名称”之一中选择了一个选项,然后单击了搜索按钮。我在下面列出了我的 Python 代码。

import os
os.chdir("/Users/fsouza/Desktop") #Setting up directory

from bs4 import BeautifulSoup #Downloading pertinent Python packages
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

chromedriver = "/Users/fsouza/Desktop/chromedriver" #Setting up Chrome driver
driver = webdriver.Chrome(executable_path=chromedriver)
driver.get("http://www.txsmartbuy.com/sp")
delay = 3 #Seconds

WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.XPATH, "//select[@id='agency-name-filter']/option[69]")))    
health = driver.find_element_by_xpath("//select[@id='agency-name-filter']/option[68]")
health.click()
search = driver.find_element_by_id("spBtnSearch")
search.click()

一旦我进入结果页面,我就卡住了。

首先,我无法使用 html 页面源访问任何生成的链接。但是,如果我在 Chrome 中手动检查单个链接,我确实会找到<a href...与单个结果相关的相关标签 ( )。我猜这是因为 JavaScript 渲染的内容。

其次,即使 Selenium 能够看到这些单独的标签,它们也没有类或 id。我认为调用它们的最佳方法是<a按显示的顺序调用标签(参见下面的代码),但这也不起作用。相反,该链接调用了其他一些“可见”标签(页脚中的东西,我不需要)。

第三,假设这些事情确实有效,我怎样才能计算<a>出页面上显示的标签数量(以便为每个结果循环此代码)?

driver.execute_script("document.getElementsByTagName('a')[27].click()")

感谢您对此的关注——请原谅我的愚蠢,考虑到我才刚刚开始。

标签: pythonselenium-webdriverweb-scrapingwebdriverwaitwindow-handles

解决方案


要使用Selenium抓取 JavaScript 渲染的内容,您需要:

  • 将WebDriverWait引入所需的element to be clickable().

  • 诱导WebDriverWaitvisibility of all elements located().

  • 使用和通过ActionChains在新选项卡中打开每个链接Ctrlclick()

  • 诱导WebDriverWait切换到新选项卡以进行 webscrape。

  • 切换回主页面。

  • 代码块:

      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 selenium.webdriver.common.action_chains import ActionChains
      from selenium.webdriver.common.keys import Keys
      import time
    
      options = webdriver.ChromeOptions() 
      options.add_argument("start-maximized")
      options.add_experimental_option("excludeSwitches", ["enable-automation"])
      options.add_experimental_option('useAutomationExtension', False)
      driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
      driver.get("http://www.txsmartbuy.com/sp")
      windows_before  = driver.current_window_handle
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='agency-name-filter' and @name='agency-name']"))).click()
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='agency-name-filter' and @name='agency-name']//option[contains(., 'Health & Human Services Commission - 529')]"))).click()
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[@id='spBtnSearch']/i[@class='icon-search']"))).click()
      for link in WebDriverWait(driver, 5).until(EC.visibility_of_all_elements_located((By.XPATH, "//table/tbody//tr/td/strong/a"))):
          ActionChains(driver).key_down(Keys.CONTROL).click(link).key_up(Keys.CONTROL).perform()
          WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
          windows_after = driver.window_handles
          new_window = [x for x in windows_after if x != windows_before][0]
          driver.switch_to_window(new_window)
          time.sleep(3)
          print("Focus on the newly opened tab and here you can scrape the page")
          driver.close()
          driver.switch_to_window(windows_before)
      driver.quit()
    
  • 控制台输出:

      Focus on the newly opened tab and here you can scrape the page
      Focus on the newly opened tab and here you can scrape the page
      Focus on the newly opened tab and here you can scrape the page
      .
      .
    
  • 浏览器快照:

刮


参考

您可以在以下位置找到一些相关的详细讨论:


推荐阅读