{ "info": { "author": "Henrique Bastos", "author_email": "henrique@bastos.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Financial and Insurance Industry", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", "Natural Language :: Portuguese (Brazilian)", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3 :: Only", "Topic :: Office/Business :: Financial :: Accounting", "Topic :: Utilities" ], "description": "Ita\u00fa Scraper\n============\n\nScraper para baixar seus extratos do Ita\u00fa com um comando.\n\nMotiva\u00e7\u00e3o\n---------\n\nAs APIs vieram para ficar, mas a maioria dos bancos ainda n\u00e3o oferecem forma\nf\u00e1cil para seus clientes extra\u00edrem seus pr\u00f3prios dados. Algo t\u00e3o simples\nquanto obter o seu extrato banc\u00e1rio \u00e9 um sofrimento para sistematizar.\n\nPesquisei se existia algo pronto para o Ita\u00fa e encontrei o\n`bankscraper `_ do\n`Kamus `_ que disponibiliza v\u00e1rios scripts\ninteressantes. Infelizmente o do Ita\u00fa n\u00e3o estava mais funcionando,\nmas estudando seu c\u00f3digo encontrei uma boa dica:\n\n O site do Ita\u00fa para computador \u00e9 todo complicado para navegar com muita\n m\u00e1gica em javascript. Mas e o site para disponsitivos m\u00f3veis?\n\nAtivei o `\"mobile mode\" `_\ndo Chrome com o `Postman `_\ne o `Postman Interceptor `_\npara rastrear todas as requisi\u00e7\u00f5es e **bingo**. De fato \u00e9 bem mais simples.\n\nDecidi escrever este artigo para explicar o procedimento, evidenciar as\nbizarrices e quem sabe facilitar a manuten\u00e7\u00e3o futura quando algo mudar.\n\nEste script funciona apenas para contas *Pessoa F\u00edsica*, pois o Ita\u00fa for\u00e7a\nempresas a usarem seu aplicativo no celular n\u00e3o dando acesso ao site m\u00f3vel\npelo navegador.\n\nComo funciona\n~~~~~~~~~~~~~\n\nO c\u00f3digo \u00e9 simples e usa `Python 3 `_ com a biblioteca\n`requests `_ para a navega\u00e7\u00e3o\ne `lxml `_ para a extra\u00e7\u00e3o de dados com\n`xpath `_.\n\nMais do que explicar o c\u00f3digo em si, o importante \u00e9 entender o fluxo de\nnavega\u00e7\u00e3o que ele precisa reproduzir.\n\nO protocolo HTTP \u00e9 *ass\u00edncrono* exigindo que cada requisi\u00e7\u00e3o envie novamente\ntodas as informa\u00e7\u00f5es necess\u00e1rias. No entanto, o site do banco cria uma din\u00e2mica\ncliente-servidor estabelecendo depend\u00eancia entre as requisi\u00e7\u00f5es mudando inclusive\nas urls de navega\u00e7\u00e3o. Por isso todo o processo acontece sequencialmente, cheio de\netapas intermedi\u00e1rias que n\u00e3o seriam necess\u00e1rias em condi\u00e7\u00f5es normais.\n\nUsando o ``requests.Session`` conseguimos reproduzir o efeito de navega\u00e7\u00e3o cont\u00ednua\nentre v\u00e1rias p\u00e1ginas propagando *cookies* e outros *cabe\u00e7alhos*.\n\nA classe ``MobileSession`` implementa os cabe\u00e7alhos para nos fazermos\npassar por um browser de celular.\n\nA classe ``ItauScraper`` usa a ``session`` para realizar o ``login`` e\nconsultar o ``extrato``.\n\nO login\n~~~~~~~\n\nPara fazer o ``login`` no site do banco \u00e9 preciso acessar uma url inicial para\ndescobrirmos a url de login real, que muda de tempos em tempos pelo que eu entendi.\n\nCom a *url de login* correta, agora \u00e9 preciso fazer um novo ``GET`` para obter\ninforma\u00e7\u00f5es que o ASP.NET injeta no formul\u00e1rio de login e ent\u00e3o realizar o POST\nefetuando a autentica\u00e7\u00e3o.\n\nDepois do login feito, somos redirecionados para uma p\u00e1gina com um menu de\nnavega\u00e7\u00e3o. Esta p\u00e1gina n\u00e3o \u00e9 usada no fluxo, mas quando quisermos implementar novas\nfuncionalidades no ``ItauScraper`` \u00e9 nela que deveremos come\u00e7ar.\n\n.. image:: https://raw.githubusercontent.com/henriquebastos/itauscraper/master/docs/itau-login.jpg\n\nO extrato\n~~~~~~~~~\n\nQuando acessamos a *url do extrato*, por padr\u00e3o \u00e9 exibido o extrato dos *\u00faltimos 3 dias*.\nNo fim da p\u00e1gina do extrato tem 4 links para listar os extratos dos per\u00edodos\n7, 15, 30 e 90 dias. Estas urls parecem mudar de tempos em tempos, como a do login,\nent\u00e3o \u00e9 preciso *extrair o link* para *90 dias* e obter o extrato com outro ``GET``.\n\n.. image:: https://raw.githubusercontent.com/henriquebastos/itauscraper/master/docs/itau-extrato.jpg\n\nCom o extrato do maior per\u00edodo:\n\n1. Extra\u00edmos a informa\u00e7\u00e3o do html;\n2. Reconstru\u00edmos a tabela com as colunas: data, descri\u00e7\u00e3o e valor;\n3. Filtramos as linhas de saldo que n\u00e3o correspondem a um lan\u00e7amento;\n4. Convertemos cada *data* para o tipo ``datetime.date``;\n5. Convertemos cada *valor* para o tipo ``Decimal``;\n\nNo final, temos uma *tupla de tuplas* na forma:\n\n.. code-block:: python\n\n ((datetime.date(2017, 1, 1), 'RSHOP-LOJA1', Decimal('-1.99')),\n (datetime.date(2017, 1, 2), 'RSHOP-LOJA2', Decimal('-5.00')),\n (datetime.date(2017, 1, 3), 'TBI 1234567', Decimal('10.00')))\n\nO cart\u00e3o\n~~~~~~~~\n\nQuando acessamos a *url do cart\u00e3o*, s\u00e3o exibidas 3 op\u00e7\u00f5es para listar:\n\n1. a fatura anterior;\n2. a fatura atual;\n3. os lan\u00e7amentos parciais da pr\u00f3xima fatura.\n\nEstas urls parecem mudar de tempos em tempos, ent\u00e3o \u00e9 preciso *extrair o link* para a *fatura atual*\ne realizar um novo ``GET`` para obter o extrato de lan\u00e7amentos.\n\n.. image:: https://raw.githubusercontent.com/henriquebastos/itauscraper/master/docs/itau-cartao.jpg\n\nAl\u00e9m dos lan\u00e7amentos, h\u00e1 na p\u00e1gina um resumo com totais.\n\nCom o extrato do cart\u00e3o:\n\n1. Extra\u00edmos a informa\u00e7\u00e3o do html;\n2. Reconstru\u00edmos o resumo como um *dicion\u00e1rio*.\n3. Reconstru\u00edmos a tabela com as colunas: data, descri\u00e7\u00e3o e valor;\n4. Convertemos cada *data* para o tipo ``datetime.date``;\n5. Convertemos cada *valor* para o tipo ``Decimal``;\n\nNo final, temos um *dicion\u00e1rio* com o sum\u00e1rio da fatura e uma *tupla de tuplas* na forma:\n\n.. code-block:: python\n\n # sum\u00e1rio\n {'Total dos lan\u00e7amentos anteriores': Decimal('4.99'),\n 'Cr\u00e9ditos e pgtos': Decimal('4.99'),\n 'Total nacional': Decimal('1.99'),\n 'Total internacional': Decimal('0.00'),\n 'D\u00f3lar em 06/07/2017': Decimal('9.99'),\n 'Total dos lan\u00e7amentos atuais': Decimal('1.99'),\n 'Pagamento m\u00ednimo': Decimal('0.25')}\n\n # lan\u00e7amentos\n ((datetime.date(2017, 1, 1), 'RSHOP-LOJA1', Decimal('-1.99')),\n (datetime.date(2017, 1, 2), 'RSHOP-LOJA2', Decimal('-5.00')),\n (datetime.date(2017, 1, 3), 'TBI 1234567', Decimal('10.00')))\n\nComo usar\n---------\n\nUse pela linha de comando:\n\n.. code-block:: console\n\n $ itauscraper --extrato --cartao --agencia 1234 --conta 12345 --digito 6 --senha SECRET\n\n\nOu importe direto no seu c\u00f3digo:\n\n.. code-block:: python\n\n from itauscraper import ItauScraper\n\n itau = ItauScraper(agencia='1234', conta='12345', digito='6', senha='SECRET')\n itau.login():\n print(itau.extrato())\n print(itau.cartao())\n # TODO: Divirta-se!\n\nPara conhecer todas as op\u00e7\u00f5es execute:\n\n.. code-block:: console\n\n $ itauscraper -h\n\n\nDevelopment\n-----------\n\n.. code-block:: console\n\n git clone https://github.com/henriquebastos/itauscraper.git\n cd itauscraper\n python -m venv -p python3.6 .venv\n source .venv/bin/activate\n pip install -r requirements.txt\n\n\nLicen\u00e7a\n-------\n\nCopyright (C) 2017 Henrique Bastos.\n\nEste c\u00f3digo \u00e9 distribu\u00eddo nos termos da \"GNU LGPLv3\". Veja o arquivo LICENSE para detalhes.", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/henriquebastos/itauscraper/", "keywords": "scraper,requests,lxml,itau,bank,finance,accounting", "license": "GNU LGPLv3", "maintainer": "", "maintainer_email": "", "name": "itauscraper", "package_url": "https://pypi.org/project/itauscraper/", "platform": "any", "project_url": "https://pypi.org/project/itauscraper/", "project_urls": { "Homepage": "http://github.com/henriquebastos/itauscraper/" }, "release_url": "https://pypi.org/project/itauscraper/1.0/", "requires_dist": null, "requires_python": "", "summary": "Scraper para baixar seus extratos do Ita\u00fa com um comando.", "version": "1.0" }, "last_serial": 3046200, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "bd809baf6172644e4a6a9e6771bb1852", "sha256": "881e9c59aa33f1b7b82c1a41f293f94b35d1ed21ee71d88eb078b253f5bb3996" }, "downloads": -1, "filename": "itauscraper-0.2.tar.gz", "has_sig": false, "md5_digest": "bd809baf6172644e4a6a9e6771bb1852", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22415, "upload_time": "2017-07-22T04:51:44", "url": "https://files.pythonhosted.org/packages/bd/b2/0dd8e516c904f94380aca4c9ead832c14039c10e1aea065778020062df8a/itauscraper-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "4902baf5a68a74933c1fd75059a9784d", "sha256": "e7678a1c8c32e56b642ef81621957d793b17ac73fadb39aac343aa7cbce9ab39" }, "downloads": -1, "filename": "itauscraper-0.3.tar.gz", "has_sig": false, "md5_digest": "4902baf5a68a74933c1fd75059a9784d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23970, "upload_time": "2017-07-23T22:37:24", "url": "https://files.pythonhosted.org/packages/ee/e8/5a8bb78a257b020fc98b821311be5595109488f4ab2b2c0e7981e7f5703f/itauscraper-0.3.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "6926ee543847892faed45f28c3511024", "sha256": "913c45e3d815c51b0493c12ccaeb6c21ae9cb9c7f209ec19a501910b77a2adf1" }, "downloads": -1, "filename": "itauscraper-1.0.tar.gz", "has_sig": false, "md5_digest": "6926ee543847892faed45f28c3511024", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11359, "upload_time": "2017-07-25T01:41:28", "url": "https://files.pythonhosted.org/packages/c6/31/7287fb64a73dfd0d64a91884a3d3e2bf1172942aecebab5a7ad09369aa1e/itauscraper-1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "6926ee543847892faed45f28c3511024", "sha256": "913c45e3d815c51b0493c12ccaeb6c21ae9cb9c7f209ec19a501910b77a2adf1" }, "downloads": -1, "filename": "itauscraper-1.0.tar.gz", "has_sig": false, "md5_digest": "6926ee543847892faed45f28c3511024", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11359, "upload_time": "2017-07-25T01:41:28", "url": "https://files.pythonhosted.org/packages/c6/31/7287fb64a73dfd0d64a91884a3d3e2bf1172942aecebab5a7ad09369aa1e/itauscraper-1.0.tar.gz" } ] }