首页 > 解决方案 > 优化python selenium webscraping

问题描述

我在下面有这段代码,它使用硒从网站中提取信息,代码工作正常,但速度很慢我想知道是否有什么可以改变的,以使程序运行得更快

from selenium import webdriver
from bs4 import BeautifulSoup
dat =[]

for m in range(1,10000):
driver = webdriver.Chrome()
driver.get("http://www.ultimatetennisstatistics.com/playerProfile?playerId="+str(m))
dat.append([driver.find_element_by_xpath('/html/body/h3').text])
dat.append(m)
try:
   dropdown = driver.find_element_by_xpath('//*[@id="playerPills"]/li[9]/a')
   dropdown.click()
   bm = driver.find_element_by_id('statisticsPill')
   bm.click()
   driver.maximize_window()
   soup = BeautifulSoup(driver.page_source,"lxml")
   for i in soup.select('#statisticsOverview table tr'):
     dat.append([x.get_text(strip=True) for x in i.select("th,td")])
   driver.quit()

except ValueError:
      print("error")
dat.append('????')

标签: pythonseleniumweb-scraping

解决方案


不要为每次迭代创建新的驱动程序实例。您的脚本几乎不需要任何时间来提取数据。其中大部分仅用于打开浏览器并一次又一次地加载 URL。

这是我对您的代码所做的-

1) 放置驱动初始化和driver.quit()外循环。

2)使用 selenium webdriver 本身来抓取数据而不是漂亮的汤,因为后者的结果不一致且可靠,因为数据来自 javascript。(此外,不需要外部库,您可以从 selenium 本身获取所有数据。)

3) 使用javascript打开网址,这样我们就可以等待WebDriverWait您网站中的相关内容(使用)出现,而不是全部加载。

最终代码抓取数据所用时间不到原始代码的一半。(通过方法测量 3 次迭代)

编辑 -

有一些像这样的页面没有必需的统计信息。在这种情况下,下面的行将抛出TimeoutException-

rows = small_wait.until(EC.presence_of_all_elements_located((By.XPATH,"//div[@id = 'statisticsOverview']//tr")))

因此,您可以简单地处理该异常,而是检查是否存在“无可用统计信息”元素(使用is_displayed())。

最终代码 -

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

dat =[]
driver = webdriver.Chrome()  
driver.maximize_window()
wait = WebDriverWait(driver, 10)
small_wait = WebDriverWait(driver, 4)    #because performance is a concern

for m in range(0,10000):
    driver.execute_script('window.open("http://www.ultimatetennisstatistics.com/playerProfile?playerId=' + str(m) + '","_self")')
    dat.append([wait.until(EC.presence_of_element_located((By.XPATH, '/html/body/h3'))).text])
    dat.append(m)
    try:
        dropdown = driver.find_element_by_xpath('//*[@id="playerPills"]/li[9]/a')
        dropdown.click()
        bm = driver.find_element_by_id('statisticsPill')
        bm.click()
        try:
            rows = small_wait.until(EC.presence_of_all_elements_located((By.XPATH,"//div[@id = 'statisticsOverview']//tr")))
            for i in rows:
                dat.append([i.text])
        except TimeoutException:
            no_statistics_element = small_wait.until(EC.presence_of_element_located((By.XPATH, "//div[@id='playerStatsTab']/p[contains(text(),'No statistics available')]")))
            if(no_statistics_element.is_displayed()):
                dat.append([no_statistics_element.text])
                continue
    except ValueError:
        print("error")
    dat.append('????')   

driver.quit()

推荐阅读