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