Advertisement
Guest User

NHScraper

a guest
Mar 6th, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.07 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import os
  4. import json
  5. import requests
  6. import argparse
  7. from bs4 import BeautifulSoup
  8.  
  9. class nhentai(object):
  10.     base_url = 'http://nhentai.net/'
  11.     prefix = ''
  12.     suffix = ''
  13.  
  14.     def __init__(self, directory='hentai', prefix='', suffix=''):
  15.         if directory:
  16.             if os.path.isdir(directory):
  17.                 if directory.endswith('/'):
  18.                     self.directory = directory
  19.                 else:
  20.                     self.directory = directory + '/'
  21.             else:
  22.                 print('[-] ' + directory + ' does not exist')
  23.                 print('[*] Defaulting to hentai')
  24.  
  25.                 if not os.path.isdir(directory):
  26.                     os.makedirs('hentai')
  27.  
  28.                 self.directory = 'hentai/'
  29.         else:
  30.             self.directory = 'hentai/'
  31.  
  32.         if prefix:
  33.             self.prefix = ''.join(i for i in prefix if i.isalnum() or i in [' ', '.', '_']).rstrip()
  34.  
  35.         if suffix:
  36.             self.suffix = ''.join(i for i in suffix if i.isalnum() or i in [' ', '.', '_']).rstrip()
  37.  
  38.     def getData(self, url):
  39.         data = None
  40.  
  41.         while not data:
  42.             try:
  43.                 r = requests.get(url, timeout=10)
  44.                 data = r.text
  45.             except Exception as e:
  46.                 print('[-] Error: ' + str(e))
  47.  
  48.         return data
  49.  
  50.     def getLastPage(self, base_url=''):
  51.         if not base_url:
  52.             base_url = self.base_url
  53.  
  54.         data = self.getData(base_url + '?page=1')
  55.         soup = BeautifulSoup(data, 'html.parser')
  56.  
  57.         return int(soup.find('a', {'class': 'last'})['href'].replace('?page=', ''))
  58.  
  59.     def getGalleryIds(self, base_url='', limit=None):
  60.         if not base_url:
  61.             base_url = self.base_url
  62.  
  63.         ids = []
  64.  
  65.         for i in range(1, self.getLastPage(base_url) + 1):
  66.             if limit:
  67.                 if len(ids) > limit:
  68.                     break
  69.  
  70.             print('[*] Getting gallery ids from ' + self.base_url + '?page=' + str(i), end='\r')
  71.            
  72.             data = self.getData(self.base_url + '?page=' + str(i))
  73.             soup = BeautifulSoup(data, 'html.parser')
  74.  
  75.             for a in soup.findAll('a', {'class': 'cover'}):
  76.                 ids.append(a['href'].split('/')[2])
  77.  
  78.         if limit:
  79.             return ids[:limit]
  80.  
  81.         return ids
  82.  
  83.     def getGalleryInfo(self, url):
  84.         print('[*] Getting gallery info from ' + url, end='\r')
  85.         data = self.getData(url)
  86.         soup = BeautifulSoup(data, 'html.parser')
  87.  
  88.         gallery_info = {
  89.             'id': soup.find('div', {'id': 'cover'}).find('a')['href'].split('/')[2],
  90.             'url': 'http://' + soup.find('div', {'id': 'cover'}).find('img')['src'].replace('cover.jpg', '').replace('cover.png', '')[2:],
  91.             'name': soup.find('div', {'id': 'info'}).find('h1').getText().strip(),
  92.             'tags': [],
  93.             'ext': soup.find('div', {'id': 'cover'}).find('img')['src'][-3:],
  94.             'last': int(soup.findAll('a', {'class': 'gallerythumb'})[-1]['href'].split('/')[-2])
  95.         }
  96.  
  97.         for div in soup.findAll('div', {'class': 'field-name'}):
  98.             if 'Tags' in div.getText():
  99.                 for a in div.findAll('a', {'class': 'tag'}):
  100.                     gallery_info['tags'].append(a['href'][5:-1])
  101.  
  102.         return gallery_info
  103.  
  104.     def getGallery(self, url):
  105.         gallery_info = self.getGalleryInfo(url)
  106.         gallery = {
  107.             'name': gallery_info['name'],
  108.             'tags': gallery_info['tags'],
  109.             'directory': self.directory + gallery_info['id'] + '/',
  110.             'images': []
  111.         }
  112.  
  113.         for i in range(1, gallery_info['last'] + 1):
  114.             filename = str(i)
  115.  
  116.             if self.prefix:
  117.                 filename = self.prefix + '_' + filename
  118.  
  119.             if self.suffix:
  120.                 filename += '_' + self.suffix
  121.  
  122.             filename =  filename + '.' + gallery_info['ext']
  123.             image = {
  124.                 'filename': filename,
  125.                 'url': gallery_info['url'] + str(i) + 't.' + gallery_info['ext']
  126.             }
  127.             gallery['images'].append(image)
  128.  
  129.         return gallery
  130.  
  131.     def downloadImage(self, url, filename):
  132.         if not os.path.isfile(filename):
  133.             with open(filename, 'wb') as f:
  134.                 r = requests.get(url, stream=True)
  135.  
  136.                 if not r.ok:
  137.                     print('[-] Error: something went wrong')
  138.                 else:
  139.                     for block in r.iter_content(1024):
  140.                         f.write(block)
  141.  
  142.                     return True
  143.  
  144.         return False
  145.  
  146.     def downloadGallery(self, gid):
  147.         url = self.base_url + 'g/' + str(gid) + '/'
  148.         gallery = self.getGallery(url)
  149.         name = gallery['name']
  150.         tags = gallery['tags']
  151.         directory = gallery['directory']
  152.         images = gallery['images']
  153.  
  154.         print('[*] Downloading gallery ' + name + ' to ' + directory)
  155.  
  156.         if not os.path.exists(directory):
  157.             os.makedirs(directory)
  158.  
  159.         with open(directory + 'info.json', 'w') as f:
  160.             json.dump({
  161.                 'url': url,
  162.                 'name': name,
  163.                 'tags': tags
  164.             }, f)
  165.  
  166.         for image in images:
  167.             url = image['url']
  168.             filename = directory + image['filename']
  169.             self.downloadImage(url, filename)
  170.  
  171.     def downloadGalleries(self, gids=[], tags=[], limit=None):
  172.         if not gids and not tags:
  173.             gids = self.getGalleryIds(limit=limit)
  174.         elif not gids and tags:
  175.             gids = []
  176.            
  177.             for tag in tags:
  178.                 for gid in self.getGalleryIds('http://nhentai.net/tag/' + tag + '/popular', limit=limit):
  179.                     gids.append(gid)
  180.  
  181.         for gid in gids:
  182.             try:
  183.                 self.downloadGallery(gid)
  184.             except Exception as e:
  185.                 print('[-] Error: ' + str(e))
  186.  
  187. parser = argparse.ArgumentParser(description='Simple nhentai.net scraper')
  188. parser.add_argument('-g', '--gallery', help='galleries to scrape')
  189. parser.add_argument('-t', '--tags', help='tags to scrape')
  190. parser.add_argument('-l', '--limit', help='max amount of albums to download')
  191. parser.add_argument('-d', '--dir', default='hentai', help='directory to save to')
  192. parser.add_argument('-p', '--prefix', default='', help='filename prefix')
  193. parser.add_argument('-s', '--suffix', default='', help='filename suffix')
  194. args = parser.parse_args()
  195.  
  196. nhentai = nhentai(args.dir, args.prefix, args.suffix)
  197.  
  198. if args.limit:
  199.     if args.limit.isnumeric() and int(args.limit) > 0:
  200.         limit = int(args.limit)
  201.     else:
  202.         limit = None
  203. else:
  204.     limit = None
  205.  
  206. if args.gallery:
  207.     if args.gallery.lower() == 'all':
  208.         nhentai.downloadGalleries(gids=[], tags=[], limit=limit)
  209.     else:
  210.         gids = []
  211.         galleries = args.gallery.split(',')
  212.         for gallery_range in galleries:
  213.             gallery_ranges = gallery_range.split('-')
  214.             if len(gallery_ranges) == 1:
  215.                 if gallery_ranges[0].isnumeric() and int(gallery_ranges[0]) > 0:
  216.                     gids.append(gallery_ranges[0])
  217.             elif len(gallery_ranges) == 2:
  218.                 if gallery_ranges[0].isnumeric() and int(gallery_ranges[0]) > 0:
  219.                     if gallery_ranges[1].isnumeric() and int(gallery_ranges[1]) > 0:
  220.                         if int(gallery_ranges[1]) > int(gallery_ranges[0]):
  221.                             min_range = int(gallery_ranges[0])
  222.                             max_range = int(gallery_ranges[1])
  223.                         else:
  224.                             min_range = int(gallery_ranges[1])
  225.                             max_range = int(gallery_ranges[0])
  226.                         for i in range(min_range, max_range + 1):
  227.                             gids.append(str(i))
  228.         if len(gids) > 0:
  229.             nhentai.downloadGalleries(gids=gids, tags=[], limit=limit)
  230. elif args.tags:
  231.     tags = args.tags.split(',')
  232.     nhentai.downloadGalleries(gids=[], tags=tags, limit=limit)
  233. else:
  234.     print('[-] Error: either -g or -t must be passed')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement