├── LICENSE ├── README.md ├── imgs ├── newf.jpg ├── r34-img-hd.jpg ├── r34-img-sd.jpg ├── r34-img2-hd.jpeg ├── r34-img2-sd.jpg └── r34.gif ├── py_code ├── rule34-downloader-hd.py └── rule34-downloader-sd.py ├── requirements.txt ├── rule34-downloader-HD.exe └── rule34-downloader-SD.exe /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Silver 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rule34-Downloader 2 | 3 | 4 |

5 | GitHub last commit 6 | GitHub contributors 7 | GitHub All Releases 8 | GitHub repo size 9 |

10 | 11 | * [What is Rule34 Downloader](#what-is-rule34-downloader) 12 | * [Installation](#installation) 13 | * [Usage](#usage) 14 | * [Difference between SD and HD downloader](#difference-between-sd-and-hd-downloader) 15 | * [Working Demo](#working-demo) 16 | * [Creator](#creator) 17 | 18 | 19 | # What is Rule34 Downloader 20 | Rule34 Downloader allows you to download every images and videos present in [rule34.xxx](https://rule34.xxx) site. The rule34 downloader comes in two flavours the SD image downloader and the HD image downloader. 21 | 22 | ### Current supported sites 23 | * rule34.xxx 24 | 25 | # Installation 26 | You can directly install tbe exe programs and run them _or_ if you want to run it using the python code make sure you have all the required dependencies installed. To install the dependencies open the ```terminal / cmd``` in this project directory and write the following command: 27 | ``` 28 | $ pip install -r requirements.txt 29 | ``` 30 | # Usage 31 | Using rule34 downloader is very easy. It is a very light weight CLI application program. 32 | All you need to do is to enter the appropriate tags and it automatically downloads all the images/videos with those tags. 33 | The tags follows the same convention as that of rule34.xxx site. 34 | 35 | Provide space between tags 36 | 37 | eg: 38 | ``` 39 | Enter Tags: erza_scarlet big_breasts nude 40 | ``` 41 | This will download all the images/videos that have tags ```erza_scarlet```, ```big_breasts```, ```nude```. 42 | 43 | # Difference between SD and HD downloader 44 | As the name says the SD downloader downloads the SD version of the image (generally 850 x 1160) whereas the HD downloader downloads the HD version of the image (4050 x 3050). 45 | 46 | __NOTE:__ _The HD downloader is little slower than the SD downloader, since it searches for HD image links which adds a good amount of overhead._ 47 | 48 | For example look at the following two images (_open the image in new tab_). 49 |
50 | SD downloader [NSFW] 51 |

52 | 53 |

54 |
55 | 56 |
57 | HD downloader [NSFW] 58 |

59 | 60 |

61 |
62 | 63 | # Working Demo 64 | This is a working demo for __SD__ downloader 65 | 66 | ![demo gif](imgs/r34.gif) 67 | 68 | # Creator 69 | __email:__ rahulsilver03@gmail.com 70 | __twitter:__ [@RaulSilv3r](https://twitter.com/RaulSilv3r) 71 | __reddit:__ [u/demonic_END](https://www.reddit.com/user/demonic_END) 72 | 73 | Twitter Follow 74 | 75 | -------------------------------------------------------------------------------- /imgs/newf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/newf.jpg -------------------------------------------------------------------------------- /imgs/r34-img-hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/r34-img-hd.jpg -------------------------------------------------------------------------------- /imgs/r34-img-sd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/r34-img-sd.jpg -------------------------------------------------------------------------------- /imgs/r34-img2-hd.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/r34-img2-hd.jpeg -------------------------------------------------------------------------------- /imgs/r34-img2-sd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/r34-img2-sd.jpg -------------------------------------------------------------------------------- /imgs/r34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/imgs/r34.gif -------------------------------------------------------------------------------- /py_code/rule34-downloader-hd.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | from bs4 import BeautifulSoup 4 | import time 5 | from termcolor import * 6 | import colorama 7 | import re 8 | 9 | colorama.init() 10 | 11 | class Post: 12 | def __init__(self,url,post_type): 13 | self.url = url 14 | self.post_type = post_type 15 | 16 | def content(self): 17 | print(self.url) 18 | print(self.post_type) 19 | 20 | def image_ext(url): 21 | url = re.split('.jpg|.png|.jpeg|.gif',url)[0] 22 | try: 23 | res_jpg = requests.get(f"{url}.jpg").content 24 | if(res_jpg != b'\n404 Not Found\n\n

404 Not Found

\n
nginx
\n\n\n'): 25 | return f"{url}.jpg" 26 | res_png = requests.get(f"{url}.png").content 27 | if(res_png != b'\n404 Not Found\n\n

404 Not Found

\n
nginx
\n\n\n'): 28 | return f"{url}.png" 29 | res_jpeg = requests.get(f"{url}.jpeg").content 30 | if(res_jpeg != b'\n404 Not Found\n\n

404 Not Found

\n
nginx
\n\n\n'): 31 | return f"{url}.jpeg" 32 | res_gif = requests.get(f"{url}.gif").content 33 | if(res_gif != b'\n404 Not Found\n\n

404 Not Found

\n
nginx
\n\n\n'): 34 | return f"{url}.gif" 35 | except: 36 | pass 37 | 38 | def contentpresent(url): 39 | res = requests.get(url).text 40 | sf = BeautifulSoup(res, 'lxml') 41 | content = sf.findAll('span', {'class': 'thumb'}) 42 | if(len(content) != 0): 43 | return True 44 | return False 45 | 46 | 47 | def main(): 48 | cprint("==== Welcome to Rule34 downloader ====", 'red') 49 | print() 50 | cprint("Rule34 downloader allows you to download all the images present in Rule34.xxx site", 'yellow') 51 | cprint("Just enter the appropriate tags and it will download all images of that tag into your computer!", 'yellow') 52 | cprint("For tags follow the same convention that used in Rule34", 'yellow') 53 | cprint("For more information visit the https://github.com/RaulS963/Rule34-Downloader", 'yellow') 54 | print() 55 | prompt_txt = colored("Enter Tags: ",'green') 56 | print(f"{prompt_txt}",end='') 57 | tags = input().split() 58 | print(f'searching tags: {tags}') 59 | 60 | url = f"https://rule34.xxx/index.php?page=post&s=list&tags={'+'.join(tags)}+&pid=0" 61 | 62 | pid = 0 63 | page = 1 64 | display_msg = 0 65 | success_dwnld = 0 66 | img_array = [] 67 | video_array = [] 68 | posts = [] 69 | print("searching...") 70 | while(contentpresent(url) and len(img_array) < 50): 71 | if(display_msg == 0): 72 | print() 73 | cprint("searching for image links....", "cyan") 74 | cprint("This process might take 2-3 mins to complete", "cyan") 75 | cprint("please be patient..", "cyan") 76 | print() 77 | display_msg += 1 78 | 79 | print(f'collecting images from page = {page} | pid = {pid}') 80 | res = requests.get(url).text 81 | soup = BeautifulSoup(res, 'lxml') 82 | thumbnails = soup.findAll("span", {'class': 'thumb'}) 83 | temp_array = [] 84 | temp_vid_array = [] 85 | for i in thumbnails: 86 | link = f"https://rule34.xxx/{i.a['href']}" 87 | # main image 88 | main = requests.get(link).text 89 | soupf = BeautifulSoup(main, 'lxml') 90 | #find images/gifs 91 | try: 92 | img_url = soupf.find('img', {'id': 'image'})['src'] 93 | if('//samples/' in img_url): 94 | img_url = img_url.replace('samples','images') 95 | img_url = img_url.replace('sample_','') 96 | img_url = img_url.split('?')[0] 97 | img_url = image_ext(img_url) 98 | #posts.append(Post(img_url,'image')) 99 | temp_array.append(img_url) 100 | except: 101 | pass 102 | #find videos 103 | try: 104 | video_url = soupf.find("source",{'type':'video/mp4'})['src'] 105 | temp_vid_array.append(video_url) 106 | #posts.append(Post(video_url,'video')) 107 | except: 108 | pass 109 | 110 | 111 | pid = pid + len(temp_array) 112 | img_array.extend(temp_array) 113 | video_array.extend(temp_vid_array) 114 | print(f"page {page} done!",end=' ') 115 | cprint(f"[ total file count: {len(img_array) + len(video_array)} ; image: {len(img_array)} ; videos: {len(video_array)} ]",'magenta') 116 | url = f"https://rule34.xxx/index.php?page=post&s=list&tags={'+'.join(tags)}+&pid={pid}" 117 | page += 1 118 | 119 | #image-search over 120 | #image download begins 121 | print() 122 | count = 1 123 | if(len(img_array) == 0): 124 | cprint("== OOPSie!! ==",'red') 125 | cprint(">>> no images found with those tags!",'red') 126 | cprint(">>> Try with other tags",'red') 127 | cprint(">>> Or check the spellings",'red') 128 | else: 129 | print(f'{len(img_array)} images detected!') 130 | for img_url in img_array: 131 | f_ext = '.jpg' 132 | if('.png' in img_url): 133 | f_ext = '.png' 134 | elif('.jpeg' in img_url): 135 | f_ext = '.jpeg' 136 | elif('.gif' in img_url): 137 | f_ext = '.gif' 138 | 139 | img_url = img_url.split('?')[0] 140 | byte_data = requests.get(img_url).content 141 | if(os.path.isdir('rule34 images') == False): 142 | os.makedirs('rule34 images') 143 | print("created new directory 'rule34 images'!") 144 | try: 145 | file_name = 'rule34 images/' + str(time.time())[:-4] + f_ext 146 | f = open(file_name,'wb') 147 | f.write(byte_data) 148 | print(f"[{count}/{len(img_array)}] {img_url} downloaded!") 149 | success_dwnld += 1 150 | count += 1 151 | except: 152 | print(f"{img_url} an error occured!") 153 | finally: 154 | f.close() 155 | print(f"{success_dwnld} of {len(img_array)} images downloaded successfully") 156 | 157 | 158 | while(True): 159 | main() 160 | print() 161 | cprint("Ready for another round!",'yellow') 162 | cprint("You can download more images by continuing..",'yellow') 163 | print() 164 | ch = input("Enter [c] to continue; else any other key to exit: ") 165 | if(ch.lower() != 'c'): 166 | break 167 | os.system('cls') -------------------------------------------------------------------------------- /py_code/rule34-downloader-sd.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | from bs4 import BeautifulSoup 4 | import time 5 | from termcolor import * 6 | import colorama 7 | import re 8 | 9 | colorama.init() 10 | 11 | def contentpresent(url): 12 | res = requests.get(url).text 13 | sf = BeautifulSoup(res, 'lxml') 14 | content = sf.findAll('span', {'class': 'thumb'}) 15 | if(len(content) != 0): 16 | return True 17 | return False 18 | 19 | def download_prompt(): 20 | num = input("Enter the no. of images that you want to download?: ") 21 | if(num.isnumeric() == False): 22 | cprint("invalid input!",'red') 23 | num = download_prompt() 24 | return int(num) 25 | 26 | 27 | def main(): 28 | cprint("==== Welcome to Rule34 downloader ====", 'red') 29 | print() 30 | cprint("Rule34 downloader allows you to download all the images present in Rule34.xxx site", 'yellow') 31 | cprint("Just enter the appropriate tags and it will download all images of that tag into your computer!", 'yellow') 32 | cprint("For tags follow the same convention that used in Rule34", 'yellow') 33 | cprint("For more information visit the https://github.com/RaulS963/Rule34-Downloader", 'yellow') 34 | print() 35 | prompt_txt = colored("Enter Tags: ",'green') 36 | print(f"{prompt_txt}",end='') 37 | tags = input().split() 38 | print(f'searching tags: {tags}') 39 | 40 | url = f"https://rule34.xxx/index.php?page=post&s=list&tags={'+'.join(tags)}+&pid=0" 41 | 42 | pid = 0 43 | page = 1 44 | display_msg = 0 45 | success_dwnld = 0 46 | img_array = [] 47 | video_array = [] 48 | print("searching...") 49 | while(contentpresent(url)): 50 | if(display_msg == 0): 51 | print() 52 | cprint("searching for image links....", "cyan") 53 | cprint("This process might take 2-3 mins to complete", "cyan") 54 | cprint("please be patient..", "cyan") 55 | print() 56 | display_msg += 1 57 | 58 | print(f'collecting images from page = {page} | pid = {pid}') 59 | res = requests.get(url).text 60 | soup = BeautifulSoup(res, 'lxml') 61 | thumbnails = soup.findAll("span", {'class': 'thumb'}) 62 | temp_array = [] 63 | temp_vid_array = [] 64 | for i in thumbnails: 65 | link = f"https://rule34.xxx/{i.a['href']}" 66 | # main image 67 | main = requests.get(link).text 68 | soupf = BeautifulSoup(main, 'lxml') 69 | #find images/gifs 70 | try: 71 | img_url = soupf.find('img', {'id': 'image'})['src'] 72 | temp_array.append(img_url) 73 | except: 74 | pass 75 | #find videos 76 | try: 77 | video_url = soupf.find("source",{'type':'video/mp4'})['src'] 78 | temp_vid_array.append(video_url) 79 | #posts.append(Post(video_url,'video')) 80 | except: 81 | pass 82 | 83 | 84 | pid = pid + len(temp_array) 85 | img_array.extend(temp_array) 86 | video_array.extend(temp_vid_array) 87 | print(f"page {page} done!",end=' ') 88 | cprint(f"[ total file count: {len(img_array) + len(video_array)} ; image: {len(img_array)} ; videos: {len(video_array)} ]",'magenta') 89 | url = f"https://rule34.xxx/index.php?page=post&s=list&tags={'+'.join(tags)}+&pid={pid}" 90 | page += 1 91 | 92 | #image-search over 93 | #image download begins 94 | print() 95 | count = 1 96 | if(len(img_array) == 0): 97 | cprint("== OOPSie!! ==",'red') 98 | cprint(">>> no images found with those tags!",'red') 99 | cprint(">>> Try with other tags",'red') 100 | cprint(">>> Or check the spellings",'red') 101 | else: 102 | total_images_count = len(img_array) 103 | print(f'{total_images_count} images detected!') 104 | if(total_images_count >= 150): 105 | cprint("Wow!! thats a lot of images!",'yellow') 106 | cprint("You can download all images [or] download limited no. of images",'yellow') 107 | txt = colored(f'Do you want to download all {total_images_count} files? (y/n): ','yellow') 108 | print(txt,end='') 109 | choice = input() 110 | if(choice.lower() == 'n'): 111 | num = download_prompt() 112 | img_array = img_array[:num] 113 | 114 | for img_url in img_array: 115 | f_ext = '.jpg' 116 | if('.png' in img_url): 117 | f_ext = '.png' 118 | elif('.jpeg' in img_url): 119 | f_ext = '.jpeg' 120 | elif('.gif' in img_url): 121 | f_ext = '.gif' 122 | 123 | img_url = img_url.split('?')[0] 124 | byte_data = requests.get(img_url).content 125 | if(os.path.isdir('rule34 images') == False): 126 | os.makedirs('rule34 images') 127 | print("created new directory 'rule34 images'!") 128 | try: 129 | file_name = 'rule34 images/' + str(time.time())[:-4] + f_ext 130 | f = open(file_name,'wb') 131 | f.write(byte_data) 132 | print(f"[{count}/{len(img_array)}] {img_url} downloaded!") 133 | success_dwnld += 1 134 | count += 1 135 | except: 136 | print(f"{img_url} an error occured!") 137 | finally: 138 | f.close() 139 | print(f"{success_dwnld} of {len(img_array)} images downloaded successfully") 140 | 141 | 142 | while(True): 143 | main() 144 | print() 145 | cprint("Ready for another round!",'yellow') 146 | cprint("You can download more images by continuing..",'yellow') 147 | print() 148 | ch = input("Enter [c] to continue; else any other key to exit: ") 149 | if(ch.lower() != 'c'): 150 | break 151 | os.system('cls') 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | BeautifulSoup4 3 | lxml 4 | termcolor 5 | colorama 6 | -------------------------------------------------------------------------------- /rule34-downloader-HD.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/rule34-downloader-HD.exe -------------------------------------------------------------------------------- /rule34-downloader-SD.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RaulS963/Rule34-Downloader/02f312e4666c577b8d3465b2dd20e30dba6eb7f5/rule34-downloader-SD.exe --------------------------------------------------------------------------------