2017-07-29 1 views
0

私は、インタラクティブなスケジューラを構築するために、大学のクラスに関するデータを取得するためのコードを書きました。ここで私は、データを取得する必要がありますコードは次のとおりです。私はこれを実用的にしていた場合、少なくとも7を必要としている、一つのクラスと1つのクラスのセクションからデータを取得するためセレンコードの最適化

from selenium import webdriver 
import os 
import pwd 
import shlex 
import re 
import time 


usr = pwd.getpwuid(os.getuid()).pw_name 
Path = ('/Users/%s/Downloads/chromedriver') %usr # Have chromedriver dowloaded 
# Create a new instance of the Chrome driver 
options = webdriver.ChromeOptions() 
options.binary_location = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' 
options.add_argument('headless') # Headless so no window is opened 
options.add_argument('window-size=1200x600') 
driver = webdriver.Chrome(Path, chrome_options=options) 


driver.get('https://web.stevens.edu/scheduler/core/2017F/2017F.xml') # Go to database 


classes = {} 

def Database(AllSelectedCourseInfo): 
    ClassDict = {} 

    for item in AllSelectedCourseInfo: # Go through list of class info 
     try: 
      thing = item.split("=") # Split string by = to get subject name and value 
      name = thing[0] 
      if any(char.isdigit() for char in thing[1]): # Get rid of annoying Z at the end of numbers 
       thing[1] = re.sub("[Z]","",thing[1]) 
      value = thing[1] 
      if value: # If subject has a value, store it 
       ClassDict[str(name)] = str(value) # Store value in a dictionary with the subject as the key 
     except: 
      pass 

    classes[str(ClassDict["Section"])] = ClassDict # Add to dictionary 


def makeDatabase(section): 


    if "Title" in driver.find_element_by_xpath("//*[text()='%s']"%section).find_element_by_xpath("..").text: 
     classSection = driver.find_elements_by_xpath("//*[text()='%s']"%section) # If class name given find class 

     for i in range(0, len(classSection)): 
      AllSelectedCourseInfo = shlex.split(classSection[i].find_element_by_xpath(".." + "/.."*4).text.replace("/>", "").replace(">", "")) # sort into a list grouping string in quotes and getting rid of unnecessary symbols 
      Database(AllSelectedCourseInfo) 

    else: 
     classSection = driver.find_element_by_xpath("//*[text()='%s']"%section) # If class section give, find class 
     AllSelectedCourseInfo = shlex.split(classSection.find_element_by_xpath(".." + "/.."*3).text.replace("/>", "").replace(">", "")) # sort into a list grouping string in quotes and getting rid of unnecessary symbols 
     Database(AllSelectedCourseInfo) 


def printDic(): 
    for key in classes: 
     print "\n-------------%s------------" %key 
     for classkey in classes[key]: 
      print "%s : %s" %(classkey, classes[key][classkey]) 

start = time.time() 
makeDatabase("Differential Calculus") 
makeDatabase("MA 124B") 
printDic() 
end = time.time() 

print end - start 

driver.quit() 

それは約20秒かかります辞書を作成するだけで1分以上かかります。誰かがこれをもっと速く走らせる方法を知っていますか?

+2

セレンは本当に必要ですか? xmlをダウンロードするためのリクエストのようなものを使用しないでください。次に、それを解析するBeautifulSoupのようなライブラリを使用できますか? – perfect5th

+0

私は仕事に慣れていたのでセレンを使用しています。この場合、BeautifulSoupがうまく動作するかどうかを調べます。 – Jake

+0

あなたは本当に1つのxmlページを取得しているので、セレンはここで過度かもしれません。また、ページを取得する簡単な方法については、http://docs.python-requests.org/ja/master/のリクエストを参照してください。 – perfect5th

答えて

0

私はlxmlとリクエストを自分のコードに統合しようとしましたが、探していたものがありませんでした。役に立たないでこれを達成するためにlxmlを使用しようと数日後、私はurlibでbeautifulsoup4を試してみることにしました。これは

from bs4 import BeautifulSoup 
from HTMLParser import HTMLParser 
import urllib 
import shlex 
import re 
import time 

h = HTMLParser() 
page = urllib.urlopen('https://web.stevens.edu/scheduler/core/2017F/2017F.xml').read() # Get to database 
soup = BeautifulSoup(page) 

RawClassData = soup.contents[10].contents[0].contents[0].contents 

classes = {} 
backupClasses = {} 

def makeDatabase(): 


    for i in range(0, len(RawClassData)): # Parse through each class 
     try: 
      AllSelectedCourseInfo = shlex.split(h.unescape(str(RawClassData[i]).replace(">", " "))) # sort into a list grouping string in quotes and getting rid of unnecessary symbols 
      ClassDict = {} 

      for item in AllSelectedCourseInfo: # Go through list of class info 
       try: 
        thing = item.split("=") # Split string by = to get subject name and value 
        name = thing[0] 
        if any(char.isdigit() for char in thing[1]): # Get rid of annoying Z at the end of numbers 
         thing[1] = re.sub("[Z]","",thing[1]) 
        value = thing[1] 
        if value: # If subject has a value, store it 
         ClassDict[str(name)] = str(value) # Store value in a dictionary with the subject as the key 
       except: 
        pass 

      classes[str(ClassDict["section"])] = ClassDict 
     except: 
      pass 


def printDic(): 
    with open("Classes", "w") as f: 
     for key in classes: 
      f.write("\n-------------%s------------" %key) 
      for classkey in classes[key]: 
       f.write("\n%s : %s" %(classkey, classes[key][classkey])) 
      f.write("\n") 

def printSection(selection): 
    print "\n-------------%s------------" %selection 
    for classkey in classes[selection]: 
     print "%s : %s" %(classkey, classes[selection][classkey]) 

def printClass(selection): 
    try: 
     for key in classes: 
      if classes[key]["title"] == selection: 
       print "\n-------------%s------------" %key 
       for classkey in classes[key]: 
        print "%s : %s" %(classkey, classes[key][classkey]) 
    finally: 
     print "\n-------------%s------------" %selection 
     for classkey in classes[selection]: 
      print "%s : %s" %(classkey, classes[selection][classkey]) 

start = time.time() 

makeDatabase() 

end = time.time() 

printClass("Circuits and Systems") 
printClass("Differential Equations") 
printClass("Writing & Communications Collqm") 
printClass("Mechanics of Solids") 
printClass("Electricity & Magnetism") 
printClass("Engineering Design III") 
printClass("Freshman Quiz") 

printDic() 

print end - start 

、私が期待している可能性がより良い仕事をこの新しいコードはすべて2秒で、目的のクラスを出力し、その後、すべてのクラスのライブラリを作成します。セレンコードでは、目的のクラスのライブラリを作成してプリントアウトするのに89秒かかりましたが、少し改善があったと思います。