【问题标题】:optimize python selenium webscraping优化python selenium webscraping
【发布时间】:2019-01-18 09:45:40
【问题描述】:

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

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('????')

【问题讨论】:

  • 重用驱动。你基本上使用了 10000 种不同的。这需要很多时间。所以在你的for循环之前实例化驱动程序。并将退出命令向下移动到底部。您可以考虑对站点进行反向工程,看看是否可以在没有硒的情况下提取数据。单击 bm 元素后,使用 chrome 并查看 networls 选项卡中发生的情况。也许您可以直接从同一个端点获取数据——就像网站一样。这通常是可能的,而且比浏览器自动化要快得多......

标签: python selenium web-scraping


【解决方案1】:

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

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

1) 将驱动程序初始化和driver.quit() 置于循环之外。

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

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

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

编辑 -

有些页面像this 没有所需的统计信息。在这种情况下,下面的行将抛出一个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()

【讨论】:

  • 嘿,感谢您的帮助,我稍微调整了您的代码,现在它运行得非常快
  • 嘿,我认为它实际上给了我一个错误,因为有些网页没有像这样的任何统计信息ultimatetennisstatistics.com/playerProfile?playerId=45103 你能帮我调整没有统计信息的页面的代码
  • 我得到一个 TimeOutException
猜你喜欢
  • 2013-10-12
  • 1970-01-01
  • 2021-07-15
  • 2019-10-29
  • 2018-08-29
  • 2017-05-24
  • 2022-12-01
  • 2021-02-26
  • 1970-01-01
相关资源
最近更新 更多