Skip to content

gusoliveira21/webscraping-instagram

Repository files navigation

Instagram-WebScraping

selenium_logo_large selenium_logo_large

Versions:
Inglês
Português

😏 Objetivo:

Este tutorial visa dar uma visão simplista da biblioteca selenium, para mostrar que com poucos códigos é possível manipular uma página web e para isso, iremos usar o Anaconda como ambiente para desenvolvimento.

O que é o selenium ❓

O Selenium é uma lib que permite definir testes e detectar automaticamente os resultados desses testes em um navegador preferido. Um conjunto de funções do Selenium possibilita criar interações passo a passo com uma página web, simulando um usuário normal do sistema. [1]

💿 Como instalar:

Para instalar o Selenium basta executar o código abaixo que irá baixar os pacotes para o seu ambiente Anaconda:

pip install selenium

📚 Imports necessários:

Espera um determinado processo.

from selenium.webdriver.support.ui import WebDriverWait

Importa as configurações da página web.

from selenium.webdriver.firefox.options import Options

Envia comandos do teclado (enter, f1, f2,...,f12).

from selenium.webdriver.common.keys import Keys

Importa o navegador que será usado.

from selenium.webdriver import Firefox

Importa as configurações do drive.

from selenium import webdriver

Modulo voltado ao tempo (calendário, horas, minutos, segundos...).

import time

Iremos usar este importe para ocultar senha (é opcional).

import getpass 

🛠️ Setando configurações para abrir a página web:

Como iremos aplicar este estudo usando o instagram como base, obviamente iremos usar o link do mesmo no campo url e logo após, iremos guardar as configurações para serem setadas posteriormente.

A variável URL pega o endereço da página.

url = "https://www.instagram.com"

Guardamos na variável OPTION todas as opções disponíveis.

option = Options()

Neste momento, é importante baixar os drives do navegador que iremos usar para que o selenium possa trabalhar e como iremos usar o Firefox para este tutorial vamos baixar o Gekodriver, para mais informações a respeito leia a Documentação.

- Feito isso, para que consigamos visualizar todo o processo acontecendo, é importante setarmos o valor False para o handler.

Setamos False no handless para aparecer o processo na página web.

option.headless = False

Abre a aba do navegador.

driver = webdriver.Firefox(options=option)

Como o instagram é um site responsivo, dependendo do tamanho da tela ele utiliza classes diferentes, para que o trabalho seja mais facilitado iremos setar configurações para o tamanho e posição da página Web.

Definimos o tamanho da tela do navegador.

driver.set_window_size(448,708)

Definimos a posição da janela do navegador.

driver.set_window_position(800,200)

Envia o url do instagram para o driver, que enviará uma ordem para o navegador acessar o site.

driver.get(url)

Até o momento este foi o resultado obtido:

🔒(***) Setando usuário e senha:

Agora precisamos identificar os nomes dos campos Usuário e Senha direto no navegador para que possamos posteriormente setar nossos usuários, senhas e criar um tempo de espera para os mesmos.

Isso pode ser facilmente resolvido apertando F12 para ver o código fonte da página.

Vamos primeiramente definir uma função que fará uma busca pelo elemento "username", para isso usamos find_element_by_name("username"), que procura tags HTML pelo nome:

def esperar_campo(firefox):
  return driver.find_element_by_name("username")

Em seguida, usaremos o WebDriverWait(driver, 5), sendo DRIVER as configurações da página web e escolhemos 5s como o tempo de espera caso a função "espera_campo()" retornar com êxito:

carregando = WebDriverWait(driver, 5).until(esperar_campo)

E por fim, iremos completar os campos usuário e senha:
Para isso, e iremos usar as funções

  • driver.find_element_by_name() -> Encontrar o campo especificado com o nome.
  • clear() -> Apagar qualquer dado que esteja contido no campo.
  • send_keys() -> Envia a string para o campo encontrado.

Ficando do seguinte modo para o campo usuário.

Insere dados do usuário no campo.

name_campo = driver.find_element_by_name("username")
name_campo.clear()
name_campo.send_keys("Coloque aqui o seu usuário")

O mesmo se repete para o campo password.

Insere senha no campo.

senha_campo = driver.find_element_by_name("password")
senha_campo.clear()
senha_campo.send_keys("Coloque aqui a sua senha")

E por fim aperta ENTER para entrar no instagram

senha_campo.send_keys(Keys.ENTER)

Desse modo, conseguimos obter o seguinte resultado:


❗ Retirar notificação:

Com o resultado a cima conseguimos perceber o surgimento de uma janela JavaScript que irá aparecer sempre que o instagram for aberto pela primeira vez na sessão. O Selenium possui métodos para fechar janelas (pode conferir mais aqui), porém, vamos ver como fazer isso usando as funções que usamos até o momento.

Inicialmente, precisamos pegar as referências da janela pois vamos usar xpath, que nada mais é do que um conjunto de regras de sintaxe para definir partes de um documento XML, para seleciona-la e armazenar em variáveis. [2]

Essas são variáveis que vou precisar, elas trazem informações do código da página!

dialog_box = "//div[@class='piCib']"
button_dialog_box = "//button[@class='aOOlW   HoLwm ']"

Após isso, criaremos uma função similar a função esperar_campo(), e ela será chamada de espera_dialog() e irá retornar retornar uma resposta quando a dialog box carregar.

Função para esperar uma resposta, caso a caixa de diálogo ainda não seja encontrada, e espera 5s após ser encontrada.

def espera_dialog(firefox):
  return driver.find_element_by_xpath(dialog_box)

Espera até a função espera_dialog() retornar um resultado, significando que a caixa de diálogo carregou.

esperando_jane_dialog = WebDriverWait(driver, 10).until(espera_dialog)

Um click é dado no botão "Agora não".

driver.find_element_by_xpath(button_dialog_box).click()

👀 Visualizar Story's:

Como já foi visto, o primeito passo é conseguir o endereço do botão de acesso aos storys e logo após, o botão para passar o story.


Em testes, foram encontrados duas classes para os botões que precisamos, class='jZyv1 H-yu6' e @class='OE3OK ' , tais classes mudam de acordo com o tamanho da tela. Sendo assim, pegaremos ambas para trabalhar mesmo não tendo necessidade já que criamos uma tela 448x708 o que significa que poderemos usar somente o @class='OE3OK ' .

Guardo em variáveis o tamanho das telas disponíveis.

window_big = "//button[@class='jZyv1  H-yu6']"
window_little = "//button[@class='OE3OK ']"

O selenium possui um método chamado Click() utilizado, como o próprio nome já diz, para dar Click em um elemento. Iremos utilizar esse método para abrir os storys.

# Procedimento: Aperta para abrir um story
def open_story ():
    try:
     #Tela Reduzida
     driver.find_element_by_xpath(window_little).click()
    except:
     #Tela Maximizada   
     driver.find_element_by_xpath(window_big).click()

Agora, temos um botão que podemos usar para abrir os storys:

Chamamos a função open_story()

open_story()

Agora, por que não criamos uma função para ir passando os storys enquanto a janela de story estiver aberta ? Pode parecer totalmente inútil, mas para algumas pessoas e trabalhos pode vir a ser útil. Para isso, pegamos a referência a página do story para saber quando estamos ou não dentro de um story e do botão de passar visto anteriormente.

Diz se os story's ainda estão abertos.

window_story ="//section[@class='_8XqED  carul']"

É o endereço do botão para passar o story

button_story_pass ="//button[@class='ow3u_']"

Criamos um laço de repetição que recebe diretamente o valor True, para fazer o processo indefinidamente.
É isso que o nosso código está dizendo:

"Enquanto True, enquanto tiver com story aberto tente apertar o botão para passar e espere 2seg, se der erro tente esperar 1.5seg e tente passar o story novamente, se der erro atualize a página web e depois espere 8seg para abrir os storys novamente."

while(True):
    try:
        while(driver.find_element_by_xpath(window_story)):
            driver.find_element_by_xpath(button_story_pass).click()
            time.sleep(2)
    except Exception as e:
        try:
            time.sleep(1.5)
            driver.find_element_by_xpath(button_story_pass).click()
        except Exception as e:
            driver.refresh()
            time.sleep(8)
            open_story()

Este é o resultado do programa em execução:

❤️ Curte automaticamente publicações no instagram:

Esta funcionalidade é contribuição de luisERH.
Para esta funcionalidade nos precisamos compreender um pouco melhor o funcionamento do instagram.

  • Todas as publicações ficam dentro de um flexbox.

  • E cada post fica dentro de um article.

Logo, se faz necessário descrever o caminho que se deve percorrer até chegar no botão que deve ser clicado. Para isso, iremos recorrer a um recurso do navegador e para usa-lo basta selecionar com o botão direito do mouse a linha a qual desejamos conseguir o endereço.

Fazendo isso, conseguiremos o seguinte resultado: Para saber mais sobre Seletores Css clique aqui

article._8Rm4L:nth-child(1) > div:nth-child(3) > section:nth-child(1) > span:nth-child(1) > button:nth-child(1)

Mas desse modo, conseguiremos selecionar somente o primeiro resultado a cada 8 ou 9 elementos e não é o que queremos. Para resolver este impasse, precisamos especificar mais qual elemento queremos selecionar, e neste caso são todos os elementos que não estão curtidos. Podemos observer logo abaixo que um elemento muda dependendo do estado da publicação:

Sendo assim, precisamos inserir esta condição no nosso código, ficando do seguinte modo:

article._8Rm4L:nth-child(1n) > div:nth-child(3) > section:nth-child(1) > span:nth-child(1) > button:nth-child(1) > svg:nth-child(1)[aria-label='Curtir']

Agora, vamos criar uma função chamada curte_publicacoes() com um Try Catch para curtir os elementos encontrados e em caso de alguma excessão, usamos o atributo PASS que significa passar, ou seja, deixa passar a ocorrência.

def curte_publicacoes():
    try:
        driver.find_element_by_css_selector("article._8Rm4L:nth-child(1n) > div:nth-child(3) > section:nth-child(1) > span:nth-child(1) > button:nth-child(1) > svg:nth-child(1)[aria-label='Curtir']").click()
    except Exception as e:
        pass

E por fim, criamos um While com o valor True, para roda-lo indefinidamente, dentro, iremos criar um acumulador chamado de aux (auxiliar), que crescera em 100 a cada volta completa. Usaremos a função de manipulação de Script do selenium (driver.execute_script()) para manipular o scroll roll da página, e para isso usaremos uma função em Script que pode ser chamada assim -> window.scrollTo(Horizontal,Vertical), e logo em seguida, chamaremos a função criada anteriormente, deixando o código do seguinte modo:

#Desde página
aux = 1
while(True):
    aux += 100
    driver.execute_script(f'window.scrollTo(0,{aux})')
    curte_publicacoes()            
  • O resultado final:

🎯 Próximas atualizações:

  • "Quando chegar no limite da página, atualizar página".
  • OBS: O código é bem simples e devido a isso acaba tendo alguns bugs.

🤝 Contribua com este pequeno projeto 💙

  • Faça um fork desse repositório;
  • Cria uma branch com a sua feature: git checkout -b minha-feature;
  • Faça commit das suas alterações: git commit -m 'feat: Minha nova feature';
  • Faça push para a sua branch: git push origin minha-feature.

Depois que o merge da sua pull request for feito, você pode deletar a sua branch.

📝 License

This project is under the MIT license. See the LICENSE for more information.

Made with by gusoliveira21 👋 Get in touch!

☕ Donation

Se este projeto lhe ajudou de alguma forma não esqueça de contribuir para o café desse dev! :)

paypal

About

🤖 Automated jobs on instagram using webscraping!

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published