Create a gist now

Instantly share code, notes, and snippets.

@fumiya-kubota /bible_search.py Secret
Last active Dec 12, 2016

What would you like to do?
import re
import requests
from lxml import html
from itertools import islice, chain
from books import BOOKS
def book_suggester(text):
for name, value in BOOKS:
if name in text:
name, bible_code, book_code = value
if bible_code == 'old':
bible_type = '旧約聖書'
else:
bible_type = '新約聖書'
return bible_type, name, bible_code, book_code
return None
class SearchQuery:
TO_END = 1000
PATTERN = re.compile('(\d+)([^\d]+(\d+)([^\d]+(\d+))?)?')
def __init__(self, text):
super().__init__()
self.ready = False
self.bible_name = None
self.book_name = None
self.bible_code = None
self.book_code = None
value = book_suggester(text)
if value is None:
return
self.bible_name, self.book_name, self.bible_code, self.book_code = value
self.chapter = None
self.section_from = None
self.section_to = None
match = self.PATTERN.search(text)
if match is None:
return
self.chapter, _, section_from, _, section_to = [g for g in match.groups()]
try:
if section_from:
self.section_from = int(section_from)
if section_to:
self.section_to = int(section_to)
if self.section_from > self.section_to:
return
if not (section_from or section_to):
self.section_from = 1
self.section_to = self.TO_END
end_words = ('', '', '最後')
if any((end_word in text for end_word in end_words)):
self.section_to = self.TO_END
except ValueError:
return
self.ready = True
@property
def to_end_of_section(self):
return self.TO_END == self.section_to
class SearchResult:
def __init__(self, responses, query):
"""
:param [requests.Response] responses:
:param SearchQuery query:
"""
super().__init__()
self.sections = (bibletext.text for bibletext in chain.from_iterable(
(html.fromstring(response).find_class('bibletext') for response in responses)
))
self.query = query
self.result_text = None
def text(self):
"""
:rtype:str
"""
if not self.result_text:
bible_sections = ''
if self.query.section_from and self.query.section_to:
sections = islice(self.sections,
self.query.section_to - self.query.section_from + 1)
else:
sections = self.sections
for section, bible_text in enumerate(sections, self.query.section_from):
bible_sections += '({}){}'.format(section, bible_text.strip())
if bible_sections.strip():
self.result_text = bible_sections
return self.result_text
class BibleSearch:
URL = 'http://www.bible.or.jp/read/titlechapter.html'
@staticmethod
def search(query):
"""
:param SearchQuery query:
:rtype:SearchResult
"""
payload = {
'transBook': 'ni',
'testamenttype': query.bible_code,
'chapterKeyword': query.chapter,
}
if query.bible_code == 'old':
payload['bookNameNiOld'] = query.book_code
elif query.bible_code == 'new':
payload['bookNameNiNew'] = query.book_code
responses = []
# 1節のみ
if query.section_from and not query.section_to:
payload['sectionKeyword'] = query.section_from
responses.append(requests.post(BibleSearch.URL, data=payload).text)
return SearchResult(responses, query)
if query.section_from and query.section_to:
payload['limitCount'] = query.section_from - 1
responses.append(requests.post(BibleSearch.URL, data=payload).text)
# 取得しようとしている長さが20節以上の場合
if query.section_to - query.section_from >= 20:
response = responses[0]
root = html.fromstring(response)
all_count = int(root.get_element_by_id('allCount').attrib['value'])
while True:
payload['limitCount'] += 20
if payload['limitCount'] > query.section_to or payload['limitCount'] > all_count:
break
responses.append(requests.post(BibleSearch.URL, data=payload).text)
if query.to_end_of_section:
query.section_to = all_count
return SearchResult(responses, query)
創世記 = ('創世記', 'old', 'nigen')
出エジプト記 = ('出エジプト記', 'old', 'niexo')
レビ記 = ('レビ記', 'old', 'nilev')
民数記 = ('民数記', 'old', 'ninum')
申命記 = ('申命記', 'old', 'nideu')
ヨシュア記 = ('ヨシュア記', 'old', 'nijos')
士師記 = ('士師記', 'old', 'nijdg')
ルツ記 = ('ルツ記', 'old', 'nirut')
サムエル記上 = ('サムエル記上', 'old', 'ni1sa')
サムエル記下 = ('サムエル記下', 'old', 'ni2sa')
列王記上 = ('列王記上', 'old', 'ni1ki')
列王記下 = ('列王記下', 'old', 'ni2ki')
歴代誌上 = ('歴代誌上', 'old', 'ni1ch')
歴代誌下 = ('歴代誌下', 'old', 'ni2ch')
エズラ記 = ('エズラ記', 'old', 'niezr')
ネヘミヤ記 = ('ネヘミヤ記', 'old', 'nineh')
エステル記 = ('エステル記', 'old', 'niest')
ヨブ記 = ('ヨブ記', 'old', 'nijob')
詩編 = ('詩編', 'old', 'nipsa')
箴言 = ('箴言', 'old', 'nipro')
コヘレトの言葉 = ('コヘレトの言葉', 'old', 'niqoh')
雅歌 = ('雅歌', 'old', 'nison')
イザヤ書 = ('イザヤ書', 'old', 'niisa')
エレミヤ書 = ('エレミヤ書', 'old', 'nijer')
哀歌 = ('哀歌', 'old', 'nilam')
エゼキエル書 = ('エゼキエル書', 'old', 'nieze')
ダニエル書 = ('ダニエル書', 'old', 'nidan')
ホセア書 = ('ホセア書', 'old', 'nihos')
ヨエル書 = ('ヨエル書', 'old', 'nijoe')
アモス書 = ('アモス書', 'old', 'niamo')
オバデヤ書 = ('オバデヤ書', 'old', 'nioba')
ヨナ書 = ('ヨナ書', 'old', 'nijon')
ミカ書 = ('ミカ書', 'old', 'nimic')
ナホム書 = ('ナホム書', 'old', 'ninah')
ハバクク書 = ('ハバクク書', 'old', 'nihab')
ゼファニヤ書 = ('ゼファニヤ書', 'old', 'nizep')
ハガイ書 = ('ハガイ書', 'old', 'nihag')
ゼカリヤ書 = ('ゼカリヤ書', 'old', 'nizec')
マラキ書 = ('マラキ書', 'old', 'nimal')
マタイによる福音書 = ('マタイによる福音書', 'new', 'nimat')
マルコによる福音書 = ('マルコによる福音書', 'new', 'nimar')
ルカによる福音書 = ('ルカによる福音書', 'new', 'niluk')
ヨハネによる福音書 = ('ヨハネによる福音書', 'new', 'nijoh')
使徒言行録 = ('使徒言行録', 'new', 'niact')
ローマの信徒への手紙 = ('ローマの信徒への手紙', 'new', 'nirom')
コリントの信徒への手紙一 = ('コリントの信徒への手紙一', 'new', 'ni1co')
コリントの信徒への手紙二 = ('コリントの信徒への手紙二', 'new', 'ni2co')
ガラテヤの信徒への手紙 = ('ガラテヤの信徒への手紙', 'new', 'nigal')
エフェソの信徒への手紙 = ('エフェソの信徒への手紙', 'new', 'nieph')
フィリピの信徒への手紙 = ('フィリピの信徒への手紙', 'new', 'niphi')
コロサイの信徒への手紙 = ('コロサイの信徒への手紙', 'new', 'nicol')
テサロニケの信徒への手紙一 = ('テサロニケの信徒への手紙一', 'new', 'ni1th')
テサロニケの信徒への手紙二 = ('テサロニケの信徒への手紙二', 'new', 'ni2th')
テモテへの手紙一 = ('テモテへの手紙一', 'new', 'ni1ti')
テモテへの手紙二 = ('テモテへの手紙二', 'new', 'ni2ti')
テトスへの手紙 = ('テトスへの手紙', 'new', 'nitit')
フィレモンへの手紙 = ('フィレモンへの手紙', 'new', 'niphm')
ヘブライ人への手紙 = ('ヘブライ人への手紙', 'new', 'niheb')
ヤコブの手紙 = ('ヤコブの手紙', 'new', 'nijam')
ペトロの手紙一 = ('ペトロの手紙一', 'new', 'ni1pe')
ペトロの手紙二 = ('ペトロの手紙二', 'new', 'ni2pe')
ヨハネの手紙一 = ('ヨハネの手紙一', 'new', 'ni1jo')
ヨハネの手紙二 = ('ヨハネの手紙二', 'new', 'ni2jo')
ヨハネの手紙三 = ('ヨハネの手紙三', 'new', 'ni3jo')
ユダの手紙 = ('ユダの手紙', 'new', 'nijud')
ヨハネの黙示録 = ('ヨハネの黙示録', 'new', 'nirev')
BOOKS = (
('ヨハネによる福音書', ヨハネによる福音書),
('使徒言行録', 使徒言行録),
('ローマの信徒への手紙', ローマの信徒への手紙),
('コリントの信徒への手紙一', コリントの信徒への手紙一),
('コリントの信徒への手紙二', コリントの信徒への手紙二),
('ガラテヤの信徒への手紙', ガラテヤの信徒への手紙),
('エフェソの信徒への手紙', エフェソの信徒への手紙),
('フィリピの信徒への手紙', フィリピの信徒への手紙),
('コロサイの信徒への手紙', コロサイの信徒への手紙),
('テサロニケの信徒への手紙一', テサロニケの信徒への手紙一),
('テサロニケの信徒への手紙二', テサロニケの信徒への手紙二),
('テモテへの手紙一', テモテへの手紙一),
('テモテへの手紙二', テモテへの手紙二),
('テトスへの手紙', テトスへの手紙),
('フィレモンへの手紙', フィレモンへの手紙),
('ヘブライ人への手紙', ヘブライ人への手紙),
('ヤコブの手紙', ヤコブの手紙),
('ペトロの手紙一', ペトロの手紙一),
('ペトロの手紙二', ペトロの手紙二),
('ヨハネの手紙一', ヨハネの手紙一),
('ヨハネの手紙二', ヨハネの手紙二),
('ヨハネの手紙三', ヨハネの手紙三),
('ユダの手紙', ユダの手紙),
('ヨハネの黙示録', ヨハネの黙示録),
('ヨハネ黙示録', ヨハネの黙示録),
('マタイ', マタイによる福音書),
('マルコ', マルコによる福音書),
('ルカ', ルカによる福音書),
('ヨハネ', ヨハネによる福音書),
('使徒', 使徒言行録),
('ローマ', ローマの信徒への手紙),
('第一コリント', コリントの信徒への手紙一),
('第二コリント', コリントの信徒への手紙二),
('ガラテヤ', ガラテヤの信徒への手紙),
('エフェソ', エフェソの信徒への手紙),
('フィリピ', フィリピの信徒への手紙),
('コロサイ', コロサイの信徒への手紙),
('第一テサロニケ', テサロニケの信徒への手紙一),
('第二テサロニケ', テサロニケの信徒への手紙二),
('第一テモテ', テモテへの手紙一),
('第二テモテ', テモテへの手紙二),
('テトス', テトスへの手紙),
('フィレモン', フィレモンへの手紙),
('ヘブライ', ヘブライ人への手紙),
('ヤコブ', ヤコブの手紙),
('第一ペトロ', ペトロの手紙一),
('第二ペトロ', ペトロの手紙二),
('第一ヨハネ', ヨハネの手紙一),
('第二ヨハネ', ヨハネの手紙二),
('第三ヨハネ', ヨハネの手紙三),
('ユダ', ユダの手紙),
('黙示録', ヨハネの黙示録),
('コリント一', コリントの信徒への手紙一),
('コリント二', コリントの信徒への手紙二),
('テサロニケ一', テサロニケの信徒への手紙一),
('テサロニケ二', テサロニケの信徒への手紙二),
('テモテへ一', テモテへの手紙一),
('テモテへ二', テモテへの手紙二),
('ペトロ一', ペトロの手紙一),
('ペトロ二', ペトロの手紙二),
('ヨハネ一', ヨハネの手紙一),
('ヨハネ二', ヨハネの手紙二),
('ヨハネ三', ヨハネの手紙三),
('コリント1', コリントの信徒への手紙一),
('コリント2', コリントの信徒への手紙二),
('テサロニケ1', テサロニケの信徒への手紙一),
('テサロニケ2', テサロニケの信徒への手紙二),
('テモテへ1', テモテへの手紙一),
('テモテへ2', テモテへの手紙二),
('ペトロ1', ペトロの手紙一),
('ペトロ2', ペトロの手紙二),
('ヨハネ1', ヨハネの手紙一),
('ヨハネ2', ヨハネの手紙二),
('ヨハネ3', ヨハネの手紙三),
('創世記', 創世記),
('出エジプト記', 出エジプト記),
('レビ記', レビ記),
('民数記', 民数記),
('申命記', 申命記),
('ヨシュア記', ヨシュア記),
('士師記', 士師記),
('ルツ記', ルツ記),
('サムエル記上', サムエル記上),
('サムエル記下', サムエル記下),
('列王記上', 列王記上),
('列王記下', 列王記下),
('歴代誌上', 歴代誌上),
('歴代誌下', 歴代誌下),
('エズラ記', エズラ記),
('ネヘミヤ記', ネヘミヤ記),
('エステル記', エステル記),
('ヨブ記', ヨブ記),
('詩編', 詩編),
('詩篇', 詩編),
('箴言', 箴言),
('コヘレトの言葉', コヘレトの言葉),
('雅歌', 雅歌),
('イザヤ書', イザヤ書),
('エレミヤ書', エレミヤ書),
('哀歌', 哀歌),
('エゼキエル書', エゼキエル書),
('ダニエル書', ダニエル書),
('ホセア書', ホセア書),
('ヨエル書', ヨエル書),
('アモス書', アモス書),
('オバデヤ書', オバデヤ書),
('ヨナ書', ヨナ書),
('ミカ書', ミカ書),
('ナホム書', ナホム書),
('ハバクク書', ハバクク書),
('ゼファニヤ書', ゼファニヤ書),
('ハガイ書', ハガイ書),
('ゼカリヤ書', ゼカリヤ書),
('マラキ書', マラキ書),
('創世', 創世記),
('出エジプト', 出エジプト記),
('レビ', レビ記),
('民数', 民数記),
('申命', 申命記),
('ヨシュア', ヨシュア記),
('士師', 士師記),
('ルツ', ルツ記),
('サムエル上', サムエル記上),
('サムエル下', サムエル記下),
('サム上', サムエル記上),
('サム下', サムエル記下),
('列王上', 列王記上),
('列王下', 列王記下),
('列上', 列王記上),
('列下', 列王記下),
('歴代上', 歴代誌上),
('歴代下', 歴代誌下),
('歴上', 歴代誌上),
('歴下', 歴代誌下),
('エズラ', エズラ記),
('ネヘミヤ', ネヘミヤ記),
('エステル', エステル記),
('ヨブ', ヨブ記),
('コヘレト', コヘレトの言葉),
('イザヤ', イザヤ書),
('エレミヤ', エレミヤ書),
('エゼキエル', エゼキエル書),
('ダニエル', ダニエル書),
('ホセア', ホセア書),
('ヨエル', ヨエル書),
('アモス', アモス書),
('オバデヤ', オバデヤ書),
('ヨナ', ヨナ書),
('ミカ', ミカ書),
('ナホム', ナホム書),
('ハバクク', ハバクク書),
('ゼファニヤ', ゼファニヤ書),
('ハガイ', ハガイ書),
('ゼカリヤ', ゼカリヤ書),
('マラキ', マラキ書)
)
lxml==3.7.0
requests==2.12.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment