]> git.lizzy.rs Git - nhentai.git/blob - nhentai/parser.py
project is now Py3 and Py2 compatible
[nhentai.git] / nhentai / parser.py
1 # coding: utf-8
2 from __future__ import print_function
3
4 from bs4 import BeautifulSoup
5 import re
6 import requests
7 from tabulate import tabulate
8
9 import nhentai.constant as constant
10 from nhentai.logger import logger
11
12
13 def request(method, url, **kwargs):
14     if not hasattr(requests, method):
15         raise AttributeError('\'requests\' object has no attribute \'{0}\''.format(method))
16
17     return requests.__dict__[method](url, proxies=constant.PROXY, **kwargs)
18
19
20 def doujinshi_parser(id_):
21     if not isinstance(id_, (int,)) and (isinstance(id_, (str,)) and not id_.isdigit()):
22         raise Exception('Doujinshi id({0}) is not valid'.format(id_))
23
24     id_ = int(id_)
25     logger.log(15, 'Fetching doujinshi information of id {0}'.format(id_))
26     doujinshi = dict()
27     doujinshi['id'] = id_
28     url = '{0}/{1}/'.format(constant.DETAIL_URL, id_)
29
30     try:
31         response = request('get', url).content
32     except Exception as e:
33         logger.critical(str(e))
34         exit(1)
35
36     html = BeautifulSoup(response)
37     doujinshi_info = html.find('div', attrs={'id': 'info'})
38
39     title = doujinshi_info.find('h1').text
40     subtitle = doujinshi_info.find('h2')
41
42     doujinshi['name'] = title
43     doujinshi['subtitle'] = subtitle.text if subtitle else ''
44
45     doujinshi_cover = html.find('div', attrs={'id': 'cover'})
46     img_id = re.search('/galleries/([\d]+)/cover\.(jpg|png)$', doujinshi_cover.a.img['src'])
47     if not img_id:
48         logger.critical('Tried yo get image id failed')
49         exit(1)
50
51     doujinshi['img_id'] = img_id.group(1)
52     doujinshi['ext'] = img_id.group(2)
53
54     pages = 0
55     for _ in doujinshi_info.find_all('div', class_=''):
56         pages = re.search('([\d]+) pages', _.text)
57         if pages:
58             pages = pages.group(1)
59             break
60     doujinshi['pages'] = int(pages)
61
62     # gain information of the doujinshi
63     information_fields = doujinshi_info.find_all('div', attrs={'class': 'field-name'})
64     needed_fields = ['Characters', 'Artists', 'Language', 'Tags']
65     for field in information_fields:
66         field_name = field.contents[0].strip().strip(':')
67         if field_name in needed_fields:
68             data = [sub_field.contents[0].strip() for sub_field in
69                     field.find_all('a', attrs={'class': 'tag'})]
70             doujinshi[field_name.lower()] = ', '.join(data)
71
72     return doujinshi
73
74
75 def search_parser(keyword, page):
76     logger.debug('Searching doujinshis of keyword {0}'.format(keyword))
77     result = []
78     try:
79         response = request('get', url=constant.SEARCH_URL, params={'q': keyword, 'page': page}).content
80     except requests.ConnectionError as e:
81         logger.critical(e)
82         logger.warn('If you are in China, please configure the proxy to fu*k GFW.')
83         exit(1)
84
85     html = BeautifulSoup(response)
86     doujinshi_search_result = html.find_all('div', attrs={'class': 'gallery'})
87     for doujinshi in doujinshi_search_result:
88         doujinshi_container = doujinshi.find('div', attrs={'class': 'caption'})
89         title = doujinshi_container.text.strip()
90         title = (title[:85] + '..') if len(title) > 85 else title
91         id_ = re.search('/g/(\d+)/', doujinshi.a['href']).group(1)
92         result.append({'id': id_, 'title': title})
93     return result
94
95
96 def print_doujinshi(doujinshi_list):
97     if not doujinshi_list:
98         return
99     doujinshi_list = [i.values() for i in doujinshi_list]
100     headers = ['id', 'doujinshi']
101     logger.info('Search Result\n' +
102                 tabulate(tabular_data=doujinshi_list, headers=headers, tablefmt='rst'))
103
104 if __name__ == '__main__':
105     print(doujinshi_parser("32271"))