├── .gitignore ├── IsUp.py ├── QueueInOOPS.py ├── README.md ├── ScrapeJames.py ├── captureAndSaveVideo.py ├── countDownMusic.py ├── downloadXkcd.py ├── get_topcoder_tutorial.py ├── hangman.py ├── i_am_feeling_lucky.py ├── jokes.py ├── multithreaddownloadXkcd.py ├── playVideo.py ├── python_org_search.py ├── sendTweetsUsingTwython.py ├── sendemail2.py ├── socialsites.py ├── stopwatch.py ├── textMyself.py ├── tweet_image.py ├── wallpaper_downloader.py └── write_test_in_python.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | -------------------------------------------------------------------------------- /IsUp.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import os 3 | import sys 4 | from time import sleep 5 | #import commands 6 | from subprocess import call 7 | 8 | 9 | if len(sys.argv)==2: 10 | 11 | url=sys.argv[1] 12 | while(1): 13 | res=requests.get(url) 14 | if res.status_code==requests.codes.ok: 15 | speech="Site is up" 16 | print(speech) 17 | call(["espeak",speech]) 18 | else: 19 | print("Nope") 20 | sleep(5) 21 | 22 | else: 23 | print("Enter correct number of arguments") 24 | 25 | -------------------------------------------------------------------------------- /QueueInOOPS.py: -------------------------------------------------------------------------------- 1 | class Queue(object): 2 | 3 | def __init__(self): 4 | """Create an empty queue""" 5 | self.vals=[] 6 | 7 | def insert(self,e): 8 | self.vals.append(e) 9 | 10 | 11 | def remove(self): 12 | """ Removes front element of queue""" 13 | 14 | try: 15 | return self.vals.pop(0) 16 | except: 17 | raise ValueError("Queue is empty") 18 | 19 | 20 | a=Queue() 21 | a.insert(5) 22 | a.insert(6) 23 | print a.remove() 24 | 25 | a.insert(7) 26 | print a.remove() 27 | print a.remove() 28 | 29 | print a.remove() 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # i_love_python 2 | Collection of my python scripts 3 | 4 | - [IsUp.py](https://github.com/MayankPratap/i_love_python/blob/master/IsUp.py) :- Script to give a sound alert if a website is up or else continues executing. 5 | 6 | - [ScrapeJames.py](https://github.com/MayankPratap/i_love_python/blob/master/ScrapeJames.py) :- Script to download every blog post of JamesAltucher and save them offline. 7 | 8 | - [QueueInOOPS.py](https://github.com/MayankPratap/i_love_python/blob/master/QueueInOOPS.py) :- Python script showing Queue in OOPS 9 | 10 | - [captureAndSaveVideo.py](https://github.com/MayankPratap/i_love_python/blob/master/captureAndSaveVideo.py) :- Capture and Save Video from Webcam using Python 11 | 12 | - [countDownMusic.py](https://github.com/MayankPratap/i_love_python/blob/master/countDownMusic.py) :- Python script to open a music file after count down 13 | 14 | - [downloadXkcd.py](https://github.com/MayankPratap/i_love_python/blob/master/downloadXkcd.py) :- Added downloadXkcd.py 15 | 16 | - [get_topcoder_tutorial.py](https://github.com/MayankPratap/i_love_python/blob/master/get_topcoder_tutorial.py) :- Download all topcoder tutorials and save as pdf 17 | 18 | - [hangman.py](https://github.com/MayankPratap/i_love_python/blob/master/hangman.py) :- Hangman game powered by Python and ASCII Art 19 | 20 | - [jokes.py](https://github.com/MayankPratap/i_love_python/blob/master/jokes.py) :- Bullshit Jokes 21 | 22 | - [multithreaddownloadXkcd.py](https://github.com/MayankPratap/i_love_python/blob/master/multithreaddownloadXkcd.py) :- Added Multithreaded Xkcd Comics Downloader 23 | 24 | - [playVideo.py](https://github.com/MayankPratap/i_love_python/blob/master/playVideo.py) :- Playing Video File using Python Script 25 | 26 | - [python_org_search.py](https://github.com/MayankPratap/i_love_python/blob/master/python_org_search.py) :- uses selenium to automatcally launch a browser and go to python.org and then uses python.org search functionality to search for "pycon" 27 | 28 | - [sendTweetsUsingTwython.py](https://github.com/MayankPratap/i_love_python/blob/master/sendTweetsUsingTwython.py) :- Python Script to send tweets using Twython Module 29 | 30 | - [sendemail2.py](https://github.com/MayankPratap/i_love_python/blob/master/sendemail2.py) :- Python script to send email with subject 31 | 32 | - [socialsites.py](https://github.com/MayankPratap/i_love_python/blob/master/socialsites.py) :- Python script to open my favorite social sites in seperate tabs 33 | 34 | - [stopwatch.py](https://github.com/MayankPratap/i_love_python/blob/master/stopwatch.py) :- Stopwatch powered by Python 35 | 36 | - [textMyself.py](https://github.com/MayankPratap/i_love_python/blob/master/textMyself.py) :- Added code to send me text messages using Python 37 | 38 | - [tweet_image.py](https://github.com/MayankPratap/i_love_python/blob/master/tweet_image.py) :- Tweet images using Tweepy and Raspberry Camera Module 39 | 40 | - [write_test_in_python.py](https://github.com/MayankPratap/i_love_python/blob/master/write_test_in_python.py) :- Unit tests in python using selenium and unittest module 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ScrapeJames.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | # ScrapeJames.py - Downloads every James Altucher's Post 3 | 4 | import requests,os,bs4,urllib.request 5 | 6 | 7 | url='http://jamesaltucher.com/page/' 8 | os.makedirs('jamesaltucher',exist_ok=True)# Store all posts of james in this folder 9 | 10 | page=1 11 | 12 | while 1==1: 13 | 14 | loadurl=url+str(page) 15 | page+=1 16 | res=requests.get(loadurl) 17 | try: 18 | res.raise_for_status() 19 | soup=bs4.BeautifulSoup(res.text,"html5lib") 20 | posts=soup.select('.post-title a') 21 | i=0 22 | 23 | while i0: 11 | # print("Hello") 12 | print(timeLeft,end=' ') 13 | time.sleep(1) 14 | timeLeft=timeLeft-1 15 | 16 | 17 | # At the end of the countdown,play a sound file 18 | 19 | # 'see' in linux acts as double clicking a file 20 | # In windows use 'start' 21 | # In OSX use 'open' 22 | 23 | subprocess.Popen(['see','jiya.mp3']) 24 | -------------------------------------------------------------------------------- /downloadXkcd.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | # downloadXkcd.py - Downloads evry single XKCD comic. 3 | 4 | import requests,os,bs4 5 | 6 | url='http://xkcd.com' # starting url 7 | os.makedirs('xkcd',exist_ok=True)# Store comics in ./xkcd 8 | 9 | while not url.endswith('#'): 10 | # Download the page. 11 | print('Downloading page %s...' % url) 12 | res=requests.get(url) 13 | try: 14 | res.raise_for_status() 15 | soup=bs4.BeautifulSoup(res.text) 16 | comicElem=soup.select('#comic img') 17 | if comicElem==[]: 18 | print('Could not find comic image.') 19 | else: 20 | comicUrl='http:'+comicElem[0].get('src') 21 | # Download the image. 22 | print('Downloading image %s...'%(comicUrl)) 23 | res=requests.get(comicUrl) 24 | res.raise_for_status() 25 | 26 | # Save the image to ./xkcd. 27 | imageFile=open(os.path.join('xkcd',os.path.basename(comicUrl)),'wb') 28 | for chunk in res.iter_content(100000): 29 | imageFile.write(chunk) 30 | 31 | imageFile.close() 32 | 33 | # Get the Prev button's url. 34 | prevLink=soup.select('a[rel="prev"]')[0] 35 | url='http://xkcd.com'+prevLink.get('href') 36 | 37 | except Exception as exc: 38 | print('There was a problem: %s' % (exc)) 39 | 40 | print('Done.') 41 | -------------------------------------------------------------------------------- /get_topcoder_tutorial.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import pdfcrowd 3 | import urllib2 4 | import os 5 | 6 | from bs4 import BeautifulSoup,SoupStrainer 7 | 8 | url="https://www.topcoder.com/community/data-science/data-science-tutorials/" 9 | 10 | def save_as_pdf(link,filename): 11 | 12 | try: 13 | 14 | client=pdfcrowd.Client("MayankPratap", "28d53cddfd1b63f50748fd6c58ad0646") 15 | output_file=open(filename,'wb') 16 | page=requests.get(link) 17 | soup=BeautifulSoup(page.text) 18 | html=soup.find_all('div',{'class':'container'}) 19 | 20 | client.convertHtml(''.join(map(str,html)),output_file) 21 | output_file.close() 22 | print filename," saved" 23 | except pdfcrowd.Error,why: 24 | 25 | print "Failed:",why 26 | 27 | page=requests.get(url) 28 | page_bs=BeautifulSoup(page.text) 29 | 30 | tutorial_links=[] 31 | 32 | for link_detail in page_bs.select('a[href]'): 33 | 34 | link=link_detail.get('href') 35 | if link.startswith(url): 36 | tutorial_links.append(link) 37 | 38 | for link in tutorial_links: 39 | link=link[:-1] 40 | #print link 41 | fileName=os.path.basename(link)+'.pdf' 42 | #print fileName 43 | save_as_pdf(link,fileName) 44 | 45 | -------------------------------------------------------------------------------- /hangman.py: -------------------------------------------------------------------------------- 1 | # A simple hangman game powered by ASCII ART AND PYTHON 2 | 3 | import random 4 | HANGMANPICS=[''' 5 | 6 | +----+ 7 | | | 8 | | 9 | | 10 | | 11 | | 12 | | 13 | | 14 | ====== ''',''' 15 | 16 | +----+ 17 | | | 18 | 0 | 19 | | 20 | | 21 | | 22 | | 23 | | 24 | ====== ''',''' 25 | 26 | +----+ 27 | | | 28 | 0 | 29 | | | 30 | | 31 | | 32 | | 33 | | 34 | ====== ''',''' 35 | 36 | +----+ 37 | | | 38 | 0 | 39 | /| | 40 | | 41 | | 42 | | 43 | | 44 | ====== ''',''' 45 | +----+ 46 | | | 47 | 0 | 48 | /|\ | 49 | | 50 | | 51 | | 52 | | 53 | ====== ''',''' 54 | 55 | +----+ 56 | | | 57 | 0 | 58 | /|\ | 59 | | 60 | | 61 | | 62 | | 63 | ====== ''',''' 64 | +----+ 65 | | | 66 | 0 | 67 | /|\ | 68 | / | 69 | | 70 | | 71 | | 72 | ====== ''',''' 73 | 74 | +----+ 75 | | | 76 | 0 | 77 | /|\ | 78 | / \ | 79 | | 80 | | 81 | | 82 | ======= ''' ] 83 | 84 | words='kane,undertaker,rock,brock,lita,hogan,edge,show,hbk,cena,orton,henry,sheamus'.split(',') 85 | 86 | def getRandomWord(wordList): 87 | # This function returns a random string from passes list of strings. 88 | wordIndex=random.randint(0,len(wordList)-1) 89 | return wordList[wordIndex] 90 | 91 | def displayBoard(HANGMANPICS,missedLetters,correctLetters,secretWord): 92 | print(HANGMANPICS[len(missedLetters)]) 93 | print() 94 | 95 | print('Missed letters:',end=' ') 96 | for letter in missedLetters: 97 | print(letter,end=' ') 98 | print() 99 | 100 | blanks='_'*len(secretWord) 101 | 102 | for i in range(len(secretWord)): # Replace blanks with correctly guessed letters 103 | if secretWord[i] in correctLetters: 104 | blanks=blanks[:i]+secretWord[i]+blanks[i+1:] 105 | 106 | for letter in blanks: 107 | print(letter,end=' ') 108 | 109 | print() 110 | 111 | def getGuess(alreadyGuessed): 112 | while True: 113 | print('Guess a letter.') 114 | guess=input() 115 | guess=guess.lower() 116 | 117 | if len(guess)!=1: 118 | print('Please enter a single letter') 119 | 120 | elif guess in alreadyGuessed: 121 | print('You have already guessed that letter.Choose Again') 122 | elif guess not in 'abcdefghijklmnopqrstuvwxyz': 123 | print('Please enter a LETTER') 124 | else: 125 | return guess 126 | 127 | def playAgain(): 128 | # This function returns True if player wants to play again 129 | 130 | print('Do you want to play again?(yes or no)') 131 | return input().lower().startswith('y') 132 | 133 | 134 | print('H A N G M A N') 135 | missedLetters='' 136 | correctLetters='' 137 | 138 | secretWord=getRandomWord(words) 139 | gameIsDone=False 140 | 141 | while True: 142 | displayBoard(HANGMANPICS,missedLetters,correctLetters,secretWord) 143 | 144 | # Let the player type in a letter 145 | guess=getGuess(missedLetters+correctLetters) 146 | 147 | foundAllLetters=False 148 | 149 | if guess in secretWord: 150 | correctLetters=correctLetters+guess 151 | foundAllLetters=True 152 | for i in range(len(secretWord)): 153 | if secretWord[i] not in correctLetters: 154 | foundAllLetters=False 155 | break 156 | 157 | if foundAllLetters: 158 | print('Yes! The secret word is "' + secretWord + ' "! You have won!') 159 | gameIsDone=True 160 | 161 | if guess not in secretWord: 162 | missedLetters=missedLetters+guess 163 | 164 | # Check if player has taken too many guesess and lost 165 | 166 | if len(missedLetters)==len(HANGMANPICS)-1: 167 | displayBoard(HANGMANPICS,missedLetters,correctLetters,secretWord) 168 | print('You have run out of guesses!\nAfter '+str(len(missedLetters))+' missed guesses and '+str(len(correctLetters))+' correct guesses,the word was "'+secretWord+'"') 169 | 170 | gameIsDone=True 171 | 172 | if gameIsDone: 173 | if playAgain(): 174 | missedLetters='' 175 | correctLetters='' 176 | gameIsDone=False 177 | secretWord=getRandomWord(words) 178 | else: 179 | break 180 | 181 | -------------------------------------------------------------------------------- /i_am_feeling_lucky.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | #i_am_feeling_lucky.py - Takes Search Parameters from command line and gets first 5 search results and opens them in 3 | # in a browser in seperate tabs. 4 | 5 | import webbrowser,sys,requests,bs4 6 | 7 | if len(sys.argv)>1: 8 | # Get search parameters from command line and join them to form a single parameter 9 | query=' '.join(sys.argv[1:]) 10 | res=requests.get('https://www.google.co.in/search?q='+query) 11 | try: 12 | res.raise_for_status() 13 | soup=bs4.BeautifulSoup(res.text,"html5lib") 14 | topresults=soup.select(".r a") 15 | 16 | numOpen = min(5, len(topresults)) 17 | 18 | for i in range(numOpen): 19 | webbrowser.open('http://google.com'+topresults[i].get('href')) 20 | 21 | 22 | 23 | 24 | 25 | except Exception as exc: 26 | print('There was a problem: %s' % (exc)) 27 | 28 | 29 | 30 | 31 | 32 | else : 33 | print('Please enter a search query') 34 | -------------------------------------------------------------------------------- /jokes.py: -------------------------------------------------------------------------------- 1 | # A very simple game in python 2 | 3 | print('What do you get when you cross a snowman with a vampire?') 4 | input() 5 | print('frostbite!') 6 | print() 7 | print('What dou dentists call a astronaut\'s cavity?') 8 | input() 9 | print('A black hole!') 10 | print() 11 | print('Knock Knock') 12 | input() 13 | print("Who's there?") 14 | input() 15 | print('Interrupting cow.') 16 | input() 17 | print('Interrupting cow wh',end='') 18 | print('-MOO!') 19 | -------------------------------------------------------------------------------- /multithreaddownloadXkcd.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | 3 | # multidonwloadXkcd.py - Downloads XKCD comics using multiple threads 4 | 5 | import requests,os,bs4,threading 6 | 7 | os.makedirs('xkcdnew',exist_ok=True) # Store comics in ./xkcd 8 | 9 | def downloadXkcd(startComic,endComic): 10 | for urlNumber in range(startComic,endComic): 11 | # Download the page. 12 | print("Downloading page http://xkcd.com/%s.."%(urlNumber)) 13 | res=requests.get("http://xkcd.com/%s"%(urlNumber)) 14 | res.raise_for_status() 15 | 16 | soup=bs4.BeautifulSoup(res.text) 17 | 18 | # Find the URL of comic image. 19 | 20 | comicElem=soup.select("#comic img") 21 | 22 | if comicElem==[]: 23 | print("Could not find comic image.") 24 | else: 25 | comicUrl=comicElem[0].get('src') 26 | # Download the image. 27 | print("Downloading image %s..."%(comicUrl)) 28 | res=requests.get(comicUrl) 29 | res.raise_for_status() 30 | 31 | # Save the image to ./xkcdnew 32 | imageFile=open(os.path.join('xkcdnew',os.path.basename(comicUrl)),"wb") 33 | 34 | for chunk in res.iter_content(100000): 35 | imageFile.write(chunk) 36 | imageFile.close() 37 | 38 | 39 | downloadThreads=[] # A list of all thread objects 40 | for i in range(0,1400,100): # Loops 14 times,creates 14 threads 41 | downloadThread=threading.Thread(target=downloadXkcd,args=(i,i+99)) 42 | downloadThreads.append(downloadThread) 43 | downloadThread.start() 44 | 45 | for downloadThread in downloadThreads: 46 | downloadThread.join() 47 | 48 | print("Done.") 49 | -------------------------------------------------------------------------------- /playVideo.py: -------------------------------------------------------------------------------- 1 | # This script plays a video file , we can change the speed of video playback or exit video playback in between. 2 | 3 | import numpy as np 4 | import cv2 5 | 6 | cap=cv2.VideoCapture('output.avi') 7 | 8 | while(cap.isOpened()): 9 | 10 | ret,frame=cap.read() 11 | 12 | gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) 13 | 14 | cv2.imshow('frame',gray) 15 | 16 | if cv2.waitKey(25) & 0xFF == ord('q'): 17 | break 18 | 19 | 20 | cap.release() 21 | cv2.destroyAllWindows() 22 | -------------------------------------------------------------------------------- /python_org_search.py: -------------------------------------------------------------------------------- 1 | # Script uses selenium to automatcally launch a browser and go to python.org and then uses python.org search functionality to search for "pycon" 2 | 3 | 4 | from selenium import webdriver 5 | from selenium.webdriver.common.keys import Keys 6 | 7 | driver=webdriver.Firefox() 8 | driver.get('http://www.python.org') 9 | assert "Python" in driver.title 10 | 11 | elem=driver.find_element_by_name("q") 12 | elem.send_keys("pycon") 13 | elem.send_keys(Keys.RETURN) 14 | assert "No results found." not in driver.page_source 15 | driver.close() 16 | -------------------------------------------------------------------------------- /sendTweetsUsingTwython.py: -------------------------------------------------------------------------------- 1 | from twython import Twython 2 | 3 | APP_KEY='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 4 | APP_SECRET='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 5 | ACCESS_TOKEN='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 6 | ACCESS_TOKEN_SECRET='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 7 | 8 | # Creating twittter object using Twython 9 | 10 | twitter = Twython(APP_KEY,APP_SECRET,ACCESS_TOKEN,ACCESS_TOKEN_SECRET) 11 | 12 | # Updating status using update_status attribute of twitter object 13 | 14 | twitter.update_status(status='Now I will undergo Beta testing') 15 | -------------------------------------------------------------------------------- /sendemail2.py: -------------------------------------------------------------------------------- 1 | #!python2 2 | 3 | # This script sends email to a person in a clean way 4 | 5 | # You have to allow "less secure apps" on your gmail account before running this script. 6 | 7 | import smtplib,getpass 8 | 9 | from email.MIMEMultipart import MIMEMultipart 10 | from email.MIMEText import MIMEText 11 | 12 | pw=getpass.getpass() 13 | 14 | 15 | 16 | fromaddr = " XYZ@gmail.com " 17 | toaddr = " ZYX@gmail.com " 18 | 19 | msg = MIMEMultipart() 20 | msg['From'] = fromaddr 21 | msg['To'] = toaddr 22 | msg['Subject'] = " Sending mail using terminal, just for fun " 23 | 24 | body = " Hey ZYX , whats going on ?? I was learning how to send mail from terminal using Python , So I just mailed you ... Sorry for disturbing :( " 25 | 26 | msg.attach(MIMEText(body,'plain')) 27 | 28 | 29 | 30 | server=smtplib.SMTP('smtp.gmail.com',587) 31 | server.starttls() 32 | server.login(fromaddr,pw) 33 | text=msg.as_string() 34 | server.sendmail(fromaddr,toaddr,text) 35 | server.quit() 36 | -------------------------------------------------------------------------------- /socialsites.py: -------------------------------------------------------------------------------- 1 | #!python3 2 | #socialsites.py Launches Several Sites simultaneously in seperate tabs simultaneously 3 | # Names of sites to be entered in command line seperated by spaces 4 | 5 | 6 | import webbrowser,sys 7 | 8 | if len(sys.argv)>1: 9 | # Get name of social network sites from command line 10 | i=1 11 | while i") 27 | l = l[0] 28 | l = l.split('"') 29 | link = "http://apod.nasa.gov/"+l[1] 30 | response = requests.get(link) 31 | 32 | x = time.strftime("%d%m%Y") 33 | 34 | name = "img"+x+".jpg" 35 | os.system("touch "+name) 36 | with open(name, 'wb') as f: 37 | f.write(response.content) 38 | 39 | 40 | os.system("feh --bg-scale "+name) 41 | -------------------------------------------------------------------------------- /write_test_in_python.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | 5 | class PythonOrgSearch(unittest.TestCase): 6 | 7 | def setUp(self): 8 | self.driver=webdriver.Firefox() 9 | 10 | def test_search_in_python_org(self): 11 | driver=self.driver 12 | driver.get("http://www.python.org") 13 | self.assertIn("Python",driver.title) 14 | elem=driver.find_element_by_name("q") 15 | elem.send_keys("pycon") 16 | elem.send_keys(Keys.RETURN) 17 | assert "No results found. " not in driver.page_source 18 | 19 | def tearDown(self): 20 | self.driver.close() 21 | 22 | 23 | if __name__ =="__main__": 24 | unittest.main() 25 | 26 | --------------------------------------------------------------------------------