2

I am using selenium to do a click function on a hyperlink, which is loaded on a certain page. The script works for google chrome, but does not for phantomjs. Why is this not working?

from selenium import webdriver

driver = webdriver.Chrome()   
#driver = webdriver.PhantomJS(executable_path = "/Users/jameslemieux/PythonProjects/phantomjs-1.9.8-macosx/bin/phantomjs")

driver.get("http://www.youtube-mp3.org/?e=t_exp&r=true#v=hC-T0rC6m7I")

elem = driver.find_element_by_link_text('Download')
elem.click()


driver.save_screenshot('/Users/jameslemieux/Desktop/Misc./test_image.png')

driver.quit()

This works in chrome, but it always opens up a new chrome window to complete the task. I read that I should use phantomjs to have it run behind the scenes, however when i switch the drivers to phantomjs, the download does not seem to go through. The screenshot grabs, and it is indeed at the right page, and the 'Download' is definitely there. So the

elem.click()

is not doing what it should, or it IS clicking, but phantomjs doesnt know how to deal with a direct download link. Please help, ive been at this for hours on end.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
James Lemieux
  • 720
  • 1
  • 9
  • 26
  • 2
    PhantomJS doesn't (never) trigger a download. You have to explicitly download it by using XHR or something else with a direct url, but there is a limitation that it will stop downloading at the 30 seconds mark. – Artjom B. Jan 12 '15 at 22:03
  • @ArtjomB. good point, the download part can be handled via `urlretrieve()` as shown below. – alecxe Jan 12 '15 at 22:11

1 Answers1

4

Since PhantomJS would never proceed with a download request, we need to download the file manually.

The idea here is to click the "Convert" button, wait for the "Download" link to appear, get the href attribute, containing the link to the generated mp3 file, and download it via urllib.urlretrieve():

import urllib
from urlparse import urljoin

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

base_url = 'http://www.youtube-mp3.org/'

driver = webdriver.PhantomJS()
driver.get("http://www.youtube-mp3.org/?e=t_exp&r=true#v=hC-T0rC6m7I")

# convert the video to mp3
driver.find_element_by_id('submit').click()

# wait for download link to appear
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.LINK_TEXT, "Download")))
link = element.get_attribute('href')
url = urljoin(base_url, link)

# download the song
urllib.urlretrieve(url, 'song.mp3')

driver.quit()

# enjoy the great song
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thank you for the answer! but unfortunately it doesnt work for me. what do you substitute for 'song.mp3'? When i run your above code, i get `IOError: [Errno 13] Permission denied: 'song.mp3'` – James Lemieux Jan 13 '15 at 02:17
  • 1
    @user2565883 may be you don't have permission to write to the directory. Try specifying an absolute path to the file. – alecxe Jan 13 '15 at 02:31
  • That fixed it! However, now if only i could find a way to get the title of the youtube video to save as the .mp3, instead of 'song'... – James Lemieux Jan 13 '15 at 02:50
  • @user2565883 well, you can let `urlretrieve()` do it - just don't supply the filename at all. – alecxe Jan 13 '15 at 03:23
  • like `urllib.urlretrieve(url)` ? It runs the script but does not download anything, as far as i know. I also tried `urllib.urlretrieve(url, 'C:\Users\user_name\Downloads')` I was denied permissions again. – James Lemieux Jan 13 '15 at 03:33