python - 优化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('????')
解决方案
不要为每次迭代创建新的驱动程序实例。您的脚本几乎不需要任何时间来提取数据。其中大部分仅用于打开浏览器并一次又一次地加载 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()
推荐阅读
- python - TypeError:只能将 str(不是“字节”)连接到 str In Socket Module
- reactjs - react-router-dom:如何将 url 与某种模式匹配
- go - 为什么将单个字节类型转换为字符串在 go 中不起作用?
- python - django-excel pyexcel 显示 django heroku 的未知参数
- reactjs - React:如果 prop 更改,则重新渲染组件
- dart - 使用“Process.start”时如何处理不需要的标准输出?
- numpy - 在 Pi 4、32 位操作系统中,无法将符号张量 (lstm/strided_slice:0) 转换为 numpy 数组;在 LSTM 实施期间
- intellij-idea - 如何从 Intellij 中的 Embold 插件导出数据?
- html - 如何将实时值从网站导入到 Google 表格?
- python - 将 Python 值更新为 Google 表格