|
1 |
| -import datetime |
2 | 1 | import json
|
3 |
| -from urllib.parse import urljoin, urlencode |
| 2 | +from collections import defaultdict |
| 3 | +from datetime import date, datetime, timedelta |
| 4 | +from urllib.parse import urlencode, urljoin |
4 | 5 |
|
5 | 6 | import scrapy
|
6 | 7 |
|
|
9 | 10 |
|
10 | 11 | class CearaSpider(scrapy.Spider):
|
11 | 12 | name = "CE"
|
| 13 | + start_date = date(2020, 3, 2) |
12 | 14 | base_url = "https://indicadores.integrasus.saude.ce.gov.br/api/coronavirus/"
|
13 |
| - start_date = datetime.date(2020, 3, 2) |
14 | 15 |
|
15 |
| - def make_state_confirmed_request(self, date, callback, meta=None): |
| 16 | + def make_city_request(self, date, meta): |
16 | 17 | data = {
|
17 | 18 | "data": date,
|
18 |
| - "idMunicipio": "", |
19 |
| - "tipo": "Confirmado", |
| 19 | + "tipo": "Confirmado,Óbito", |
20 | 20 | }
|
21 | 21 | url = urljoin(self.base_url, "qtd-por-municipio") + "?" + urlencode(data)
|
22 |
| - return scrapy.Request(url, callback=callback, meta=meta) |
| 22 | + return scrapy.Request(url, callback=self.parse_city, meta=meta) |
23 | 23 |
|
24 |
| - def make_city_deaths_request(self, date, city_id, callback, meta=None): |
| 24 | + def make_state_confirmed_request(self, date, meta): |
25 | 25 | data = {
|
26 | 26 | "data": date,
|
27 |
| - "idMunicipio": city_id, |
28 | 27 | "tipo": "Confirmado",
|
29 | 28 | }
|
| 29 | + url = urljoin(self.base_url, "qtd-por-tipo") + "?" + urlencode(data) |
| 30 | + return scrapy.Request(url, callback=self.parse_state_confirmed, meta=meta) |
| 31 | + |
| 32 | + def make_state_deaths_request(self, date, meta): |
| 33 | + data = { |
| 34 | + "data": date, |
| 35 | + "tipo": "Óbito", |
| 36 | + } |
30 | 37 | url = urljoin(self.base_url, "qtd-obitos") + "?" + urlencode(data)
|
31 |
| - return scrapy.Request(url, callback=callback, meta=meta) |
| 38 | + return scrapy.Request(url, callback=self.parse_state_death, meta=meta) |
32 | 39 |
|
33 | 40 | def start_requests(self):
|
34 |
| - for date in date_utils.date_range(self.start_date, date_utils.today()): |
35 |
| - yield self.make_state_confirmed_request( |
36 |
| - date, |
37 |
| - callback=self.parse_state_confirmed, |
38 |
| - meta={"row": {"date": date}}, |
39 |
| - ) |
| 41 | + filtro_data_url = urljoin(self.base_url, "job") |
| 42 | + yield scrapy.Request(filtro_data_url, self.parse_filter_date) |
| 43 | + |
| 44 | + def parse_filter_date(self, response): |
| 45 | + filter_date = json.loads(response.body) |
| 46 | + date_str = filter_date["time"].split(" ")[0] |
| 47 | + end_date = datetime.strptime(date_str, "%d/%m/%Y").date() |
| 48 | + end_date += timedelta(days=1) |
| 49 | + |
| 50 | + for case_date in date_utils.date_range(self.start_date, end_date): |
| 51 | + meta = {"date": case_date} |
| 52 | + |
| 53 | + yield self.make_city_request(date=case_date, meta=meta) |
| 54 | + yield self.make_state_confirmed_request(date=case_date, meta=meta) |
| 55 | + |
| 56 | + def parse_city(self, response): |
| 57 | + map_city_case = defaultdict(dict) |
| 58 | + cases = json.loads(response.body) |
| 59 | + |
| 60 | + for case in cases: |
| 61 | + municipio = case["municipio"] |
| 62 | + map_city_case[municipio].update(case) |
| 63 | + |
| 64 | + for case in map_city_case.values(): |
| 65 | + municipio = case["municipio"] |
| 66 | + if municipio == "Sem informação": |
| 67 | + municipio = "Importados/Indefinidos" |
| 68 | + |
| 69 | + yield { |
| 70 | + "date": response.meta["date"], |
| 71 | + "state": self.name, |
| 72 | + "city": municipio.title(), |
| 73 | + "place_type": "city", |
| 74 | + "confirmed": case.get("qtdConfirmado") or None, |
| 75 | + "deaths": case.get("qtdObito") or None, |
| 76 | + } |
40 | 77 |
|
41 | 78 | def parse_state_confirmed(self, response):
|
42 |
| - date = response.meta["row"]["date"] |
43 |
| - confirmed_data = json.loads(response.body) |
44 |
| - |
45 |
| - for city_data in confirmed_data: |
46 |
| - assert city_data["tipo"] == "Positivo" |
47 |
| - city = city_data["municipio"] |
48 |
| - if city == "Sem informação": |
49 |
| - city = "Importados/Indefinidos" |
50 |
| - city_id = None |
51 |
| - else: |
52 |
| - city_id = city_data["idMunicipio"] |
53 |
| - confirmed = city_data["quantidade"] |
54 |
| - yield self.make_city_deaths_request( |
55 |
| - date, |
56 |
| - city_id, |
57 |
| - callback=self.parse_city_deaths, |
58 |
| - meta={"row": {"date": date, "city": city, "confirmed": confirmed}}, |
59 |
| - ) |
60 |
| - # TODO: check if all requests made here were received as reponses |
61 |
| - |
62 |
| - def parse_city_deaths(self, response): |
63 |
| - row_data = response.meta["row"] |
64 |
| - row_data["state"] = self.name |
65 |
| - deaths_data = json.loads(response.body) |
66 |
| - |
67 |
| - assert len(deaths_data) == 1 |
68 |
| - assert deaths_data[0]["tipo"] == "Óbito" |
69 |
| - row_data["deaths"] = deaths_data[0]["quantidade"] |
70 |
| - yield row_data |
| 79 | + meta = {"date": response.meta["date"], "confirmed": json.loads(response.body)} |
| 80 | + yield self.make_state_deaths_request(date=response.meta["date"], meta=meta) |
| 81 | + |
| 82 | + def parse_state_death(self, response): |
| 83 | + all_types = json.loads(response.body) + response.meta["confirmed"] |
| 84 | + map_type_qtt = {item["tipo"]: item["quantidade"] for item in all_types} |
| 85 | + |
| 86 | + yield { |
| 87 | + "date": response.meta["date"], |
| 88 | + "state": self.name, |
| 89 | + "city": None, |
| 90 | + "place_type": "state", |
| 91 | + "confirmed": map_type_qtt.get("Positivo"), |
| 92 | + "deaths": map_type_qtt.get("Óbito") or None, |
| 93 | + } |
0 commit comments