Compare commits

...

10 Commits

Author SHA1 Message Date
tnt2402
dbbf7cd80f update 2023-02-27 20:34:51 +07:00
tnt2402
8eae0b9181 update readme.md 2023-02-20 19:21:42 +07:00
tnt2402
6f3ba8c38f update readme.md 2023-02-20 19:19:47 +07:00
tnt2402
66b3c1fa6b change downloader to aria2c for better speed 2023-02-20 19:10:45 +07:00
tnt2402
2a13613d9a deprecate youtube-dl
using yt-dlp fork
2023-02-20 13:57:53 +07:00
tnt2402
f8e54b7b32 Merge branch 'main' of https://github.com/tnt2402/pornhub_dl 2023-02-19 23:52:31 +07:00
tnt2402
af3317cf9f maybe last update :> 2023-02-19 23:52:12 +07:00
tnt2402
4f11cd4ae7 update ReadMe.md 2023-02-19 23:43:49 +07:00
tnt2402
3cdb0b495c update --playlist arg 2023-02-19 23:39:52 +07:00
tnt2402
124c501da8 Update Readme.md 2022-12-30 00:06:05 +07:00
8 changed files with 123 additions and 57 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*.pyc
*.pyc

View File

@@ -5,7 +5,8 @@ PornHub-dl is a Python tool for downloading PornHub video/playlist.
## Requirements
```bash
Python 3.7 or later
ffmpeg
VPN or any anti - Deep Packet Inspection (if your ISP blocks Pornhub) ^-^
```
## Installation
@@ -32,9 +33,11 @@ optional arguments:
# download single video from PornHub
pornhub_dl.py --url https://www.pornhub.com/view_video.php?viewkey=ph5b11c7f2ddecc
# download all videos (most viewed) from model CarryLight of PornHub
# download first 30 videos (default = best) from model CarryLight
pornhub_dl.py --url https://www.pornhub.com/model/carrylight --playlist --limit 30
# download all videos (most viewed) from model CarryLight
pornhub_dl.py --url https://www.pornhub.com/model/carrylight --playlist most-viewed
# download first 30 videos (most viewed) from model CarryLight of PornHub
# download first 30 videos (most viewed) from model CarryLight
pornhub_dl.py --url https://www.pornhub.com/model/carrylight --playlist most-viewed --limit 30
```
@@ -47,12 +50,16 @@ Please make sure to update tests as appropriate.
[MIT](https://choosealicense.com/licenses/mit/)
## Special thanks
YouTube-DL (the world's most powerful tool)
```
YouTube-DL (the world's most powerful tool)
aria2c (a f*ckinn lightweight multi-source command-line download utility)
PyFiglet (simple and beauty)
BeautifulSoup4
@ValdikSS for his Deep Packet Inspection circumvention utility (github.com/ValdikSS/GoodbyeDPI)
@mariosemes for his PornHub-downloader (github.com/mariosemes/PornHub-downloader-python)
```
# from tnt2402 with <3
# from tnt2402 with <3

BIN
aria2c.exe Normal file

Binary file not shown.

View File

@@ -10,18 +10,22 @@ import json
from time import sleep
from tqdm import tqdm
#############
def ascii_banner(text):
print('\n\n########################################################\n\n\n')
ascii_banner = pyfiglet.figlet_format(text)
print(ascii_banner)
print(ascii_banner)
################################
duration = 1000
download_dir = os.getcwd()
# duration = 1000
download_dir = os.getcwd()
def ph_config_dl_dir(dir):
global download_dir
if (dir != None):
if (dir != None):
download_dir = dir
print("Output directory: " + download_dir + "\model\\")
if (os.path.exists(download_dir) != True):
@@ -31,39 +35,63 @@ def ph_config_dl_dir(dir):
if (os.path.exists(download_dir) != True):
os.mkdir(download_dir)
### Main functions
def run_command(command):
try:
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
pbar = tqdm(total=100, unit=" percents")
state = 0
current_frag = 0
total_frag = 1
result_txt = ''
while True:
output = process.stdout.readline().decode("utf-8")
if "[download] 100" in output:
result_txt = 'Result: ' + output.split("[download]")[1].strip()
if output == '' and process.poll() is not None:
break
if 'Total fragments' in output:
total_frag = int(output.split(':')[1].strip())
if 'FILE:' in output:
current_frag = int(output.split('.part-Frag')[1].strip())
current_per = int(current_frag / total_frag * 100)
pbar.update(current_per - state)
state = current_per
sleep(0.00001)
pbar.update(100 - state)
pbar.close()
rc = process.poll()
if result_txt != '': print(result_txt)
return rc
except Exception as e:
print(e)
sys.exit(0)
# Main functions
def ph_check_valid_pornhub_url(url):
if ('pornhub.com' not in url):
print('Invalid Pornhub URL')
sys.exit()
if url.startswith('pornhub.com'):
url = 'https://www.' + url
return url
return url
def download_video(url, filename):
global duration
# global duration
state = 0
print('[+] Save as: ' + filename + '\n')
try:
pbar = tqdm(total=duration, unit= " fragments")
p = subprocess.Popen(['.\youtube-dl', '--no-warnings', '--hls-prefer-ffmpeg', '--ffmpeg-location', os.getcwd(), '-o', filename, url], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell = False)
for line in iter(p.stdout.readline, b''):
line = line.decode('utf-8').strip()
# if ("[ffmpeg] " in line):
# print('\n' + line.strip())
if "time=" in line:
time = line.split("time=")[1][:8]
hour, minute, second = time.split(":")
progress_time = 3600 * int(hour) + 60 * int(minute) + int(second)
pbar.update(progress_time - state)
state = progress_time
sleep(0.001)
elif "Failed" in line:
print("\nFailed while processing")
sys.exit(1)
pbar.update(duration)
pbar.close()
# print("\n[$] Video download successfully!")
run_command(['.\yt-dlp', '--downloader', 'aria2c', '--downloader-args',
'aria2c:-x 8 --log-level=info --file-allocation=none --summary-interval=1', '--no-warnings', '--newline', '-o', filename, url])
print("[$] Video download successfully!")
except KeyboardInterrupt:
os.kill(p.pid, signal.CTRL_C_EVENT)
sys.exit()
@@ -74,65 +102,88 @@ def fix_title(s):
deny_char = ['\\', '/', '.', '?', '*', ':', '!']
for i in deny_char:
decoded_unicode = decoded_unicode.replace(i, '')
return decoded_unicode
return decoded_unicode.strip()
def check_output_dir(model_name):
global download_dir
download_dir = download_dir
download_dir = download_dir
if (os.path.exists(download_dir + model_name) != True):
os.mkdir(download_dir+model_name)
def ph_download_video(url, model_name, filename):
try:
try:
check_output_dir(model_name)
# filename = os.path.join(download_dir, model_name, fix_title(str(video["title"])) + '.' + str(video['ext']))
download_video(url, filename)
except:
print('Cannot download video')
def ph_download_playlist(url, model_name, limit):
global download_dir
global duration
# global duration
check_output_dir(model_name)
if (limit != 0):
print("[!] Limit: {} videos".format(limit))
# tmp_playlist download
print('... Getting playlist information...')
playlist_download_command = [".\youtube-dl", "-j", "--flat-playlist", "--no-check-certificate", url]
res = subprocess.run(playlist_download_command, capture_output=True, text=True).stdout.split("\n")
if (limit != 0 ):
print("[!] Limit: {} videos".format(limit))
try:
playlist_download_command = [".\yt-dlp", "-j",
"--flat-playlist", "--no-check-certificate", url]
res = subprocess.run(playlist_download_command,
capture_output=True, text=True).stdout.split("\n")
except Exception as e:
print(e)
sys.exit(1)
count = 0
if res == ['']:
print("Cannot download playlist information!")
sys.exit(1)
print("Playlist has {} videos".format(len(res)))
for i in range(len(res) - 1):
if (count == limit and limit != 0):
break
sys.exit()
try:
video_dict = ast.literal_eval(res[i])
# print(res[i])
# video_dict = ast.literal_eval(res[i])
video_dict = json.loads(res[i])
url = video_dict['url']
p = subprocess.Popen(['.\youtube-dl', '--no-warnings', '--dump-json', '--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell = True)
p = subprocess.Popen(['.\yt-dlp', '--no-warnings', '--dump-json',
'--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell=True)
output = p.communicate()[0]
info = json.loads(output.decode('utf-8'))
duration = int(info['duration'])
filename = os.path.join(download_dir, model_name, fix_title(str(info["title"])) + '.' + str(info['ext']))
print("\n\n==========================================\n[+] File #{}: {}".format(count, fix_title(str(info["title"])) + '.' + str(info['ext'])))
# duration = int(info['duration'])
filename = os.path.join(download_dir, model_name, fix_title(
str(info["title"])) + '.' + str(info['ext']))
print("\n\n==========================================\n[+] File #{}: {}".format(
count, fix_title(str(info["title"])) + '.' + str(info['ext'])))
ph_download_video(url, model_name, filename)
count = count + 1
except KeyboardInterrupt:
print("Cannot download video")
sys.exit()
def fix_url(url, type):
url = ph_check_valid_pornhub_url(url)
if '/model/' not in url:
p = subprocess.Popen(['.\youtube-dl', '--no-warnings', '--dump-json', '--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell = True)
p = subprocess.Popen(['.\yt-dlp', '--no-warnings', '--dump-json',
'--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell=True)
output = p.communicate()[0]
info = json.loads(output.decode('utf-8'))
model_name = info['uploader']
else:
model_name = url.split('/model/')[1].split('/')[0]
url = 'www.pornhub.com/model/' + model_name + '/videos'
if (type == 'most-viewed'):
url = url + '?o=mv'
@@ -143,20 +194,25 @@ def fix_url(url, type):
print("[+] Model: " + model_name)
return (url, model_name)
def ph_get_video(url):
global duration
# global duration
url = ph_check_valid_pornhub_url(url)
p = subprocess.Popen(['.\youtube-dl', '--no-warnings', '--dump-json', '--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell = True)
p = subprocess.Popen(['.\yt-dlp', '--no-warnings', '--dump-json',
'--skip-download', url], stdout=subprocess.PIPE, stderr=None, shell=True)
output = p.communicate()[0]
info = json.loads(output.decode('utf-8'))
model_name = info['uploader']
duration = int(info['duration'])
filename = os.path.join(download_dir, model_name, fix_title(str(info["title"])) + '.' + str(info['ext']))
# duration = int(info['duration'])
filename = os.path.join(download_dir, model_name, fix_title(
str(info["title"])) + '.' + str(info['ext']))
print("[+] Model: " + model_name)
print("[+] Filename: " + fix_title(str(info["title"])) + '.' + str(info['ext']))
print("[+] Filename: " + fix_title(str(info["title"])) +
'.' + str(info['ext']))
ph_download_video(url, model_name, filename)
def ph_get_playlist(url, type, limit):
url, model_name = fix_url(url, type)
ph_download_playlist(url, model_name, limit)
ph_download_playlist(url, model_name, limit)

View File

@@ -16,7 +16,7 @@ else:
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--url', type=str, help = 'URL of Pornhub video')
parser.add_argument('--playlist', choices = ['most-viewed', 'best', 'top-rated', 'longest'], type=str, help = 'Optional ordering of videos')
parser.add_argument('--playlist', nargs='?', const='best', choices = ['most-viewed', 'best', 'top-rated', 'longest'], help = 'Optional ordering of videos')
parser.add_argument('--limit', type=int, help = 'Maximum number of videos', default=0)
parser.add_argument('--dir', type=str, help = 'Output directory')
args = parser.parse_args()

Binary file not shown.

BIN
yt-dlp.exe Normal file

Binary file not shown.