opening URL in browser with python (not headless) - python

I am not taking about headless browser.
I am writing an script, when a directory get a new file, it will open an url, when the file deleted from directory, it will open another url.
My Script is below:
import os, time
def folderListener(mydir):
old_list = len(os.listdir(mydir))
new_list = 0
while True:
new_list = len(os.listdir(mydir))
if old_list != new_list:
old_list = new_list
print('OPen first url in chrom browser')
else:
print('Open 2nd URL in Chrome Browser')
time.sleep(2)
if __name__ == '__main__':
mydir = os.getcwd() + '/testdir'
folderListener(mydir)
The script working very nice, now i need to it in the script when print function place. i mean, it should open an URL on Chrome Browser instead, no headless chrome browser.

You could look into webbrowser.
Used like:
import webbrowser
url = "http://mywebsite.com"
webbrowser.open_new(url) # open in default browser
webbrowser.get('safari').open_new(url) # open in safari if available
webbrowser.get('firefox').open_new_tab(url) # open in firefox if available
webbrowser.get(using='google-chrome').open_new(url) # open in chrome if available
But considering you tagged selenium-webdriver you could also do this:
from selenium import webdriver
url = "http://mywebsite.com"
driver = webdriver.Chrome()
driver.get(url)

Related

Selenium - How to open url in active/current tab in python

def get_status(driver):
try:
driver.execute(Command.STATUS)
return "Alive"
except (socket.error, httplib.CannotSendRequest):
return "Dead"
if get_status(driver) == 'Alive':
#using this opens a whole new window but i want to go to another website in same tab.
driver.get('https://www.amazon.in')
else :
driver.get('https://www.google.in')
so basically i want to open a new url in the active tab of chrome/firefox browser. but i failed to find any workaround. i hope you can answer this question.
all tutorials on this redirect me to java function
driver.navigate.to()
which is not working in python.
This code did open a new URL within the same tab.
from selenium import webdriver
from selenium.webdriver.remote.command import Command
import http.client as httplib
import socket
def get_status(driver):
try:
driver.execute(Command.STATUS)
return "Alive"
except (socket.error, httplib.CannotSendRequest):
return "Dead"
driver = webdriver.Chrome(executable_path="path to chromedriver.exe")
driver.maximize_window()
driver.implicitly_wait(20)
driver.get("https://www.youtube.com/")
if get_status(driver) == 'Alive':
# using this opens a whole new window but i want to go to another website in same tab.
driver.get('https://www.amazon.in')
else:
driver.get('https://www.google.in')
driver.quit()

Driver.get a group of links?

How do I use driver.get to open several URLs in Chrome.
My code:
import requests
import json
import pandas as pd
from selenium import webdriver
chromeOptions = webdriver.ChromeOptions()
chromedriver = r"C:\Users\Harrison Pollock\Downloads\Python\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(executable_path=r"C:\Users\Harrison Pollock\Downloads\Python\chromedriver_win32\chromedriver.exe",chrome_options=chromeOptions)
links = []
request1 = requests.get('https://api.beta.tab.com.au/v1/recommendation-service/featured-events?jurisdiction=NSW')
json1 = request1.json()
for n in json1['nextToGoRaces']:
if n['meeting']['location'] in ['VIC','NSW','QLD','SA','WA','TAS','IRL']:
links.append(n['_links']['self'])
driver.get('links')
Based on the comments - you'll want a class to manage your browsers, a class for your tests, then a runner to run in parallel.
Try this:
import unittest
import time
import testtools
from selenium import webdriver
class BrowserManager:
browsers=[]
def createBrowser(self, url):
browser = webdriver.Chrome()
browser.get(url)
self.browsers.append(browser)
def getBrowserByPartialURL(self, url):
for browser in self.browsers:
if url in browser.current_url:
return browser
def CloseItAllDown(self):
for browser in self.browsers:
browser.close()
class UnitTest1(unittest.TestCase):
def test_DoStuffOnGoogle(self):
browser = b.getBrowserByPartialURL("google")
#Point of this is to watch the output! you'll see this +other test intermingled (proves parallel run)
for i in range(10):
print(browser.current_url)
time.sleep(1)
def test_DoStuffOnYahoo(self):
browser = b.getBrowserByPartialURL("yahoo")
#Point of this is to watch the output! you'll see this +other test intermingled (proves parallel run)
for i in range(10):
print(browser.current_url)
time.sleep(1)
#create a global variable for the brwosers
b = BrowserManager()
# To Run the tests
if __name__ == "__main__":
##move to an init to Create your browers
b.createBrowser("https://www.google.com")
b.createBrowser("https://www.yahoo.com")
time.sleep(5) # This is so you can see both open at the same time
suite = unittest.TestLoader().loadTestsFromTestCase(UnitTest1)
concurrent_suite = testtools.ConcurrentStreamTestSuite(lambda: ((case, None) for case in suite))
concurrent_suite.run(testtools.StreamResult())
This code doesn't do anything exciting - it's an example of how to manage multiple browsers and run tests in parallel. It goes to the specified urls (which you should move to an init/setup), then prints out the URL it's on 10 times.
This is how you add a browser to the manager: b.createBrowser("https://www.google.com")
This is how you retrieve your browser: browser = b.getBrowserByPartialURL("google") - note it's a partial URL so you can use the domain as a keyword.
This is the output (just the first few lines- not all of it...) - It's a print URL for google then yahoo, then google then yahoo - showing that they're running at the same time:
PS C:\Git\PythonSelenium\BrowserManager> cd 'c:\Git\PythonSelenium'; & 'C:\Python38\python.exe' 'c:\Users\User\.vscode\extensions\ms-python.python-2020.7.96456\pythonFiles\lib\python\debugpy\launcher' '62426' '--' 'c:\Git\PythonSelenium\BrowserManager\BrowserManager.py'
DevTools listening on ws://127.0.0.1:62436/devtools/browser/7260dee3-368c-4f21-bd59-2932f3122b2e
DevTools listening on ws://127.0.0.1:62463/devtools/browser/9a7ce919-23bd-4fee-b302-8d7481c4afcd
https://www.google.com/
https://consent.yahoo.com/collectConsent?sessionId=3_cc-session_d548b656-8315-4eef-bb1d-82fd4c6469f8&lang=en-GB&inline=false
https://www.google.com/
https://consent.yahoo.com/collectConsent?sessionId=3_cc-session_d548b656-8315-4eef-bb1d-82fd4c6469f8&lang=en-GB&inline=false
https://www.google.com/

How to open an HTML file in the browser from Python?

I am trying to open an HTML file from Python but my script just displays the contents of the HTML file in Python instead of opening it in the browser. How can I fix this problem? How can I open the HTML file in my Chrome browser?
testdata.html
<div>
<img src="https://plot.ly/~user001/2.png" alt="Success vs Failure" style="max-width: 100%;width: 600px;" width="600" onerror="this.onerror=null;this.src='https://plot.ly/404.png';" />
<script data-plotly="user001:2" src="https://plot.ly/embed.js" async></script>
</div>
Python 2.7 script:
import urllib
page = urllib.urlopen('testdata.html').read()
print page
Try specifying the "file://" at the start of the URL.
// Also, use the absolute path of the file:
webbrowser.open('file://' + os.path.realpath(filename))
Or
import webbrowser
new = 2 # open in a new tab, if possible
// open a public URL, in this case, the webbrowser docs
url = "http://docs.python.org/library/webbrowser.html"
webbrowser.open(url,new=new)
// open an HTML file on my own (Windows) computer
url = "file://d/testdata.html"
webbrowser.open(url,new=new)
import os
os.system("start [your's_url]")
Enjoy!
You can use webbrowser library:
import webbrowser
url = 'file:///path/to/your/file/testdata.html'
webbrowser.open(url, new=2) # open in new tab
Here's a way that doesn't require external libraries and that can work of local files as well.
import subprocess
import os
url = "https://stackoverflow.com"
# or a file on your computer
# url = "/Users/yourusername/Desktop/index.html
try: # should work on Windows
os.startfile(url)
except AttributeError:
try: # should work on MacOS and most linux versions
subprocess.call(['open', url])
except:
print('Could not open URL')
You can use Selenium.
download the latest chromedriver, paste the chromedriver.exe in "C:\Python27\Scripts".
then
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("your page path")
print driver.page_source.encode('utf-8')
driver.quit()
display.stop()
I feel this is the easiest solution:
import os
os.getcwd() #To check the current working directory or path
os.chdir("D:\\Folder Name\\") # D:\Folder Name\ is the new path where you want to save the converted dataframe(df) to .html file
import webbrowser
df.to_html("filename.html") #Converting dataframe df to html and saving with a name 'filename' and
webbrowser.get("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s").open("file://" + os.path.realpath("filename.html"))
you can download latest version of "gecodriver" from here.then add gecodriver executable file to your project.then pip install selenium and below the code for windows:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import os
#optional
options = Options()
options.set_preference('permissions.default.image', 2)
options.set_preference('dom.ipc.plugins.enabled.libflashplayer.so', False)
#for windows
Driver = webdriver.Firefox(options=options, executable_path='geckodriver.exe')
Driver.implicitly_wait(15)
#path of your project -> reference : "https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure/40227116"
Root = os.path.dirname(os.path.abspath(__file__))
driver.get('file://' + Root + 'path/to/htmlfile')
Hope I Helped You:)
import os
os.system('open "/Applications/Safari.app" '+ '"' + os.path.realpath(fname)+ '"')

webbrowser, opening chrome and internet explore for different url

url = 'http://www.google.org/'
chrome_path = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe %s'
webbrowser.get(chrome_path)
webbrowser.open(url)
above will open chrome, which is what I want.
However if I change the url to url = 'reddit it will open internet explore instead. Why does it open different webbrowsers for different urls? And how can I make sure it opens in chrome for all urls?
Do this:
>>> import webbrowser
>>> browser = webbrowser.get()
>>> browser.open('http://google.com')
True
>>> browser.open_new_tab('http://yahoo.com')
True
>>>
The webbrowser.get() call will get you a browser controller object. You can run open, open_new and open_new_tab on the controller object. This will ensure the commands are executed on the same browser instance you opened.
If you directly use webbrowser.open() - it will always open the link in the default browser, which in your case is Internet Explorer.
So to rewrite your code:
chrome_path = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
chrome = webbrowser.get(chrome_path)
chrome.open('http://google.com')
chrome.open_new_tab('http://reddit.com')

How can I download a file on a click event using selenium?

I am working on python and selenium. I want to download file from clicking event using selenium. I wrote following code.
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get("http://www.drugcite.com/?q=ACTIMMUNE")
browser.close()
I want to download both files from links with name "Export Data" from given url. How can I achieve it as it works with click event only?
Find the link using find_element(s)_by_*, then call click method.
from selenium import webdriver
# To prevent download dialog
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', '/tmp')
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv')
browser = webdriver.Firefox(profile)
browser.get("http://www.drugcite.com/?q=ACTIMMUNE")
browser.find_element_by_id('exportpt').click()
browser.find_element_by_id('exporthlgt').click()
Added profile manipulation code to prevent download dialog.
I'll admit this solution is a little more "hacky" than the Firefox Profile saveToDisk alternative, but it works across both Chrome and Firefox, and doesn't rely on a browser-specific feature which could change at any time. And if nothing else, maybe this will give someone a little different perspective on how to solve future challenges.
Prerequisites: Ensure you have selenium and pyvirtualdisplay installed...
Python 2: sudo pip install selenium pyvirtualdisplay
Python 3: sudo pip3 install selenium pyvirtualdisplay
The Magic
import pyvirtualdisplay
import selenium
import selenium.webdriver
import time
import base64
import json
root_url = 'https://www.google.com'
download_url = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
print('Opening virtual display')
display = pyvirtualdisplay.Display(visible=0, size=(1280, 1024,))
display.start()
print('\tDone')
print('Opening web browser')
driver = selenium.webdriver.Firefox()
#driver = selenium.webdriver.Chrome() # Alternately, give Chrome a try
print('\tDone')
print('Retrieving initial web page')
driver.get(root_url)
print('\tDone')
print('Injecting retrieval code into web page')
driver.execute_script("""
window.file_contents = null;
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
window.file_contents = reader.result;
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', %(download_url)s);
xhr.send();
""".replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') % {
'download_url': json.dumps(download_url),
})
print('Looping until file is retrieved')
downloaded_file = None
while downloaded_file is None:
# Returns the file retrieved base64 encoded (perfect for downloading binary)
downloaded_file = driver.execute_script('return (window.file_contents !== null ? window.file_contents.split(\',\')[1] : null);')
print(downloaded_file)
if not downloaded_file:
print('\tNot downloaded, waiting...')
time.sleep(0.5)
print('\tDone')
print('Writing file to disk')
fp = open('google-logo.png', 'wb')
fp.write(base64.b64decode(downloaded_file))
fp.close()
print('\tDone')
driver.close() # close web browser, or it'll persist after python exits.
display.popen.kill() # close virtual display, or it'll persist after python exits.
Explaination
We first load a URL on the domain we're targeting a file download from. This allows us to perform an AJAX request on that domain, without running into cross site scripting issues.
Next, we're injecting some javascript into the DOM which fires off an AJAX request. Once the AJAX request returns a response, we take the response and load it into a FileReader object. From there we can extract the base64 encoded content of the file by calling readAsDataUrl(). We're then taking the base64 encoded content and appending it to window, a gobally accessible variable.
Finally, because the AJAX request is asynchronous, we enter a Python while loop waiting for the content to be appended to the window. Once it's appended, we decode the base64 content retrieved from the window and save it to a file.
This solution should work across all modern browsers supported by Selenium, and works whether text or binary, and across all mime types.
Alternate Approach
While I haven't tested this, Selenium does afford you the ability to wait until an element is present in the DOM. Rather than looping until a globally accessible variable is populated, you could create an element with a particular ID in the DOM and use the binding of that element as the trigger to retrieve the downloaded file.
In chrome what I do is downloading the files by clicking on the links, then I open chrome://downloads page and then retrieve the downloaded files list from shadow DOM like this:
docs = document
.querySelector('downloads-manager')
.shadowRoot.querySelector('#downloads-list')
.getElementsByTagName('downloads-item')
This solution is restrained to chrome, the data also contains information like file path and download date. (note this code is from JS, may not be the correct python syntax)
Here is the full working code. You can use web scraping to enter the username password and other field. For getting the field names appearing on the webpage, use inspect element. Element name(Username,Password or Click Button) can be entered through class or name.
from selenium import webdriver
# Using Chrome to access web
options = webdriver.ChromeOptions()
options.add_argument("download.default_directory=C:/Test") # Set the download Path
driver = webdriver.Chrome(options=options)
# Open the website
try:
driver.get('xxxx') # Your Website Address
password_box = driver.find_element_by_name('password')
password_box.send_keys('xxxx') #Password
download_button = driver.find_element_by_class_name('link_w_pass')
download_button.click()
driver.quit()
except:
driver.quit()
print("Faulty URL")

Categories