One place for hosting & domains

      Como Fazer Scraping em Páginas Web com Beautiful Soup and Python 3


      Introdução

      Muitos projetos de análise de dados, big data, e aprendizado de máquina exigem o scraping de websites para coletar os dados com os quais você irá trabalhar. A linguagem de programação Python é largamente utilizada na comunidade de data science, e, portanto, tem um ecossistema de módulos e ferramentas que você pode usar em seus próprios projetos. Neste tutorial estaremos nos concentrando no módulo Beautiful Soup.

      Beautiful Soup, uma alusão à música Mock Turtle’s encontrada no Capítulo 10 de Alice no País das Maravilhas, de Lewis Carroll, é uma biblioteca do Python que permite um retorno rápido em projetos de web scraping. Atualmente disponível como Beautiful Soup 4 e compatível tanto com Python 2.7 quanto com Python 3, o Beautiful Soup cria uma árvore de análise a partir de documentos HTML e XML analisados (incluindo documentos com tags não fechadas ou tag soup e outras marcações malformadas).

      Neste tutorial, iremos coletar e analisar uma página web de forma a pegar dados textuais e gravar as informações que tivermos recolhido em um arquivo CSV.

      Pré-requisitos

      Antes de trabalhar com este tutorial, você deve ter um ambiente de programação Python local ou baseado em servidor configurado em sua máquina.

      Você deve ter os módulos Requests e Beautiful Soup instalados, o que pode ser conseguido seguindo o nosso tutorial “How To Work with Web Data Using Requests and Beautiful Soup with Python 3.” Também seria útil ter familiaridade no trabalho com esses módulos.

      Adicionalmente, uma vez que vamos trabalhar com dados extraídos da web, você deve estar confortável com a estrutura e a marcação de tags HTML.

      Entendendo os Dados

      Neste tutorial, iremos trabalhar com dados do site oficial do National Gallery of Art nos Estados Unidos. O National Gallery é um museu de arte localizado no National Mall em Washington, D.C. Ele possui mais de 120.000 peças datadas desde o Renascimento aos dias atuais feitas por mais de 13.000 artistas.

      Gostaríamos de pesquisar o Índice de Artistas, que, no momento da atualização deste tutorial, estava disponível via Internet Archive’s Wayback Machine na seguinte URL:

      https://web.archive.org/web/20170131230332/https://www.nga.gov/collection/an.shtm

      Nota: A longa URL acima é devido a este site ter sido arquivado pelo Internet Archive.

      O Internet Archive é uma biblioteca digital sem fins lucrativos que fornece acesso livre a sites da internet e outras mídias digitais. A organização tira instantâneos de websites para preservar a história dos sites, e atualmente, podemos acessar uma versão mais antiga do site da National Gallery que estava disponível quando este tutorial foi escrito pela primeira vez. O Internet Archive é uma boa ferramenta para se ter em mente sempre que estiver fazendo qualquer tipo de scraping de dados históricos, incluindo a comparação entre iterações do mesmo site e dados disponíveis.

      Logo abaixo do cabeçalho do Internet Archive, você verá uma página como esta:

      Como estamos fazendo esse projeto para aprender sobre o web scraping com o Beautiful Soup, não precisamos extrair muitos dados do site, por isso, vamos limitar o escopo dos dados do artista que estamos tentando capturar. Vamos, portanto, escolher uma letra — em nosso exemplo escolheremos a letra Z — e veremos uma página como esta:

      Na página acima, vemos que o primeiro artista listado no momento da escrita é Zabaglia, Niccola, o que é uma boa coisa a se notar quando começamos a extrair dados. Começaremos trabalhando com essa primeira página, com a seguinte URL para a letra Z:

      https://web.archive.org/web/20121007172955/http://www.nga.gov/collection/anZ1.htm

      É importante observar, para análise posterior, quantas páginas existem para a letra que você está escolhendo listar, o que você pode descobrir clicando na última página de artistas. Nesse caso, existe um total de 4 páginas, e o último artista listado no momento da escrita é Zykmund, Václav. A última página de artistas com Z tem a seguinte URL:

      https://web.archive.org/web/20121010201041/http://www.nga.gov/collection/anZ4.htm

      Contudo, você também pode acessar a página acima usando a mesma string numérica do Internet Archive da primeira página:

      https://web.archive.org/web/20121007172955/http://www.nga.gov/collection/anZ4.htm

      É importante observar isso, pois mais adiante neste tutorial faremos a iteração dessas páginas.

      Para começar a se familiarizar com a forma que essa página web é configurada, você pode dar uma olhada em seu DOM, que o ajudará a entender como o HTML é estruturado. Para inspecionar o DOM, você pode abrir Ferramentas do Desenvolvedor do seu navegador.

      Importando as Bibliotecas

      Para iniciar nosso projeto de codificação, vamos ativar nosso ambiente de programação. Certifique-se de que você está no diretório onde o seu ambiente de desenvolvimento está localizado, e execute o seguinte comando.

      Com o nosso ambiente de programação ativado, vamos criar um novo arquivo, com o nano por exemplo. Você pode nomear seu arquivo como quiser, vamos chamá-lo de nga_z_artists.py nesse tutorial.

      Nesse arquivo, podemos começar a importar as bibliotecas que iremos utilizar — Requests e Beautiful Soup.

      A biblioteca Requests lhe permite fazer uso do HTTP dentro dos seus programas Python em um formato legível, e o módulo Beautiful Soup é projetado para fazer web scraping rapidamente.

      Vamos importar tanto o Requests quanto o Beautiful Soup com a declaração import. Para o Beautiful Soup iremos importá-lo do bs4, o pacote no qual o Beautiful Soup 4 é encontrado.

      nga_z_artists.py

      
      # Importar bibliotecas
      import requests
      from bs4 import BeautifulSoup
      

      Com os módulos Requests e Beautiful Soup importados, podemos passar a trabalhar para coletar primeiro uma página e analisá-la.

      Coletando e Analisando uma Página Web

      O próximo passo que precisaremos fazer é coletar a URL da primeira página web com o Requests. Iremos atribuir a URL da primeira página à variável page usando o método requests.get().

      nga_z_artists.py

      
      import requests
      from bs4 import BeautifulSoup
      
      
      # Coletar a primeira página da lista de artistas
      page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
      
      

      Nota: Como a URL é longa, o código acima, bem como todo este tutorial não passarão no PEP 8 E501, que sinaliza linhas com mais de 79 caracteres. Você pode querer atribuir a URL a uma variável para tornar o código mais legível nas versões finais. O código neste tutorial é para fins de demonstração e permitirá que você troque URLs mais curtas como parte de seus próprios projetos.

      Agora iremos criar o objeto BeautifulSoup, ou uma árvore de análise. Esse objeto utiliza como argumento o documento page.text do Requests (o conteúdo da resposta do servidor) e então o analisa através do html.parser interno do Python.

      nga_z_artists.py

      
      import requests
      from bs4 import BeautifulSoup
      
      
      page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
      
      # Criar o objeto BeautifulSoup
      soup = BeautifulSoup(page.text, 'html.parser')
      
      

      Com a nossa página coletada, analisada e configurada como um objeto BeautifulSoup, podemos passar para a coleta dos dados que gostaríamos.

      Pegando Texto de uma Página Web

      Para este projeto, iremos coletar nomes de artistas e os links relevantes disponíveis no website. Você pode querer coletar dados diferentes, tais como a nacionalidade dos artistas e datas. Para quaisquer dados que você queira coletar, você precisa descobrir como ele é descrito pelo DOM da página web.

      Para fazer isso, no seu navegador web, clique com o botão direito — ou CTRL + clique no macOS — no nome do primeiro artista, Zabaglia, Niccola. Dentro do menu de contexto que aparece, você deve ver um item de menu semelhante ao Inspecionar Elemento (Firefox) ou Inspecionar (Chrome).

      Após clicar no item de menu relevante Inspecionar, as ferramentas para desenvolvedores web devem aparecer no seu navegador. Queremos procurar pela classe e as tags associadas aos nomes dos artistas nessa lista.

      Veremos primeiro que a tabela de nomes está dentro de tags <div> onde class="BodyText". É importante observar isso, para que só procuremos texto nessa seção da página web. Também notamos que o nome Zabaglia, Niccola está em uma tag de link, já que o nome faz referência a uma página web que descreve o artista. Então, vamos querer referenciar a tag <a> para links. O nome de cada artista é uma referência a um link.

      Para fazer isso, iremos utilizar os métodos find() e find_all() do Beautiful Soup a fim de extrair o texto dos nomes dos artistas do BodyText <div>.

      nga_z_artists.py

      
      import requests
      from bs4 import BeautifulSoup
      
      
      # Coletar e analisar a primeira página
      page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
      soup = BeautifulSoup(page.text, 'html.parser')
      
      # Pegar todo o texto da div BodyText
      artist_name_list = soup.find(class_='BodyText')
      
      # Pegar o texto de todas as instâncias da tag <a> dentro da div BodyText
      artist_name_list_items = artist_name_list.find_all('a')
      
      

      A seguir, na parte inferior do nosso arquivo de programa, criaremos um loop for para iterar todos os nomes de artistas que acabamos de colocar na variável artist_name_list_items.

      Vamos imprimir esses nomes com o método prettify() para transformar a árvore de análise do Beautiful Soup em uma string Unicode bem formatada.

      nga_z_artists.py

      
      ...
      artist_name_list = soup.find(class_='BodyText')
      artist_name_list_items = artist_name_list.find_all('a')
      
      # Criar loop para imprimir todos os nomes de artistas
      for artist_name in artist_name_list_items:
          print(artist_name.prettify())
      
      

      Vamos executar o programa como ele está até agora:

      Assim que fizermos isso, receberemos a seguinte saída:

      Output

      <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=11630"> Zabaglia, Niccola </a> ... <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=3427"> Zao Wou-Ki </a> <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/collection/anZ2.htm"> Zas-Zie </a> <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/collection/anZ3.htm"> Zie-Zor </a> <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/collection/anZ4.htm"> <strong> next <br/> page </strong> </a>

      O que vemos na saída nesse ponto é o texto completo e as tags relativas a todos os nomes de artistas dentro de tags <a> encontradas na tag <div class="BodyText"> na primeira página, bem como algum texto de link adicional na parte inferior. Como não queremos essa informação extra, vamos trabalhar para remover isso na próxima seção.

      Removendo Dados Supérfluos

      Até agora, conseguimos coletar todos os dados de texto do link dentro de uma seção <div> da nossa página web. No entanto, não queremos ter os links inferiores que não fazem referência aos nomes dos artistas. Por isso, vamos trabalhar para remover essa parte.

      Para remover os links inferiores da página, vamos clicar novamente com o botão direito e Inspecionar o DOM. Veremos que os links na parte inferior da seção <div class="BodyText"> estão contidos em uma tabela HTML: <table class="AlphaNav">:

      Podemos, portanto, usar o Beautiful Soup para encontrar a classe AlphaNav e usar o método decompose() para remover uma tag da árvore de análise e depois destruí-la juntamente com seu conteúdo.

      Usaremos a variável last_links para fazer referência a esses links inferiores e adicioná-los ao arquivo do programa:

      nga_z_artists.py

      
      import requests
      from bs4 import BeautifulSoup
      
      
      page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
      
      soup = BeautifulSoup(page.text, 'html.parser')
      
      # Remover links inferiores
      last_links = soup.find(class_='AlphaNav')
      last_links.decompose()
      
      artist_name_list = soup.find(class_='BodyText')
      artist_name_list_items = artist_name_list.find_all('a')
      
      for artist_name in artist_name_list_items:
          print(artist_name.prettify())
      
      

      Agora, quando executarmos o programa com o comando python nga_z_artist.py, receberemos a seguinte saída:

      Output

      <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=11630"> Zabaglia, Niccola </a> <a href="http://www.digitalocean.com/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=34202"> Zaccone, Fabian </a> ... <a href="http://www.digitalocean.com/web/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=11631"> Zanotti, Giampietro </a> <a href="http://www.digitalocean.com/web/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=3427"> Zao Wou-Ki </a>

      Nesse ponto, vemos que a saída não inclui mais os links na parte inferior da página web e agora exibe apenas os links associados aos nomes dos artistas.

      Até agora, focamos especificamente os links com os nomes dos artistas, mas temos os dados de tags extras que realmente não queremos. Vamos remover isso na próxima seção.

      Pegando o Conteúdo de uma Tag

      Para acessar apenas os nomes reais dos artistas, queremos focar no conteúdo das tags <a> em vez de imprimir toda a tag de link.

      Podemos fazer isso com o .contents do Beautiful Soup, que irá retornar a tag filha com um tipo de dados lista do Python.

      Vamos revisar o loop for para que, em vez de imprimir o link inteiro e sua tag, façamos a impressão da lista das filhas (ou seja, os nomes completos dos artistas).

      nga_z_artists.py

      
      import requests
      from bs4 import BeautifulSoup
      
      
      page = requests.get('https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ1.htm')
      
      soup = BeautifulSoup(page.text, 'html.parser')
      
      last_links = soup.find(class_='AlphaNav')
      last_links.decompose()
      
      artist_name_list = soup.find(class_='BodyText')
      artist_name_list_items = artist_name_list.find_all('a')
      
      # Usar .contents para pegar as tags <a> filhas
      for artist_name in artist_name_list_items:
          names = artist_name.contents[0]
          print(names)
      
      

      Note que estamos iterando na lista acima chamando o número do índice de cada item.

      Podemos executar o programa com o comando python para ver a seguinte saída:

      Output

      Zabaglia, Niccola Zaccone, Fabian Zadkine, Ossip ... Zanini-Viola, Giuseppe Zanotti, Giampietro Zao Wou-Ki

      Recebemos de volta uma lista de todos os nomes dos artistas disponíveis na primeira página da letra Z.

      Mas, e se quisermos também capturar as URLs associadas a esses artistas? Podemos extrair URLs encontradas dentro de tags <a> utilizando o método get('href') do Beautiful Soup.

      A partir da saída dos links acima, sabemos que a URL inteira não está sendo capturada, então vamos concatenar a string do link com o início da string da URL (nesse caso https://web.archive.org/).

      Estas linhas também serão adicionadas ao loop for:

      nga_z_artists.py

      
      ...
      for artist_name in artist_name_list_items:
          names = artist_name.contents[0]
          links = 'https://web.archive.org' + artist_name.get('href')
          print(names)
          print(links)
      
      

      Quando executamos o programa acima, receberemos tanto os nomes dos artistas quanto as URLs para os links que nos dizem mais sobre eles:

      Output

      Zabaglia, Niccola https://web.archive.org/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=11630 Zaccone, Fabian https://web.archive.org/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=34202 ... Zanotti, Giampietro https://web.archive.org/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=11631 Zao Wou-Ki https://web.archive.org/web/20121007172955/https://www.nga.gov/cgi-bin/tsearch?artistid=3427

      Embora estejamos agora recebendo informações do site, ele está apenas imprimindo em nossa janela de terminal. Em vez disso, vamos capturar esses dados para podermos usá-los em outro lugar, gravando-os em um arquivo.

      Gravando os Dados em um Arquivo CSV

      Coletar dados que só residem em uma janela de terminal não é muito útil. Arquivos de valores separados por vírgulas (CSV) nos permitem armazenar dados tabulares em texto plano, e é um formato comum para planilhas e bancos de dados. Antes de iniciar esta seção, você deve familiarizar-se com como manipular arquivos de texto sem formatação em Python.

      Primeiro, precisamos importar o módulo interno csv do Python junto com os outros módulos no topo do arquivo de código:

      import csv
      

      Em seguida, vamos criar e abrir um arquivo chamado z-artist-names.csv para que possamos gravar nele (iremos utilizar aqui a variável f para o arquivo), utilizando o modo 'w'. Também vamos escrever os cabeçalhos da primeira linha: Name and Link que iremos passar para o método writerow() como uma lista.

      f = csv.writer(open('z-artist-names.csv', 'w'))
      f.writerow(['Name', 'Link'])
      

      Finalmente, dentro do nosso loop for, vamos escrever cada linha com os names ou nomes dos artistas e seus links associados:

      f.writerow([names, links])
      

      Você pode ver as linhas para cada uma dessas tarefas no arquivo abaixo:

      nga_z_artists.py

      
      import requests
      import csv
      from bs4 import BeautifulSoup
      
      
      page = requests.get('https://web.archive.org/web/20121007172955/http://www.nga.gov/collection/anZ1.htm')
      
      soup = BeautifulSoup(page.text, 'html.parser')
      
      last_links = soup.find(class_='AlphaNav')
      last_links.decompose()
      
      # Criar um arquivo para gravar, adicionar linha de cabeçalhos
      f = csv.writer(open('z-artist-names.csv', 'w'))
      f.writerow(['Name', 'Link'])
      
      artist_name_list = soup.find(class_='BodyText')
      artist_name_list_items = artist_name_list.find_all('a')
      
      for artist_name in artist_name_list_items:
          names = artist_name.contents[0]
          links = 'https://web.archive.org' + artist_name.get('href')
      
      
          # Adicionar em uma linha o nome de cada artista e o link associado
          f.writerow([names, links])
      
      

      Quando você executar o programa agora com o comando python, nenhuma saída será retornada para sua janela de terminal. Em vez disso, um arquivo será criado no diretório em que você está trabalhando, chamado z-artist-names.csv.

      Dependendo do que você usa para abrí-lo, ele deve ser algo assim:

      z-artist-names.csv

      
      Name,Link
      "Zabaglia, Niccola",https://web.archive.org/web/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=11630
      "Zaccone, Fabian",https://web.archive.org/web/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=34202
      "Zadkine, Ossip",https://web.archive.org/web/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=3475w
      ...
      
      

      Ou, ele pode se parecer mais com uma planilha:

      Em ambos os casos, agora você pode usar esse arquivo para trabalhar com os dados de maneiras mais significativas, já que as informações coletadas agora estão armazenadas no disco do seu computador.

      Recuperando Páginas Relacionadas

      Criamos um programa que extrairá dados da primeira página da lista de artistas cujos sobrenomes começam com a letra Z. Porém, existem 4 páginas desses artistas no total, disponíveis no website.

      Para coletar todas essas páginas, podemos executar mais iterações com loops for. Isso revisará a maior parte do código que escrevemos até agora, mas empregará conceitos semelhantes.

      Para começar, vamos inicializar uma lista para manter as páginas:

      pages = []
      

      Vamos preencher essa lista inicializada com o seguinte loop for:

      for i in range(1, 5):
          url = 'https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ' + str(i) + '.htm'
          pages.append(url)
      
      

      Anteriormente neste tutorial, observamos que devemos prestar atenção ao número total de páginas que contêm nomes de artistas começando com a letra Z (ou qualquer letra que estivermos utilizando). Uma vez que existem 4 páginas para a letra Z, construímos o loop foracima com um intervalo de 1 a 5 de modo que ele vai iterar através de cada uma das 4 páginas.

      Para este website específico, as URLs começam com a string https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZe são seguidas com um número de página (que será o inteiro i do loop for que convertemos para uma string) e terminam com .htm. Iremos concatenar estas strings e depois acrescentar o resultado à lista pages.

      Além desse loop, teremos um segundo loop que passará por cada uma das páginas acima. O código nesse loop for será parecido com o código que criamos até agora, já que ele está executando a tarefa que completamos para a primeira página dos artistas com a letra Z para cada um das 4 páginas do total. Observe que, como colocamos o programa original no segundo loop for, agora temos o loop original como um loop for aninhado contido nele.

      Os dois loops for ficarão assim:

      pages = []
      
      for i in range(1, 5):
          url = 'https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ' + str(i) + '.htm'
          pages.append(url)
      
      for item in pages:
          page = requests.get(item)
          soup = BeautifulSoup(page.text, 'html.parser')
      
          last_links = soup.find(class_='AlphaNav')
          last_links.decompose()
      
          artist_name_list = soup.find(class_='BodyText')
          artist_name_list_items = artist_name_list.find_all('a')
      
          for artist_name in artist_name_list_items:
              names = artist_name.contents[0]
              links = 'https://web.archive.org' + artist_name.get('href')
      
              f.writerow([names, links])
      
      

      No código acima, você deve ver que o primeiro loop for está iterando nas páginas e o segundo loop for está extraindo dados de cada uma dessas páginas e, em seguida, adicionando os nomes e links dos artistas, linha por linha, em cada linha de cada página.

      Estes dois loops for estão abaixo das declaraçõs import, da criação e escrita do arquivo CSV (com a linha para a escrita dos cabeçalhos do arquivo), e a inicialização da variável pages (atribuída a uma lista).

      Dentro de um contexto macro do arquivo de programação, o código completo se parece com isto:

      nga_z_artists.py

      
      import requests
      import csv
      from bs4 import BeautifulSoup
      
      
      f = csv.writer(open('z-artist-names.csv', 'w'))
      f.writerow(['Name', 'Link'])
      
      pages = []
      
      for i in range(1, 5):
          url = 'https://web.archive.org/web/20121007172955/https://www.nga.gov/collection/anZ' + str(i) + '.htm'
          pages.append(url)
      
      
      for item in pages:
          page = requests.get(item)
          soup = BeautifulSoup(page.text, 'html.parser')
      
          last_links = soup.find(class_='AlphaNav')
          last_links.decompose()
      
          artist_name_list = soup.find(class_='BodyText')
          artist_name_list_items = artist_name_list.find_all('a')
      
          for artist_name in artist_name_list_items:
              names = artist_name.contents[0]
              links = 'https://web.archive.org' + artist_name.get('href')
      
              f.writerow([names, links])
      
      
      

      Como esse programa está fazendo um trabalho, levará algum tempo para criar o arquivo CSV. Depois de concluído, a saída estará comleta, mostrando os nomes dos artistas e seus links associados de Zabaglia, Niccola até Zykmund, Václav.

      Sendo Cuidadoso

      Ao fazer scraping em páginas web, é importante manter-se cuidadoso com os servidores dos quais você está pegando informações.

      Verifique se o site tem termos de serviço ou termos de uso relacionados ao web scraping. Além disso, verifique se o site tem uma API que permite coletar dados antes de você mesmo fazer scraping.

      Certifique-se de não acessar continuamente os servidores para coletar dados. Depois de coletar o que você precisa de um site, execute scripts que vasculhem pelos dados localmente, em vez de sobrecarregar os servidores de outra pessoa.

      Adicionalmente, é uma boa ideia fazer web scraping com um cabeçalho que tenha o seu nome e e-mail para que o website possa identificá-lo e fazer o acompanhamento caso tenha alguma dúvida. Um exemplo de cabeçalho que você pode usar com a biblioteca Requests do Python é o seguinte:

      import requests
      
      headers = {
          'User-Agent': 'Seu nome, example.com',
          'From': 'email@example.com'
      }
      
      url = 'https://example.com'
      
      page = requests.get(url, headers = headers)
      
      

      A utilização de cabeçalhos com informações identificáveis ​​garante que as pessoas que acessam os logs de um servidor possam entrar em contato com você.

      Conclusão

      Este tutorial usou o Python e o Beautiful Soup para coletar dados de um website. Armazenamos o texto que reunimos em um arquivo CSV.

      Você pode continuar trabalhando neste projeto coletando mais dados e tornando seu arquivo CSV mais robusto. Por exemplo, você pode querer incluir as nacionalidades e os anos de cada artista. Você também pode usar o que aprendeu para coletar dados de outros sites.

      Para continuar aprendendo sobre como extrair informações da web, leia nosso tutorial “How To Crawl A Web Page with Scrapy and Python 3.”



      Source link

      Como Construir um Classificador de Machine Learning em Python com Scikit-learn


      Introdução

      Machine learning ou Aprendizado de máquina é um campo de pesquisa em ciência da computação, inteligência artificial, e estatística. O foco do Machine Learning é treinar algoritmos para aprender padrões e fazer previsões a partir de dados. Machine learning é especialmente valioso porque ele nos leva a utilizar computadores para automatizar o processo de tomada de decisões.

      Você encontrará aplicações de Machine learning em todos os lugares. Netflix e Amazon usam machine learning para fazer novas recomendações de produtos. Bancos usam machine learning para detectar atividades fraudulentas em transações de cartões de crédito, e empresas de assistência à saúde estão começando a usar machine learning para monitorar, avaliar e diagnosticar pacientes.

      Neste tutorial vamos implementar um algoritmo simples de machine learning em Python utilizando Scikit-learn, uma ferramenta de machine learning para Python. Usando um banco de dados de informações sobre tumores de câncer de mama, iremos usar um classificador Naive Bayes (NB) que prevê se um tumor é maligno ou benigno.

      No final deste tutorial, você saberá como construir o seu próprio modelo de machine learning em Python.

      Pré-requisitos

      Para completar este tutorial, você precisará de:

      Passo 1 — Importando o Scikit-learn

      Vamos começar instalando o módulo Python Scikit-learn, um das melhores e mais bem documentadas bibliotecas de machine learning para Python.

      Para começar com nosso projeto de codificação, vamos ativar nosso ambiente de programação Python 3. Certifique-se de estar no diretório onde o seu ambiente está localizado, e execute o seguinte comando:

      Com seu ambiente de programação ativado, verifique se o módulo Scikit-learn já está instalado:

      • python -c "import sklearn"

      Se o sklearn estiver instalado, este comando irá completar sem erros. Se ele não estiver instalado, você verá a seguinte mensagem de erro:

      Output

      Traceback (most recent call last): File "<string>", line 1, in <module> ImportError: No module named 'sklearn'

      A mensagem de erro indica que o módulo sklearn não está instalado, então baixe o biblioteca usando o pip:

      • pip install scikit-learn[alldeps]

      Quando a instalação estiver concluída, inicie o Jupyter Notebook:

      No Jupyter, crie um novo Python Notebook chamado ML Tutorial. Na primeira célula do Notebook, importe o módulo sklearn.

      ML Tutorial

      
      import sklearn
      
      

      Seu notebook deve se parecer com a figura a seguir:

      Agora que temos o sklearn importado em nosso notebook, podemos começar a trabalhar com o dataset para o nosso modelo de machine learning.

      Passo 2 — Importando o Dataset do Scikit-learn

      O dataset com o qual estaremos trabalhando neste tutorial é o Breast Cancer Wisconsin Diagnostic Database. O dataset inclui várias informações sobre tumores de câncer de mama, bem como rótulos de classificação como malignos ou benignos. O dataset tem 569 instâncias, ou dados, sobre 569 tumores e inclui informações sobre 30 atributos, ou características, tais como o raio do tumor, textura, suavidade, e área.

      Utilizando este dataset, construiremos um modelo de machine learning para utilizar as informações sobre tumores para prever se um tumor é maligno ou benigno.

      O Scikit-learn vem instalado com vários datasets que podemos carregar no Python, e o dataset que queremos está incluído. Importe e carregue o dataset:

      ML Tutorial

      
      ...
      
      from sklearn.datasets import load_breast_cancer
      
      # Carregar o dataset
      data = load_breast_cancer()
      
      

      A variável data representa um objeto Python que funciona como um dicionário. As chaves importantes do dicionário a considerar são os nomes dos rótulos de classificação (target_names), os rótulos reais (target), os nomes de atributo/característica (feature_names), e os atributos (data).

      Atributos são uma parte crítica de qualquer classificador. Os atributos capturam características importantes sobre a natureza dos dados. Dado o rótulo que estamos tentando prever (tumor maligno versus benigno), os possíveis atributos úteis incluem o tamanho, raio, e a textura do tumor.

      Crie novas variáveis para cada conjunto importante de informações e atribua os dados:

      ML Tutorial

      
      ...
      
      # Organizar nossos dados
      label_names = data['target_names']
      labels = data['target']
      feature_names = data['feature_names']
      features = data['data']
      
      

      Agora temos listas para cada conjunto de informações. Para entender melhor nosso conjunto de dados, vamos dar uma olhada em nossos dados imprimindo nossos rótulos de classe, o primeiro rótulo da instância de dados, nossos nomes de características, e os valores das características para a primeira instância de dados.

      ML Tutorial

      
      ...
      
      # Olhando para os nossos dados
      print(label_names)
      print(labels[0])
      print(feature_names[0])
      print(features[0])
      
      

      Você verá os seguintes resultados se você executar o código:

      Como mostra a imagem, nossos nomes de classes são malignant and benign (maligno e benigno), que são então mapeados para valores binários de 0 e 1, onde 0 representa tumores malignos e 1 representa tumores benignos. Portanto, nossa primeira instância de dados é um tumor maligno cujo raio médio é 1.79900000e+01.

      Agora que temos nossos dados carregados, podemos trabalhar com eles para construir nosso classificador de machine learning.

      Passo 3 — Organizando Dados em Conjuntos

      Para avaliar o desempenho de um classificador, você deve sempre testar o modelo em dados não visualizados. Portanto, antes da construção de um modelo, divida seus dados em duas partes: um conjunto de treinamento e um conjunto de testes.

      Você usa o conjunto de testes para treinar e avaliar o modelo durante o estágio de desenvolvimento. Então você usa o modelo treinado para fazer previsões no conjunto de testes não visualizado. Essa abordagem lhe dá uma noção do desempenho e robustez do modelo.

      Felizmente, o sklearn tem uma função chamada train_test_split(), que divide seus dados nesses conjuntos. Importe a função e em seguida utilize-a para dividir os dados:

      ML Tutorial

      
      ...
      
      from sklearn.model_selection import train_test_split
      
      # Dividir nossos dados
      train, test, train_labels, test_labels = train_test_split(features,
                                                                labels,
                                                                test_size=0.33,
                                                                random_state=42)
      
      

      A função divide aleatoriamente os dados usando o parâmetro test_size. Neste exemplo, agora temos um conjunto de testes (test) que representa 33% do dataset original. Os dados restantes (train) formam então os dados de treinamento. Também temos os respectivos rótulos para ambas as variáveis train/test, ou seja, train_labels e test_labels.

      Agora podemos passar para o treinamento do nosso primeiro modelo.

      Passo 4 — Construindo e Avaliando o Modelo

      Existem muitos modelos para machine learning, e cada modelo tem seus pontos fortes e fracos. Neste tutorial, vamos nos concentrar em um algoritmo simples que geralmente funciona bem em tarefas de classificação binária, a saber Naive Bayes (NB).

      Primeiro, importe o módulo GaussianNB. Em seguida inicialize o modelo com a função GaussianNB(), depois treine o modelo, ajustando-o aos dados usando gnb.fit():

      ML Tutorial

      
      ...
      
      from sklearn.naive_bayes import GaussianNB
      
      # Inicializar nosso classificador
      gnb = GaussianNB()
      
      # Treinar nosso classificador
      model = gnb.fit(train, train_labels)
      
      

      Depois de treinarmos o modelo, podemos usar o modelo treinado para fazer previsões no nosso conjunto de teste, o que fazemos utilizando a função predict(). A função predict() retorna uma matriz de previsões para cada instância de dados no conjunto de testes. Podemos então, imprimir nossas previsões para ter uma ideia do que o modelo determinou.

      Utilize a função predict() com o conjunto test e imprima os resultados:

      ML Tutorial

      
      ...
      
      # Fazer previsões
      preds = gnb.predict(test)
      print(preds)
      
      

      Execute o código e você verá os seguintes resultados:

      Como você vê na saída do Jupyter Notebook, a função predict() retornou uma matriz de 0s e 1s que representa nossos valores previstos para a classe tumor (maligno vs. benigno).

      Agora que temos nossas previsões, vamos avaliar o desempenho do nosso classificador.

      Passo 5 — Avaliando a Precisão do Modelo

      Usando a matriz de rótulos de classe verdadeira, podemos avaliar a precisão dos valores previstos do nosso modelo comparando as duas matrizes (test_labels vs. preds). Utilizaremos a função accuracy_score() do sklearn para determinar a precisão do nosso classificador de machine learning.

      ML Tutorial

      
      ...
      
      from sklearn.metrics import accuracy_score
      
      # Avaliar a precisão
      print(accuracy_score(test_labels, preds))
      
      

      Você verá os seguintes resultados:

      Como você vê na saída, o classificador NB é 94.15% preciso. Isso significa que 94,15 porcento do tempo o classificador é capaz de fazer a previsão correta se o tumor é maligno ou benigno. Esses resultados sugerem que nosso conjunto de características de 30 atributos são bons indicadores da classe do tumor.

      Você construiu com sucesso seu primeiro classificador de machine learning. Vamos reorganizar o código colocando todas as declarações import no topo do Notebook ou script. A versão final do código deve ser algo assim:

      ML Tutorial

      
      from sklearn.datasets import load_breast_cancer
      from sklearn.model_selection import train_test_split
      from sklearn.naive_bayes import GaussianNB
      from sklearn.metrics import accuracy_score
      
      # Carregar o dataset
      data = load_breast_cancer()
      
      # Organizar nossos dados
      label_names = data['target_names']
      labels = data['target']
      feature_names = data['feature_names']
      features = data['data']
      
      # Olhando para os nossos dados
      print(label_names)
      print('Class label = ', labels[0])
      print(feature_names)
      print(features[0])
      
      # Dividir nossos dados
      train, test, train_labels, test_labels = train_test_split(features,
                                                                labels,
                                                                test_size=0.33,
                                                                random_state=42)
      
      # Inicializar nosso classificador
      gnb = GaussianNB()
      
      # Treinar nosso classificador
      model = gnb.fit(train, train_labels)
      
      # Fazer previsões
      preds = gnb.predict(test)
      print(preds)
      
      # Avaliar a precisão
      print(accuracy_score(test_labels, preds))
      
      

      Agora você pode continuar trabalhando com seu código para ver se consegue fazer com que seu classificador tenha um desempenho ainda melhor. Você pode experimentar com diferentes subconjuntos de características ou mesmo tentar algoritmos completamente diferentes. Confira o website do Scikit-learn para mais ideias sobre machine learning.

      Conclusão

      Neste tutorial, você aprendeu como construir um classificador de machine learning em Python. Agora você pode carregar dados, organizar dados, treinar, prever e avaliar classificadores de machine learning em Python usando o Scikit-learn. Os passos deste tutorial devem ajudá-lo a facilitar o processo de trabalhar com seus próprios dados no Python.

      Traduzido Por Fernando Pimenta



      Source link

      Serviços de Armazenamento de Objetos versus Armazenamento em Blocos


      Introdução

      O armazenamento de dados flexível e escalável é um requisito básico para a maioria dos aplicativos e serviços que estão sendo desenvolvidos com técnicas e ferramentas modernas. Seja armazenando grandes ou pequenas quantidades de imagens, vídeos ou pequenos blocos de texto, os desenvolvedores de aplicativos precisam de uma solução para o armazenamento e a recuperação do conteúdo gerado por usuários, logs, backups e assim por diante.

      Com os deployments complexos atuais, containers, e infraestrutura efêmera, os dias de simplesmente salvar arquivos no disco em um único servidor acabaram. Provedores de nuvem desenvolveram serviços para preencher as necessidades de armazenamento dos deployments de aplicações modernas, e eles se encaixam principalmente em duas categorias: armazenamento de objetos e armazenamento em blocos.

      Vamos dar uma olhada em ambos e discutir as vantagens, desvantagens e casos de uso para cada um.

      O que é o Armazenamento em Blocos

      Os serviços de armazenamento em blocos ou block storage são relativamente simples e familiares. Eles fornecem um dispositivo de armazenamento em blocos tradicional — como um disco rígido — através da rede. Os provedores de nuvem geralmente têm produtos que podem provisionar um dispositivo de armazenamento em blocos de qualquer tamanho e anexá-lo à sua máquina virtual.

      A partir disso, você poderia tratá-lo como um disco normal. Você pode formatá-lo com um sistema de arquivos e armazenar arquivos nele, combinar vários dispositivos em um RAID, ou configurar um banco de dados para gravar diretamente no dispositivo de blocos, evitando completamente a sobrecarga do sistema de arquivos. Além disso, os dispositivos de armazenamento em blocos conectados à rede geralmente têm algumas vantagens exclusivas em relação aos discos rígidos normais:

      • Você pode tirar snapshots ou instantâneos ao vivo de todo o dispositivo para fins de backup
      • Dispositivos de armazenamento em blocos podem ser redimensionados para acomodar as necessidades de crescimento
      • Você pode facilmente desanexar e mover dispositivos de armazenamento em blocos entre as máquinas

      Esta é uma configuração muito flexível que pode ser útil para a maioria dos aplicativos de qualquer tipo. Vamos resumir algumas vantagens e desvantagens da tecnologia.

      Algumas vantagens do armazenamento em blocos são:

      • O Armazenamento em blocos é um paradigma familiar. Pessoas e softwares entendem e suportam arquivos e sistemas de arquivos quase que universalmente
      • Dispositivos de blocos são bem suportados. Toda linguagem de programação pode ler e gravar arquivos facilmente
      • Permissões de sistema de arquivos e controles de acesso são familiares e bem entendidos
      • Os dispositivos de armazenamento em bloco fornecem I/O de baixa latência, sendo então, adequados para uso por bancos de dados.

      As desvantagens do armazenamento em blocos são:

      • O armazenamento em blocos está ligado a um servidor de cada vez
      • Blocos e sistemas de arquivos tem metadados limitados sobre os blobs de informações que eles estão armazenando (data da criação, proprietário, tamanho). Qualquer informação adicional sobre o que você está armazenando tem que ser tratada no nível da aplicação e do banco de dados, o que é uma complexidade adicional para um desenvolvedor se preocupar
      • Você precisa pagar por todo o espaço de armazenamento em blocos que você alocou, mesmo que você não o esteja usando
      • Você só pode acessar o armazenamento em blocos através de um servidor em execução
      • O armazenamento em blocos precisa de mais trabalho e configuração manual se comparado ao armazenamento de objetos (escolha de sistemas de arquivos, permissões, versionamento, backups, etc).

      Devido às suas características de I/O rápida, os serviços de armazenamento em blocos são adequados para armazenar dados em bancos de dados tradicionais. Além disso, muitos aplicativos legados que exigem armazenamento normal do sistema de arquivos precisarão usar um dispositivo de armazenamento em blocos.

      Se o seu provedor de nuvem não oferece um serviço de armazenamento em blocos, você pode executar o seu próprio serviço usando OpenStack Cinder, Ceph, ou o serviço iSCSI integrado disponível em muitos dispositivos NAS.

      O que é o Armazenamento de Objetos

      No mundo moderno da computação em nuvem, o armazenamento de objetos ou object storage é o armazenamento e a recuperação de blobs (grandes objetos binários) não estruturados de dados e metadados utilizando uma API HTTP. Em vez da quebra dos arquivos em blocos para armazená-los em disco usando um sistema de arquivos, lidamos com objetos inteiros armazenados na rede. Esses objetos podem ser um arquivo de imagem, logs, arquivos HTML ou qualquer bloco de bytes auto contido. Eles são não estruturados porque não há um esquema ou formato específico que eles precisem seguir.

      O Armazenamento de Objetos decolou porque simplificou muito a experiência do desenvolvedor. Como a API consiste de solicitações HTTP padrão, bibliotecas são rapidamente desenvolvidas para a maioria das linguagens de programação. O salvamento de um blob de dados tornou-se tão fácil quanto uma solicitação HTTP PUT ao object store. A recuperação de arquivo e metadados é uma solicitação GET normal. Além disso, a maioria dos serviços de armazenamento de objetos também pode servir os arquivos publicamente para seus usuários, eliminando a necessidade de manter um servidor web para hospedar recursos estáticos.

      Além do mais, os serviços de armazenamento de objetos cobram apenas pelo espaço de armazenamento que você usa (alguns também cobram por solicitação HTTP e por largura de banda de transferência). Isso é um benefício para pequenos desenvolvedores, que podem obter armazenamento de classe mundial e hospedagem de recursos a custos que aumentam com o uso.

      Entretanto, o armazenamento de objetos não é a solução ideal para todas as situações. Vamos olhar um resumo dos benefícios e desvantagens.

      Algumas vantagens do armazenamento de objetos são:

      • Uma API HTTP simples, com clientes disponíveis para todos os principais sistemas operacionais e linguagens de programação
      • Uma estrutura de custos na qual que você paga apenas pelo que usa
      • Um serviço interno de publicação de recursos significando um servidor a menos que você precisa gerenciar
      • Alguns provedores armazenamento de objetos oferecem integração com CDN, que armazena seus recursos em cache em todo o mundo para fazer downloads e carregamentos de página mais rápidos para seus usuários
      • O versionamento opcional significa que você pode recuperar versões antigas de objetos para se proteger da sobrescrita acidental de dados
      • Os serviços de armazenamento de objetos podem escalar facilmente de necessidades modestas para casos de uso realmente intensos, sem que o desenvolvedor tenha que lançar mais recursos ou rearquitetar a aplicação para lidar com a carga
      • Usar um serviço de armazenamento de objetos significa que você não precisa manter discos rígidos e matrizes RAID, pois isso é feito pelo provedor de serviços.
      • A capacidade de armazenar trechos de metadados junto com seu blob de dados pode simplificar ainda mais a arquitetura do seu aplicativo

      Algumas desvantagens do armazenamento de objetos são:

      • Você não pode utilizar serviços de armazenamento de objetos para manter um banco de dados tradicional, devido à alta latência desses serviços
      • O armazenamento de objetos não permite que você altere apenas um fragmento de dados, você deve ler e escrever um objeto inteiro de uma só vez. Por exemplo, em um sistema de arquivos, você pode facilmente adicionar uma única linha ao final de um arquivo de log. Em um sistema de armazenamento de objetos, você precisaria recuperar o objeto, adicionar a nova linha e gravar todo o objeto de volta. Isso torna o armazenamento de objetos menos ideal para dados que mudam com muita frequência
      • Sistemas operacionais não podem montar facilmente um armazenamento de objetos como um disco normal. Existem alguns clientes e adaptadores para ajudar nisso, mas em geral, usar e navegar em um armazenamento de objetos não é tão simples quanto folhear diretórios em um navegador de arquivos

      Devido a essas propriedades, o armazenamento de objetos é útil para hospedar recursos estáticos, salvamento de conteúdo criado por usuários tais como imagens e filmes, armazenamento de arquivos de backup, armazenamento de logs, por exemplo.

      Existem algumas soluções de armazenamento de objetos que você pode hospedar, embora você tenha que abrir mão de alguns dos benefícios de uma solução hospedada (como não ter que se preocupar com discos rígidos e problemas de dimensionamento). Você pode experimentar o Minio, um popular servidor de armazenamento de objetos escrito na linguagem Go, o Ceph, ou o OpenStack Swift.

      Conclusão

      A escolha de uma solução de armazenamento pode ser uma decisão complexa para desenvolvedores. Neste artigo discutimos as vantagens e desvantagens tanto dos serviços de armazenamento em blocos quanto dos serviços de armazenamento de objetos. É provável que qualquer aplicativo suficientemente complexo precisará dos dois tipos de armazenamento para atender a todas as suas necessidades.



      Source link