-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcore.py
More file actions
120 lines (89 loc) · 3.21 KB
/
core.py
File metadata and controls
120 lines (89 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from copy import copy
from bs4 import BeautifulSoup
import requests
from re import compile
class BaseError(Exception):
def __init__(self, error_code, error_desc, status_code):
self.error_code = error_code
self.error_desc = error_desc
self.status_code = status_code
def to_dict(self):
return {
'error_code': self.error_code,
'error_desc': self.error_desc,
}
class NifRequiredError(BaseError):
pass
class InvalidNifError(BaseError):
pass
class Voter:
def __init__(self, nif, district, section, table, school, address):
self.nif = nif
self.district = district
self.section = section
self.table = table
self.school = school
self.address = address
def to_dict(self):
return {
'nif': self.nif,
'district': self.district,
'section': self.section,
'table': self.table,
'school': self.school,
'address': self.address,
}
@classmethod
def from_li_items(cls, nif, li_items):
def _extract_number(li):
regex = compile('(\d+)')
text = li.text
res = regex.search(text)
return int(res.group(1).strip()) if res else None
def _extract_string(li):
regex = compile('(.*):(.*)')
text = li.text
res = regex.search(text)
return res.group(2).strip() if res else None
li_district, li_section, li_table, li_school, li_address = li_items
district = _extract_number(li_district)
section = _extract_number(li_section)
table = _extract_string(li_table)
school = _extract_string(li_school)
address = _extract_string(li_address)
return cls(nif, district, section, table, school, address)
class ElectoralCensus:
BASE_URL = 'https://cens.palma.cat'
URL = '{base}/portal/PALMA/cens/cens_principal1.jsp?codResi=1'.format(base=BASE_URL)
DEFAULT_PARAMS = {
'form_name': 'formcenso',
'seccion': 'Consulta.jsp',
}
DEFAULT_HEADERS = {
'Origin': BASE_URL,
'Referer': URL,
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36',
'Accept-Language': 'es-ES,es;q=0.8',
}
@classmethod
def find_by_nif(cls, nif):
if not nif:
raise NifRequiredError('bad_request', 'El camp NIF és obligatori', 400)
soup = cls.get_soup(nif)
if soup.find('table', {'id': 'formcenso-errors'}):
error_desc = 'El NIF {} és invàlid'.format(nif)
raise InvalidNifError('not_found', error_desc, 404)
ul = soup.find('div', {'id': 'mesaInfo'})
li_items = ul.find_all('li')
voter = Voter.from_li_items(nif, li_items)
return voter
@classmethod
def get_soup(cls, nif):
url_params = copy(cls.DEFAULT_PARAMS)
url_params.update({
'nifPersona': nif,
})
response = requests.get(cls.URL, params=url_params, headers=cls.DEFAULT_HEADERS)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
return soup