Infomoney-spider is a web crawler developed with Scrapy for scraping historical price data of Brazilian Stocks from Infomoney website. Infomoney provides daily price data (OHLCV) and earnings data for more than 700 assets. English readme 🇬🇧/🇺🇸
Infomoney-spider é um web crawler desenvolvido com Scrapy para extração dos dados históricos de preço dos ativos da B3 disponibilizados na página Infomoney. A Infomoney disponibiliza dados de preço diário (OHLCV) e dados de proventos para mais de 700 ativos. Leia-me em português 🇧🇷
Clone o repositório e instale as dependências.
$ git clone https://github.com/renatodvc/infomoney-spider.git
$ pip install -r requirements.txt
Infomoney-spider requer Python 3.6+
Se você pretende usar um banco de dados SQL para armazenar os dados:
-
Preencha o campo
DATABASE_URI
dentro desettings.py
com as informações de conexão com o banco.- O projeto usa a ORM do SQLAlchemy, verifique os DBs suportados.
-
Após preencher o campo
DATABASE_URI
, execute as migrações:
$ alembic upgrade head
Execute no terminal:
$ scrapy crawl infomoney [-a param=value]
Todos os parâmetros são opcionais.
- assets: Código dos ativos na B3, aceita múltiplos ativos separados por virgúla. Se nenhum ativo for informado o spider fará requisições para todos os ativos disponíveis na lista de cotações da Infomoney. Ex:
-a assets=PETR4,PETR3
- start_date: Busca os dados históricos a partir da data informada (utilizar padrão dd/mm/yyyy). Se nenhuma data for informada a requisição será feita para o período máximo disponível (2 anos para ações, FIIs podem ter um período mais longo disponível). Ex:
-a start_date=01/01/2019
- end_date: Busca os dados históricos até a data informada (utilizar padrão dd/mm/yyyy). Se nenhuma data for informada será utilizado o dia da execução. Ex:
-a end_date=01/01/2020
- no_earnings: Se
True
o spider não fará coleta dos dados de proventos (JSCP, dividendos, etc). Se não informado a coleta é realizada automaticamente. Ex:-a no_earnings=True
- no_price: Se
True
o spider não fará coleta dos dados de preço (Abertura, Máxima, Fechamento, etc). Se não informado a coleta é realizada automaticamente. Ex:-a no_price=True
- force: Se
True
o spider atualizará os registros já existentes no banco de dados com as novas informações obtidas. Se não informado registros que já constam no banco de dados serão ignorados. AFETA APENAS BANCO DE DADOS SQL. Ex:-a force=True
Por padrão ambos os pipelines SplitInCSVsPipeline
e StoreInDatabasePipeline
estão ativados, você pode alterar isto comentando suas linhas no arquivo settings.py
.
-
SplitInCSVsPipeline: Os dados extraídos são armazenados em arquivos CSV na pasta
csv_output
. Para alterar o diretório de armazenamento editeFILES_STORAGE_FOLDER
e/ouFILES_STORAGE_PATH
dentro do arquivosettings.py
. Os dados de cada ativo são armazenados em arquivos diferentes, dados de proventos também são separados dos dados de preços. -
StoreInDatabasePipeline: Se nenhuma informação de conexão com o banco de dados for incluída no campo
DATABASE_URI
dosettings.py
, essa pipeline se desativará automaticamente. A pipeline utiliza da ORM do SQLAlchemy, para suportar diferentes opções de banco de dados, veja quais são eles. Quando ativa, os dados de preço e proventos serão armazenados nas tabelasassets_earnings
eassets_prices
respectivamente.
INFO: Earnings data for XXXX returned empty.
: A maioria dos ativos listados não possuem dados de proventos disponíveis.ERROR: No redirect from asset code BLCP11. Page returned 404.
: A página de alguns ativos não redireciona como esperado, é possível que a página exista, mas o link que consta na fonte está quebrado.SQLite Decimals Dialect sqlite+pysqlite does *not* support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.
: Os dados numéricos são armazenados como objetos Decimals, o banco de dados SQLite não suporta esse tipo nativamente, o que pode causar problemas de arredondamento.[SQL: ALTER TABLE assets_prices ALTER COLUMN timestamp DROP NOT NULL]
se estiver usando SQLite e fazendo o upgrade das tabelas. SQLite não suporta essa operação, você pode executar um workaround alterando como a migração é executada. Cheque os comentários aqui.
Em geral, os dados não sofrem alteração e são armazenados integralmente como são disponibilizados pela plataforma da Infomoney. (Datas são convertidas em objetos datetime
e quando armazenados em banco de dados SQL os dados podem sofrer conversões de tipo.)
A estrutura colunar dos dados na fonte seguem os seguintes padrões:
- Histórico de Preço:
Data | Timestamp (POSIX Time) | Abertura | Máxima | Mínima | Fechamento | Volume | Variação
- Histórico de Proventos:
Tipo | Valor | % / Fator | Valor Emissão | Data de Aprovação | Data de Ex-Dividendos¹ | Data de Pagamento
- Incluir testes.
- Permitir operação de incrementar o CSV ao invés de sobrescrever.
Clone the repository and install the dependencies.
$ git clone https://github.com/renatodvc/infomoney-spider.git
$ pip install -r requirements.txt
Infomoney-spider requires Python 3.6+
If you plan to use a SQL database to store the data:
-
Fill in the
DATABASE_URI
field withinsettings.py
with your DB connection information.- The project uses SQLAlchemy ORM, check the supported DBs.
-
After filling in the
DATABASE_URI
field, execute the migrations:
$ alembic upgrade head
Run in terminal:
$ scrapy crawl infomoney [-a param=value]
All parameters are optional.
- assets: Assets code in B3 (Brazillian stock exchange), accepts multiple assets separated by a comma. If no asset is informed, the spider will make requests for all assets available in the Infomoney's asset list. Ex:
-a assets=PETR4,PETR3
- start_date: Search the historical data starting from the informed date (use dd/mm/yyyy format). If no date is given, the request will be made for the maximum available period (2 years for stocks, REITs may have longer period available). Ex:
-a start_date=01/01/2019
- end_date: Search historical data up to the given date (use dd/mm/yyyy format). If no date is given, the current day will be used. Ex:
-a end_date=01/01/2020
- no_earnings: If
True
the spider will not collect the earnings data. If not informed, scraping is performed automatically. Ex:-a no_earnings=True
- no_price: If
True
the spider will not collect the price data (Open, High, Close ...). If not informed, scraping is performed automatically. Ex:-a no_price=True
- force: If
True
the spider will update the existing records in the database with the most recent information obtained. If not informed, records that already exist in the database will be ignored. AFFECTS ONLY SQL DATABASE. Ex:-a force=True
By default, both the SplitInCSVsPipeline
and StoreInDatabasePipeline
pipelines are enabled, you can change this by commenting out their lines in the settings.py
file.
-
SplitInCSVsPipeline: The extracted data is stored in CSV files in the
csv_output
folder. To change the storage directory, editFILES_STORAGE_FOLDER
and/orFILES_STORAGE_PATH
inside thesettings.py
file. The data for each asset is stored in a different file, earnings data are also separated from the price data. -
StoreInDatabasePipeline: If no database connection information is included in the
DATABASE_URI
field ofsettings.py
, this pipeline will be disabled automatically. The pipeline uses the SQLAlchemy ORM, to support multiple database options, see what they are. When activated, the price and earnings data will be stored in theassets_earnings
andassets_prices
tables respectively.
INFO: Earnings data for XXXX returned empty.
: Most of the listed assets do not have earnings data available.ERROR: No redirect from asset code BLCP11. Page returned 404.
: Some asset pages doesn't redirect as expected, it is possible that the page exists, but the link in the source page is broken.SQLite Decimals Dialect sqlite+pysqlite does *not* support Decimal objects natively, and SQLAlchemy must convert from floating point - rounding errors and other issues may occur. Please consider storing Decimal numbers as strings or integers on this platform for lossless storage.
: Numerical data is stored as Decimal objects, the SQLite database does not support this type natively, which can cause rounding errors and other issues.[SQL: ALTER TABLE assets_prices ALTER COLUMN timestamp DROP NOT NULL]
when using SQLite and upgrading the tables. SQLite doesn't support this operation, you can work around it by changing how the migration is performed. Check the comments here.
In general, the data is not altered by the spider and is stored in its entirety as provided by the Infomoney platform. (Dates are converted into datetime
objects and when storing data in SQL databases they may have their types converted.)
The columnar structure of the data at the source follows these patterns:
- Price data:
Date | Timestamp (POSIX Time) | Open | High | Low | Close | Volume | Variation
- Earnings data:
Type | Value | % / Factor | Emission Value | Approval Date | Date of Record¹ | Date of Payment
¹: Ex-dividend date.
- Write tests.
- Allow for append operations in the CSV instead of overwriting.