Select Page

Introdução

Muitos projetos de análise de dados, large knowledge, e aprendizado de máquina exigem o scraping de internet sites para coletar os dados com os quais você irá trabalhar. A linguagem de programação Python é largamente utilizada na comunidade de knowledge science, e, portanto, tem um ecossistema de módulos e ferramentas que você pode usar em seus próprios projetos. Neste educational estaremos nos concentrando no módulo Gorgeous 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 internet scraping. Atualmente disponível como Gorgeous Soup four e compatível tanto com Python 2.7 quanto com Python 3, o Gorgeous 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 educational, iremos coletar e analisar uma página internet 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 educational, 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 Gorgeous Soup instalados, o que pode ser conseguido seguindo o nosso educational “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 internet, você deve estar confortável com a estrutura e a marcação de tags HTML.

Entendendo os Dados

Neste educational, iremos trabalhar com dados do web page oficial do National Gallery of Art nos Estados Unidos. O Nationwide Gallery é um museu de arte localizado no Nationwide 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 educational, estava disponível by way of 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 web page ter sido arquivado pelo Web Archive.

O Web Archive é uma biblioteca virtual sem fins lucrativos que fornece acesso livre a websites da web e outras mídias digitais. A organização tira instantâneos de internet sites para preservar a história dos websites, e atualmente, podemos acessar uma versão mais antiga do web page da Nationwide Gallery que estava disponível quando este educational foi escrito pela primeira vez. O Web 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 web page e dados disponíveis.

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

Como estamos fazendo esse projeto para aprender sobre o internet scraping com o Gorgeous Soup, não precisamos extrair muitos dados do web page, 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 general de four 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 Web 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 educational faremos a iteração dessas páginas.

Para começar a se familiarizar com a forma que essa página internet é 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 educational.

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

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

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

nga_z_artists.py


# Importar bibliotecas
import requests
from bs4 import BeautifulSoup

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

Coletando e Analisando uma Página Internet

O próximo passo que precisaremos fazer é coletar a URL da primeira página internet com o Requests. Iremos atribuir a URL da primeira página à variável web 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
web page = requests.get('https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ1.htm')

Nota: Como a URL é longa, o código acima, bem como todo este educational 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 educational é 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 web page.textual content 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


web page = requests.get('https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ1.htm')

# Criar o objeto BeautifulSoup
soup = BeautifulSoup(web page.textual content, '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 Internet

Para este projeto, iremos coletar nomes de artistas e os hyperlinks relevantes disponíveis no web page. 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 internet.

Para fazer isso, no seu navegador internet, 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 merchandise de menu semelhante ao Inspecionar Elemento (Firefox) ou Inspecionar (Chrome).

Após clicar no merchandise de menu relevante Inspecionar, as ferramentas para desenvolvedores internet 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

onde elegance="BodyText". É importante observar isso, para que só procuremos texto nessa seção da página internet. Também notamos que o nome Zabaglia, Niccola está em uma tag de hyperlink, já que o nome faz referência a uma página internet que descreve o artista. Então, vamos querer referenciar a tag para hyperlinks. O nome de cada artista é uma referência a um hyperlink.

Para fazer isso, iremos utilizar os métodos to find() e find_all() do Gorgeous Soup a fim de extrair o texto dos nomes dos artistas do BodyText

.

nga_z_artists.py


import requests
from bs4 import BeautifulSoup


# Coletar e analisar a primeira página
web page = requests.get('https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ1.htm')
soup = BeautifulSoup(web page.textual content, 'html.parser')

# Pegar todo o texto da div BodyText
artist_name_list = soup.to find(class_='BodyText')

# Pegar o texto de todas as instâncias da tag  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 Gorgeous Soup em uma string Unicode bem formatada.

nga_z_artists.py


...
artist_name_list = soup.to 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

Zabaglia, Niccola ... Zao Wou-Ki Zas-Zie Zie-Zor next
page

O que vemos na saída nesse ponto é o texto completo e as tags relativas a todos os nomes de artistas dentro de tags encontradas na tag

na primeira página, bem como algum texto de hyperlink adicional na parte inferior. Como não queremos essa informação further, vamos trabalhar para remover isso na próxima seção.

Removendo Dados Supérfluos

Até agora, conseguimos coletar todos os dados de texto do hyperlink dentro de uma seção

da nossa página internet. No entanto, não queremos ter os hyperlinks inferiores que não fazem referência aos nomes dos artistas. Por isso, vamos trabalhar para remover essa parte.

Para remover os hyperlinks inferiores da página, vamos clicar novamente com o botão direito e Inspecionar o DOM. Veremos que os hyperlinks na parte inferior da seção

estão contidos em uma tabela HTML:

:

Podemos, portanto, usar o Gorgeous 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 hyperlinks inferiores e adicioná-los ao arquivo do programa:

nga_z_artists.py


import requests
from bs4 import BeautifulSoup


web page = requests.get('https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ1.htm')

soup = BeautifulSoup(web page.textual content, 'html.parser')

# Remover hyperlinks inferiores
last_links = soup.to find(class_='AlphaNav')
last_links.decompose()

artist_name_list = soup.to 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

Zabaglia, Niccola Zaccone, Fabian ... Zanotti, Giampietro Zao Wou-Ki

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

Até agora, focamos especificamente os hyperlinks 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 em vez de imprimir toda a tag de hyperlink.

Podemos fazer isso com o .contents do Gorgeous 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 hyperlink 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


web page = requests.get('https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ1.htm')

soup = BeautifulSoup(web page.textual content, 'html.parser')

last_links = soup.to find(class_='AlphaNav')
last_links.decompose()

artist_name_list = soup.to find(class_='BodyText')
artist_name_list_items = artist_name_list.find_all('a')

# Usar .contents para pegar as tags  filhas
for artist_name in artist_name_list_items:
    names = artist_name.contents[0]
    print(names)

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

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 utilizando o método get('href') do Gorgeous Soup.

A partir da saída dos hyperlinks acima, sabemos que a URL inteira não está sendo capturada, então vamos concatenar a string do hyperlink com o início da string da URL (nesse caso https://internet.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]
    hyperlinks = 'https://internet.archive.org' + artist_name.get('href')
    print(names)
    print(hyperlinks)

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

Output

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

Embora estejamos agora recebendo informações do web page, 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: Title and Hyperlink que iremos passar para o método writerow() como uma lista.

f = csv.creator(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 hyperlinks 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


web page = requests.get('https://internet.archive.org/internet/20121007172955/http://www.nga.gov/assortment/anZ1.htm')

soup = BeautifulSoup(web page.textual content, 'html.parser')

last_links = soup.to find(class_='AlphaNav')
last_links.decompose()

# Criar um arquivo para gravar, adicionar linha de cabeçalhos
f = csv.creator(open('z-artist-names.csv', 'w'))
f.writerow(['Name', 'Link'])

artist_name_list = soup.to 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]
    hyperlinks = 'https://internet.archive.org' + artist_name.get('href')


    # Adicionar em uma linha o nome de cada artista e o hyperlink 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ê america para abrí-lo, ele deve ser algo assim:

z-artist-names.csv


Title,Hyperlink
"Zabaglia, Niccola",https://internet.archive.org/internet/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=11630
"Zaccone, Fabian",https://internet.archive.org/internet/20121007172955/http://www.nga.gov/cgi-bin/tsearch?artistid=34202
"Zadkine, Ossip",https://internet.archive.org/internet/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 four páginas desses artistas no general, disponíveis no web page.

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 vary(1, 5):
    url = 'https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/anZ' + str(i) + '.htm'
    pages.append(url)

Anteriormente neste tutorial, observamos que devemos prestar atenção ao número general 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 four 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 four páginas.

Para este web page específico, as URLs começam com a string https://internet.archive.org/internet/20121007172955/https://www.nga.gov/assortment/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 four páginas do general. Practice que, como colocamos o programa authentic no segundo loop for, agora temos o loop authentic como um loop for aninhado contido nele.

Os dois loops for ficarão assim:

pages = []

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

for merchandise in pages:
    web page = requests.get(merchandise)
    soup = BeautifulSoup(web page.textual content, 'html.parser')

    last_links = soup.to find(class_='AlphaNav')
    last_links.decompose()

    artist_name_list = soup.to 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]
        hyperlinks = 'https://internet.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 hyperlinks 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.creator(open('z-artist-names.csv', 'w'))
f.writerow(['Name', 'Link'])

pages = []

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


for merchandise in pages:
    web page = requests.get(merchandise)
    soup = BeautifulSoup(web page.textual content, 'html.parser')

    last_links = soup.to find(class_='AlphaNav')
    last_links.decompose()

    artist_name_list = soup.to 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]
        hyperlinks = 'https://internet.archive.org' + artist_name.get('href')

        f.writerow([names, links])


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

Sendo Cuidadoso

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

Verifique se o web page tem termos de serviço ou termos de uso relacionados ao internet scraping. Além disso, verifique se o web page 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 web page, execute scripts que vasculhem pelos dados localmente, em vez de sobrecarregar os servidores de outra pessoa.

Adicionalmente, é uma boa ideia fazer internet scraping com um cabeçalho que tenha o seu nome e electronic mail para que o web page 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 = {
    'Person-Agent': 'Seu nome, instance.com',
    'From': 'electronic mail@instance.com'
}

url = 'https://instance.com'

web 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 educational usou o Python e o Gorgeous Soup para coletar dados de um web page. 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 websites.

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