Git Product home page Git Product logo

olx-monitor's Introduction

OLX Monitor

OLX Monitor

Estava procurando um produto específico no OLX, e diariamente acessava minhas buscas salvas no aplicativo à procura de uma boa oportunidade. Um dia encontrei uma ótima oportunidade, mas quando entrei em contato com o vendedor já era tarde, ele já estava indo ao encontro do comprador e caso a a venda não desse certo tinham mais 3 pessoas na espera para comprar.

Vi nessa situação uma oportunidade para aprender um pouco sobre scrapping usando o nodejs para tentar não perder uma próxima oportunidade. Espero que você também consiga o mesmo.

Instalação e configuração

Para utilizar esse script você precisa ter o node e o npm devidamente instalados, ter uma conta no Telegram, e idealmente um computador que fique ligado 27/7 para executar o script continuamente. Eu usei um Raspberry Pi 2 que consome pouca energia e já uso para outros fins, mas você pode usar um VPS, ou um sevidor gratuito da Oracle.

Se você já está familiarizado com a API do Telegram e já mexeu bom bots segue um passo-a-passo mais enxuto:

Usando Node

  1. Clonar ou fazer download do repositório git clone https://github.com/carmolim/olx-monitor.git
  2. Acessar a pasta onde os arquivos js se encontram cd src
  3. Instalar as dependências com o comando npm install
  4. Renomear o arquivo example.env para .env e incluir as informações do seu BOT e do seu grupo que irá receber as notificações
  5. Incluir as URLs que você quer que sejam monitoradas no arquivo config.js
  6. Definir qual o intervalo que você quer que as buscas sejam feitas no arquivo config.js
  7. Executar o script usando o comando node index.js
  8. Acompanhar o andamento do script no Terminal
  9. Se correu tudo certo, dois novos arquivos foram criados dentro da pasta data: ads.db que é o banco de dados e o scrapper.log com os logs de execução do script

Usando docker-compose

Se você quiser utiliar o Docker para não ter que instalar o Node e nem as dependências diretamente na sua máquina siga os seguintes passos

  1. Realize os passos 1 a 7 do guia usando Node
  2. Na primeira vez que você for rodar é preciso buildar a imagem rodando o comando docker-compose build
  3. Nas próximas vezes só é necessário rodar o comando docker-compose up

Configuração do Telegram

Para você poder receber as notificações pelo Telegram você precisa ter algumas coisas, um bot que terá um token e um grupo que tenho bot com que você irá criar como participante.

Criar seu bot

Para conseguir o seu token você precisa criar o seu próprio bot. Eu pretendo fazer um tutorial, mas enquanto isso você pode usar esse aqui. O vídeo é longo mas você só precisa assistir até: 3:24. Com esse vídeo você irá conseguir obter o seu token.

Descobrindo seu CHAT ID

Depois de criar o seu bot, crie um grupo e convite o seu bot que você acabou de criar e també um outro bot, o @idbot, ele vai te ajudar a descobrir o CHAT_ID que precisamos para enviar a notificação.

Depois de incluir o no grupo, basta digitar /getgroupid@myidbot e bot irá responder com o ID do chat.

Editando seu ambiênte

Dentro do repositório tem um arquivo chamado example.env, você precisa renomea-lo para apenas .env e preencher as informações que você acabou de pegar.

Variável Exemplo
TELEGRAM_TOKEN Token do seu bot gerado pelo BotFather
TELEGRAM_CHAT_ID ID do seu chat

O que deve ser monitorado?

Eu não sei o que você está procurando no OLX, mas você precisa dizer para o script. A forma mais fácil de fazer isso é entrar no site do OLX, fazer uma busca, colocar os filtros que você acha necessário e copiar o endereço que o OLX vai criar.

Recomendo utilizar filtros bem específicos para não gerar resultados com muitos itens. Como esse script irá varrer todos os resultados encontrados, pode ser possível que não seja possível passar por todos os resultados dentro do intervalo definido, isso pode fazer com que o Olx perceba uma quantidade alta de chamadas do seu IP e faça algum bloqueio. Isso nunca me aconteceu, mas pode acontecer.

Você pode utilizar uma ou mais pesquisas, basta apenas incluir as URLs no arquivo config.js dentro da variável URLs

Exemplos

Apenas uma URL
config.urls = ['https://sp.olx.com.br/sao-paulo-e-regiao/centro/celulares/iphone?cond=1&cond=2&pe=1600&ps=600&q=iphone']
Várias URLs

Para usar várias URLs você só precisa separa-las por vírgula.

config.urls = [
    'https://sp.olx.com.br/sao-paulo-e-regiao/centro/celulares/iphone?cond=1&cond=2&pe=1600&ps=600&q=iphone',
    'https://sp.olx.com.br/sao-paulo-e-regiao/imoveis/venda?bae=2&bas=1&gsp=1&pe=600000&ps=100000&se=6&ss=2',
]

Dica

Quando mais específica sua busca for mais eficiente o script será, se você só buscar por iPhone, no Brasil todo, você vai receber muitas notificações por dia, não vai ser muito legal.

Funcionamento

O funcionamamento do script é simples. Ele percorre um array de URLs copiadas do OLX, que já contém os filtros de preço mínimo, máximo e etc, encontra os anúncios dentro dessa página e inclui os anúncios encontrados em um banco de dados SQLite e também envia uma notificação para um BOT no Telegram.

As entradas salvas no banco de dados são utilizadas posteriormente para detectar alterações nos preços, que também são notificadas através do Telegram.

Considerações

  • Esse script só funciona com a versão brasileira do OLX, nos outros países a interface é diferente e o scrapper não consegue puxar as informações necessárias para funcionar. Porém a adaptação para outros países deve ser consideravalmente fácil de fazer. As alterações deverão ser feitas no arquivo Scraper.js

olx-monitor's People

Contributors

carmolim avatar douglasrolim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

olx-monitor's Issues

Bot roda normal mas não envia a mensagem para o TELEGRAM

Bot está rodando normal sem nenhum erro, acha os anuncios, mas não envia a mensagem para o telegram.

Telegram token e CHAT_ID corretamente configurados

O que poderia ser?

Estou usando a última versão postada no github

image

Testei usando os parâmetros via URL direto no navegador e foi normal:
image

[Feature Request] Monitoria mais limpa/assertiva

Boa noite @carmolim, obrigado mais uma vez pelo excelente projeto.

Recentemente, tive uma ideia para mantermos a monitoria e, consequentemente as notificações, mais assertivas, visto que atualmente o programa pega os anúncios impulsionados que não são originários/oriundos do termo de busca monitorado. Poderia por gentileza remove-los do scraper? Atualmente eu tenho uma solução paliativa mas não estou muito satisfeito.

Geralmente são identificados pela tag a seguir
<span data-ds-component="DS-Badge" role="status" class="olx-badge olx-badge--info" aria-label="Impulsionado" style="color: var(--color-neutral-70); background-color: var(--color-primary-100);">IMPULSIONADO</span>

E costuma aparecer itens que não são exclusivamente os anúncios desejados.

Como contribuir?

Adicionei uma funcionalidade que senti falta: filtro por título.
Não consigo construir a PR. Qual branch é a mais atualizada, acredito que seja a docker, mas a branch main é incompatível com ela, como posso propor essa feature, na branch docker mesmo?

Erro ao executar o node index.js

Fiz todos os passos conforme a descrição, porém, não funcionou.
na hora de rodar o node index.js aparece o seguinte erro como o print abaixo:

image

Instalei o node e fiz o processo pelo npm install tudo certinho,
estou utilizando uma máquina virtual com o Ubuntu

  • Se puder me ajudar, serei muito grato !
  • Esse monitor da OLX é algo fantástico, queria tanto fazer funcionar. Fico no seu aguardo.

Dúvida

Podem me ajudar com o problema?
Segui as notas, e ao executar o comando [ node index.js ] encontrei o seguinte problema:

Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\Teste\Desktop\OLX\olx-monitor\node_modules\sqlite-async\sqlite-async.js from C:\Users\Teste\Desktop\OLX\olx-monitor\index.js not supported.
Instead change the require of sqlite-async.js in C:\Users\Teste\Desktop\OLX\olx-monitor\index.js to a dynamic import() which is available in all CommonJS modules.
at Object. (C:\Users\Teste\Desktop\OLX\olx-monitor\index.js:4:18) {
code: 'ERR_REQUIRE_ESM'
}

Error: SQLITE_CONSTRAINT: NOT NULL constraint failed: ads.searchTerm

Acontece quando eu inicializo o index.js
Segue o arquivo de configuração:

require('dotenv').config()

let config = {}

config.urls = [
    'https://www.olx.com.br/videogames/estado-pe/grande-recife?vgm=18&vgm=17',
    'https://www.olx.com.br/videogames?op=2&vgm=18&vgm=17&opst=2'
]

// this tool can help you create the interval string:
// https://tool.crontap.com/cronjob-debugger

config.interval = '*/5 * * * *' 
config.telegramChatID = process.env.TELEGRAM_CHAT_ID
config.telegramToken = process.env.TELEGRAM_TOKEN
config.logFile = 'scrapper.log'
config.dbFile = 'ads.db'

module.exports = config

O token foi configurado de acordo com o Token entregue pelo @Botfather no formato: 1234567890:AAAAAAAAAAAAAAAAAA
O bot foi adicionado ao grupo, cujo ID foi obtido pelo IDBot no formato: -123456789

Enviando notificação de todos os anúncios encontrados quando adiciono uma nova URL

Atualmente o script verifica se já existe um arquivo de log no diretório, se não tiver um arquivo de log significa, que o script está rodando pela primeira vez, logo ele não envia uma notificação para cada anúncio encontrado.

Mas quando incluo uma nova URL a ser monitorada no arquivo config.js, ao script rodar ele vai verificar se existe o arquivo de log e possivelmente já exista um arquivo, por isso ele envia as notificações para todos os anúncios encontrados.

Soluções possíveis

Criar um log para cada URL encontrada
Dessa forma cada url terá seu próprio log para fazer a verificação, e facilitaria para o usuário acompanhar o progresso de cada URL. Para idenficar cada log poderia ser utilzado algum HASH para gerar um ID único com base na URL passada.

Desvantagem
Criaria vários arquivos log com nomes relativamente grandes pode causa do HASH.

Fazer o controle através do banco de dados
Criar um novo banco de dados para controlar as URLs que estão sendo monitoradas, mantendo um controle de qual delas já foi monitorada.

Desvantagem
Além de impedir que todos os anúncios sejam notificados não trás nenhuma vantagem para o usuário.

Dúvida sobre arquivo .env

Fale amigo, tava revisitando sua aplicação e fiz todos os passos.
porém na hora de ler os parâmetros do BOT não consegui

o erro é esse aqui

image

Serei muito grato se conseguir me ajudar, to precisando muito monitorar os preços da OLX.

Dúvida sobre o filtro das pesquisas

Olá, amigo! Consegui executar o script e até agora tudo bem. O problema é que os vendedores estão adicionando tags irrelevantes nas descrições dos anúncios, incluindo várias coisas que não têm relação com o produto que estão vendendo, o que acaba confundindo os resultados.

Por exemplo, se você tentar filtrar por "iPhone 13", vai acabar recebendo até anúncios de relógios. Quando inspeciono o anúncio para entender o motivo, vejo uma longa lista de tags que o vendedor inseriu na descrição.

Minha dúvida é se existe alguma forma de eu filtrar os resultados de busca para considerar apenas o título do anúncio? Agradeço pela atenção.

Problemas em encontrar novos anúncios

Alguém percebeu se houve uma baixa de notificações após o último commit?

Eu estava utilizando o commit 1af2f03 há algumas semanas e o script estava funcionando bem, encontrando novos anúncios que correspondiam aos meus filtros, e me notificando no Telegram. Eu sou o inimigo do update quando algo está funcionando, então mesmo após a última atualização 6aaa31c, eu permaneci no commit anterior 1af2f03.

Eis que há uma semana atrás, eu estava ocioso e atualizei para o último commit.
O script rodou ok, e continuou me notificando sobre baixa de preços dos anúncios que eu já tinha em DB, mas após alguns dias eu percebi que houve uma baixa nas notificações de novos anúncios, e até pensei: "Devem ser as pessoas que estão vendendo menos esse mês" 😂
Se antes eu recebia umas 3-5 notificações de novos anúncios por dia, após a atualização eu passei alguns dias sem receber nenhuma notificação de novos anúncios, mas apenas notificação de preços caindo (do que já estava em minha DB).

Acontece que hoje, um amigo me mandou um link de um produto que ele sabia que eu estava esperando aparecer, e o produto correspondia ao filtro que eu havia setado na config, então eu pesquisei no DB e vi que o anúncio não estava no DB.

Para fazer um teste, eu copiei o link de busca do produto diretamente da minha config e colei no navegador, para verificar se o anúncio que meu amigo me passou seria listado no site da OLX.
Quando colei o link de pesquisa no navegador, o anúncio que ele havia me passado apareceu como um dos primeiros resultados, então concluí que o script poderia não estar encontrando ou não estar cadastrando os novos anúncios no DB.

Para tentar voltar ao estado de quando estava funcionando, eu voltei ao commit anterior (git reset 1af2f03 --hard), rodei o script novamente, e esse foi o resultado:

10:20:02.330 INFO  Ad 124xxxxx1 added to the database
10:20:02.333 INFO  Ad 124xxxxx8 added to the database
10:20:02.335 INFO  Ad 124xxxxx8 added to the database
10:20:02.576 ERROR SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
{"errno":19,"code":"SQLITE_CONSTRAINT"}
Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
10:20:02.576 INFO  Ad 124xxxxx6 added to the database
10:20:02.579 INFO  Ad 124xxxxx8 added to the database
10:20:02.581 INFO  Ad 124xxxxx1 added to the database
10:20:02.582 INFO  Ad 124xxxxx4 added to the database
10:20:02.584 INFO  Ad 124xxxxx9 added to the database
10:20:02.586 INFO  Ad 124xxxxx5 added to the database
10:20:02.588 INFO  Ad 124xxxxx2 added to the database
10:20:02.590 INFO  Ad 124xxxxx7 added to the database
10:20:02.591 ERROR SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
{"errno":19,"code":"SQLITE_CONSTRAINT"}
Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
10:20:02.602 ERROR SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
{"errno":19,"code":"SQLITE_CONSTRAINT"}
Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: ads.id
10:20:02.603 INFO  Ad 124xxxxx4 added to the database
10:20:02.813 INFO  Ad 124xxxxx3 added to the database
10:20:02.816 INFO  Ad 110xxxxx1 added to the database
10:20:02.848 INFO  Ad 124xxxxx2 added to the database
10:20:02.850 INFO  Ad 124xxxxx9 added to the database
10:20:02.852 INFO  Ad 124xxxxx6 added to the database
10:20:02.854 INFO  Ad 124xxxxx3 added to the database
10:20:02.856 INFO  Ad 124xxxxx2 added to the database
10:20:02.858 INFO  Ad 124xxxxx9 added to the database

(Editei o número dos anúncios com xxxxx).

Quando voltei para o commit antigo (sem deletar a DB) e rodei o script novamente, ele já encontrou diversos novos anúncios que não havia encontrado quando estava no último commit, inclusive o anúncio que meu amigo me mandou o link.
Recebi aproximadamente 20 notificações no Telegram de novos anúncios, acredito que foram os anúncios que eu não recebia enquanto estava no último commit.

Não sei exatamente o que pode ter causado isso, se foi culpa minha, mas apenas reportando para ver se mais alguém teve o mesmo problema.

ERROR Cannot read properties of undefined (reading 'length')

Boa tarde amigo,

Acredito que a OLX passou por uma nova estruturação de dados, poderia por gentileza atualizar o código para que se adeque às novas alterações? Funcionava perfeitamente durante todo o mês, mas hoje está resultando no erro mostrado no print abaixo.

image

Não é mais possível persistir as URLs a partir de hoje

Boa tarde amigo,

Fui executar o script hoje e pela primeira vez ele me retornou diversos erros ao tentar enviar a requisição pra URL especificada, você também está enfrentando esse tipo de erro? Vou informar o log abaixo, bem como o trecho do código responsável por isso.

12:03:53.571 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=41
12:03:53.673 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=42
12:03:53.776 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=43
12:03:53.876 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=44
12:03:53.978 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=45
12:03:54.082 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=46
12:03:54.188 ERROR Could not fetch the url https://www.olx.com.br/brasil?q=funko&o=47

do {
        currentUrl = setUrlParam(url, 'o', page)
        
        try {
            const response  = await axios(currentUrl)
            const html      = response.data;
            const $         = cheerio.load(html)
            nextPage        = await scrapePage($, searchTerm, notify, url)
        } catch (error) {
            log.error('Could not fetch the url ' + currentUrl)
        }

        page++

    } while (nextPage);

Minha URL monitorada:

config.urls = [
    'https://www.olx.com.br/brasil?q=funko'
]

WORKAROUNDS

Já tentei solucionar removendo o database e recriando e mesmo assim o erro persiste.

ERROR Scraping failed

Olá @carmolim!
Desde já muito obrigado por compartilhar esse projeto conosco, tem me ajudado muito!

Estou enfrentando um problema após a exclusão e reinstalação do projeto. Ao listar os anúncios, ocorre este erro. O processo identifica a presença de certos anúncios, mas em seguida, ocorre um erro e o sistema tenta reiniciar a busca, voltando novamente para o mesmo erro

2024-01-04 09:55:25 INFO  Ads found: 2047
2024-01-04 09:55:26 ERROR No adverts found
{}
Error: No adverts found
    at scrapePage (/Users/possomato/Downloads/olx-monitor-main/components/Scraper.js:72:19)
    at scraper (/Users/possomato/Downloads/olx-monitor-main/components/Scraper.js:36:37)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-01-04 09:55:26 ERROR Scraping failed
{}
Error: Scraping failed
    at scrapePage (/Users/possomato/Downloads/olx-monitor-main/components/Scraper.js:113:15)
    at scraper (/Users/possomato/Downloads/olx-monitor-main/components/Scraper.js:36:37)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

ReferenceError: config is not defined

Olá.
Minha primeira vez rodando o script, e tentei utilizar minhas próprias pesquisas em config.js, mas sempre acontece esse mesmo erro de config is not defined.
Dessa última vez, tentei utilizando a mesma URL retirada do exemplo no README, mas o mesmo erro ocorre. Alguma sugestão?

Cópia do erro abaixo

root@proxy:~/olx-monitor# node index.js
/root/olx-monitor/config.js:1
config.urls = ['https://sp.olx.com.br/sao-paulo-e-regiao/centro/celulares/iphone?cond=1&cond=2&pe=1600&ps=600&q=iphone']
^

ReferenceError: config is not defined
    at Object.<anonymous> (/root/olx-monitor/config.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/root/olx-monitor/index.js:1:16)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)

Conteúdo de config.js:

root@proxy:~/olx-monitor# cat config.js
config.urls = ['https://sp.olx.com.br/sao-paulo-e-regiao/centro/celulares/iphone?cond=1&cond=2&pe=1600&ps=600&q=iphone']
root@proxy:~/olx-monitor#

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.