With this code
import os
with open('urls.txt') as f:
for line in f:
os.system("youtube-dl "+"--write-thumbnail "+"--skip-download "+"--yes-playlist " +line)
The first image in the playlist downloads, then I get an error message saying 'list' is not recognized as an internal or ex ternal command, operable program or batch file. In 'urls.txt' I have just one url of a Youtube playlist. The url is this:
https://www.youtube.com/watch?v=GA3St3Rf9Gs&list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
It's cutting off input after the & symbol. If I replace 'list' in the url with 'foo' I get the same message. What do I do to make youtube-dl accept playlist URL?
Your program has a major command injection security vulnerability. You have triggered this (with harmless code) by accident. You are executing
youtube-dl --write-thumbnail --skip-download --yes-playlist \
https://www.youtube.com/watch?v=GA3St3Rf9Gs&list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
Since the ampersand is a command character in shell scripts, you're running two commands
youtube-dl --write-thumbnail --skip-download --yes-playlist \
https://www.youtube.com/watch?v=GA3St3Rf9Gs
and
list=PL-uc0GihCvU9s24BT_mvTzt3zm7e2uDGm
Since there is no program with that name, the second command will likely fail.
To fix this, use proper subprocess invocations with subprocess:
import subprocess
with open('urls.txt') as f:
for line in f:
subprocess.check_call([
"youtube-dl",
"--write-thumbnail", "--skip-download", "--yes-playlist",
line])
All you have to do to fix this, quote the YouTube URL, as in:
yt-dlp --yes-playlist "https://www.youtube.com/watch?v=XArZ74galOE&list=PLDrswW4_QtejDZdLE4EOVXunQvqU18sPK"
Solved the problem.
Thanks to nav3916872
You can use the youtube_dl library directly in your script and pass the urls to download from.
import os
import youtube_dl
ydl_opts = {
'writethumbnail': True,
'skip_download': True,
'noplaylist': False
}
with open('urls.txt') as f:
sources = f.readlines()
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(sources)
in commandprompt , you just need to quote the url(with ampersand). You can try to escape the url(with ampersand) in the same way in python. Refer youtube-dl FAQ
Related
I am appending text to a file that requires sudo permissions. When I run this python script below:
import subprocess
ssid= "testing"
psk= "testing1234"
p1 = subprocess.Popen(["wpa_passphrase", ssid, psk], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["sudo","tee","-a","/etc/wpa_supplicant/wpa_supplicant.conf",">","/dev/null"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
output,err = p2.communicate
It will append to the file as expected, but will append this:
network={
ssid="testing"
#psk="testing1234"
psk=9891dab18debe8308a5d3bf596f5277e4a5c158bff016145830b12673ef63360
}
When I want this:
network={
ssid="testing"
psk="testing1234"
key_mgmt=WPA-PSK
}
This subprocess syntax is complicated to me, so I am open to an alternative method! I tried to use f=open("appendedtext >> /etc/wpa_supplicant/wpa_supplicant.conf") but I need to run as sudo and I can't seem to find a way to do this via open(). I get a permission error.
Any help is appreciated!!
It's not python or subrpocess issue, you're getting expected output from wpa_passphrase, see the man page:
NAME
wpa_passphrase - Generate a WPA PSK from an ASCII passphrase for a SSID
SYNOPSIS
wpa_passphrase [ ssid ] [ passphrase ]
OVERVIEW
wpa_passphrase pre-computes PSK entries for network configuration blocks of a wpa_supplicant.conf file. An ASCII passphrase and SSID are
used to generate a 256-bit PSK.
if you need plain text password just write it to file without calling wpa_passphrase:
with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'a') as conf:
conf.writelines(['network={\n', '\tssid="{0}"\n'.format(ssid), '\tpsk="{0}"\n'.format(psk), '\tkey_mgmt=WPA-PSK\n', '}\n'])
and don't forget to call it with sudo: sudo python script.py.
When I execute this [say filename as curl.py and execute by python curl.py]
import subprocess
import json
subprocess.call([
'curl',
'--digest',
'--user',
'user:pass',
'https://url'],
)
The output is a JSON file in my case.
I see the output on my terminal, but I want it to be stored in an object in the same python file.
How can I achieve this?
As per the comments, here's an alternative without curl. I am using requests here (pip install requests):
import requests
url = 'http://httpbin.org/digest-auth/auth/user/pass'
r = requests.get(url, auth=requests.auth.HTTPDigestAuth('user', 'pass'))
print(r.json()) # no need to unpack JSON manually!
Currently, I'm trying to convert CURL request to Python script.
curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq ".report.download" -r) > "C:\sample.zip"
I have tried pycurl, with no success, due to knowledge limitation.
As a solution, I have found, that it is possible to run commands through python.
https://www.raspberrypi.org/forums/viewtopic.php?t=112351
import os
os.system("curl -K.........")
And other solution ( based on the search more common) using subprocess
import subprocess
subprocess.call(['command', 'argument'])
Currently, I'm not sure where to move and how to adapt this solution to my sitionation.
import os
os.system("curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq '.report.download' -r) > 'C:\sample.zip'")
'curl' is not recognized as an internal or external command,
operable program or batch file.
255
P.S. - Update v1
Any suggestion?
import requests
response = requests.get('https://api.example.com/v1.1/reports/11111?fields=download | jq ".report.download" -r', auth=('username', 'password'))
This work without "| jq ".report.download" this part, but this is the main part which gives at the end only link to download the file.
ANy way around it?
The error 'curl' is not recognized as an internal or external command means that python couldn't find the location where curl is installed. If you have already installed curl, try giving the full path to where curl is installed. For example, if curl.exe is located in C:\System32, the try
import os
os.system("C:\System32\curl $(curl -u username:password -s https://api.example.com/v1.1/reports/11111?fields=download | jq '.report.download' -r) > 'C:\sample.zip'")
But thats definitely not pythonic way of doing things. I would instead suggest to use requests module.
You need to invoke requests module twice for this, first to download the json content from https://api.example.com/v1.1/reports/11111?fields=download, get a new url pointed byreport.download and then invoke requests again to download data from the new url.
Something along these lines should get you going
import requests
url = 'https://api.example.com/v1.1/reports/11111'
response = requests.get(url, params=(('fields', 'download'),),
auth=('username', 'password'))
report_url = response.json()['report']['download']
data = requests.get(report_url).content
with open('C:\sample.zip', 'w') as f:
f.write(data)
You can use this site to convert the actual curl part of your command to something that works with requests: https://curl.trillworks.com/
From there, just use the .json() method of the request object to do whatever processing you need to be doing.
Finally, can save like so:
import json
with open('C:\sample.zip', 'r') as f:
json.dump(data, f)
I am trying to download a file using python, imitating the same behavior as this curl command:
curl ftp://username:password#example.com \
--retry 999 \
--retry-max-time 0
-o 'target.txt' -C -
How would this look in python ?
Things I have looked into:
Requests : no ftp support
Python-wget: no download resume support
requests-ftp : no download resume support
fileDownloader : broken(?)
I am guessing one would need to build this from scratch and go low level with pycurl or urllib2 or something similar.
I am trying to create this script in python and I feel lost.. Should I just call curl from python subprocess ?
Any point to the write direction would be much appreciated
you can use python's inbuilt ftplib
Here is the code:
from ftplib import FTP
ftp = FTP('example.com', 'username', 'password') #logs in
ftp.retrlines() # to see the list of files and directories ftp.cwd('to change to any directory')
ftp.retrbinary('RETR filename', open('Desktop\filename', 'wb').write) # start downloading
ftp.close() # close the connection
Auto resume is supported. I even tried turning off my wifi and checked if the download is resuming.
You can refer to /Python27/Lib/ftplib.py for default GLOBAL_TIME_OUT settings.
there is this library for downloading files from ftp server
fileDownloader.py
to download the file
downloader = fileDownloader.DownloadFile(‘http://example.com/file.zip’, “C:UsersusernameDownloadsnewfilename.zip”, (‘username’,’password’))
downloader.download()
to resume download
downloader = fileDownloader.DownloadFile(‘http://example.com/file.zip’, “C:UsersusernameDownloadsnewfilename.zip”, (‘username’,’password’))
downloader.resume()
I would like to access the result of the following shell command,
youtube-dl -g "www.youtube.com/..."
to print its output direct url to a file, from within a python program. This is what I have tried:
import youtube-dl
fromurl="www.youtube.com/..."
geturl=youtube-dl.magiclyextracturlfromurl(fromurl)
Is that possible?
I tried to understand the mechanism in the source but got lost: youtube_dl/__init__.py, youtube_dl/youtube_DL.py, info_extractors ...
It's not difficult and actually documented:
import youtube_dl
ydl = youtube_dl.YoutubeDL({'outtmpl': '%(id)s.%(ext)s'})
with ydl:
result = ydl.extract_info(
'http://www.youtube.com/watch?v=BaW_jenozKc',
download=False # We just want to extract the info
)
if 'entries' in result:
# Can be a playlist or a list of videos
video = result['entries'][0]
else:
# Just a video
video = result
print(video)
video_url = video['url']
print(video_url)
For simple code,
may be i think
import os
os.system('youtube-dl [OPTIONS] URL [URL...]')
Above is just running command line inside python.
Other is mentioned in the documentation Using youtube-dl on python
Here is the way
from __future__ import unicode_literals
import youtube_dl
ydl_opts = {}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])
Here is a way.
We set-up options' string, in a list, just as we set-up command line arguments. In this case opts=['-g', 'videoID']. Then, invoke youtube_dl.main(opts). In this way, we write our custom .py module, import youtube_dl and then invoke the main() function.
from __future__ import unicode_literals
import youtube_dl
ydl_opts = {}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['Your youtube url'])
You can use 'format', 'continue', 'outtmpl' in ydl_opts
As example;
ydl_opts= {
'format': '22',
'continue': True,
'outtmpl': '%(uploader)s - %(title)s.%(ext)s',
'progress_hooks': [my_hook],
}
def my_hook(d):
if d['status'] == 'downloading':
print('Downloading video!')
if d['status'] == 'finished':
print('Downloaded!')
When you need to stop playlist downloading, Just add this code into ydl_opts.
'noplaylist': True;
Usage: python3 AudioFromYtVideo.py link outputName
import os
from sys import argv
try:
if argv[1] and argv[2]:
pass
except:
print("Input: python3 [programName] [url] [outputName]")
os.system('youtube-dl -x --audio-format mp3 -o '+argv[2]+' '+argv[1])
If youtube-dl is a terminal program, you can use the subprocess module to access the data you want.
Check out this link for more details: Calling an external command in Python
I would like this
from subprocess import call
command = "youtube-dl https://www.youtube.com/watch?v=NG3WygJmiVs -c"
call(command.split(), shell=False)