├── 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 |
6 |
7 |
8 |
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 | 
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 |
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\n404 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\n404 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\n404 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\n404 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
--------------------------------------------------------------------------------