优化python硒网络抓取

时间:2018-08-10 18:29:05

标签: python selenium web-scraping

我下面有这段代码,可以使用硒从网站中提取信息,该代码可以正常工作,但运行速度很慢,我想知道是否可以进行任何更改以使程序运行更快

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

3)使用javascript打开url,以便我们仅等待网站中相关的内容(使用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()
相关问题