Torne o seu Web Scraper da Python mais inteligente

Yunhan Huang Segue 20 de jun · 6 min ler

Recentemente, comecei a aprender sobre o web scraping com o Python. Até agora, uma coisa que eu acho bastante interessante é como tornar o seu Web scraper “mais inteligente” adicionando mais recursos a ele. Por exemplo, eu queria torná-lo capaz de virar a página e continuar fazendo seu trabalho assim que terminar de copiar todos os dados desejados em sua página atual.

Projeto de exemplo

Eu queria conhecer as relações entre todas as celebridades chinesas. Para obter as informações, eu precisava extrair dados de http://www.1905.com/mdb/relation/list/s0t1p1.html ”, que é um site que consiste em todas as relações de celebridades chinesas.

Relações de celebridades

Observe “s0t1p1“ no final do URL: indica o número da categoria, o tipo de relacionamento (casamento, membro da família, casais, etc.) e o número da página. Portanto, s0t1p1 indica categoria1, tipo de relacionamento1 (casamento) e página1.

Aqui, eu uso o Beautiful Soup em Python para ler meu arquivo HTML e extrair dados dele. Este artigo explica o que é o Beautiful Soup e como podemos usá-lo para facilmente extrair dados da web.

Depois de importar os módulos e pacotes necessários, vamos começar.

Criar um belo objeto de sopa

Depois de ler o HTML usando o urllib , precisamos criar um objeto Beautiful Soup. Passe o html para a função BeautifulSoup (), e o pacote Beautiful Soup irá analisar o html (ele pega o texto html e o analisa em objetos Python).

 html = urlopen (url) 
soup = BeautifulSoup (html, “html.parser”)

Ou, você pode fazer isso de outra maneira, e esse método pode evitar erros quando você faz diretamente html = urlopen(url)

 url_i = "YOUR_URL" referer = url_i user_agent = Cabeçalhos de "YOUR_USER_AGENT" = {'User-Agent': user_agent, 'Referer': referenciador, 'Connection': 'keep-alive'} tente: req = urllib.request.Request ( url = url_i, cabeçalhos = cabeçalhos) response = urlopen (req) html = response.read () # lança exceções, exceto error.HTTPError como e: print (e.reason) soup = BeautifulSoup (html, “html.parser”) 

Extraindo Dados

Depois de obter o objeto Beautiful Soup, podemos usá-lo para extrair os dados que desejamos. Neste projeto de exemplo, usamos o mesmo método que mencionei em meu post anterior, que é o de raspar os dados com base em sua tag e classe. Além dos nomes das celebridades e suas relações, eu também quero seu ID correspondente, que é o href .

Uma única relação entre as celebridades “??” e “?? ?”

Ao construir um loop aninhado, o seu scraper da Web raspa automaticamente todos os dados desejados.

 def relações (sopa): 
k = soup.find_all ('div', classe _ = 'gx_List mt10')
para x em k:
allP = x.find_all ('ul')
por pessoa em allP:
resultado = ""
para el in person.find_all ('li'):
iD = ""
para um em el.find_all ('a', href = True):
p = el.get_text (“|”, strip = True)
iD + = a ['href']
iD + = “|”
res = p + iD
res + = “ n”
resultado + = res
resultado de retorno

A função acima irá gerar os dados na primeira página, algo parecido com isto:

Virando a página

Agora vamos falar sobre virar a página. Muitas vezes, os dados são distribuídos em todos os lugares em um site específico, especialmente quando há várias páginas que consistem no mesmo tipo de dados que você deseja extrair de uma só vez. Assim, um virador de página é necessário ao desenvolver o seu raspador da web.

Para fazê-lo rodar várias vezes, precisamos construir outra função que manterá o controle da página atual, do número da página e se o raspador chegará ao final da lista de páginas. Neste site de exemplo, não podemos descobrir o número total de páginas, por isso não podemos usar um número específico para definir o limite do nosso loop.

1. um contador

Vamos primeiro inicializar um contador, i, para ser zero. Ele controla a página atual e incrementa em 1 em cada iteração.

 # NÃO UM CÓDIGO COMPLETO PARA O ENQUANTO LOOP i = 0 Enquanto ALGUMAS CONDIÇÕES: 

i + = 1
url_i = "http://www.1905.com/mdb/relation/list/" + "s0t1p" + str (i) + ".html" referenciador = url_i user_agent = "SEUS AGENTES DE USUÁRIO" headers = {'User-Agent': user_agent, 'Referer': referenciador, 'Connection': 'keep-alive'} tente: req = urllib.request.Request (url = url_i, cabeçalhos = cabeçalhos) response = urlopen (req) html = response.read () # lança exceções
exceto error.HTTPError como e:
print (e.reason)
soup = BeautifulSoup (html, “html.parser”)

2. A Página

O próximo passo é descobrir o elemento no site que indica a página. Clique com o botão direito do mouse no seu site, escolha “inspecionar” e vá para “elemento”.

(O texto "???" significa "próxima página" em chinês.)

Agora observe esta parte do texto html de perto. Para encontrar as informações da página, precisamos extrair essa tag div inteira

 page = soup.find_all (id = “new_page”) 

Para verificar se o scraper chega ao final da lista de páginas, precisamos verificar se esta linha do texto html existe quando está na página:

 <a href=”/mdb/relation/list/s0t1p2.html”> ??? </a> </ div> 

Por isso podemos construir um loop como este:

 para p na página: 
allp = p.find_all ('a', href = True)
para x em allp:
if x.get_text () == “???”:
print (“Mais páginas à frente, continue!”)
se x ['href'] == “/ mdb / relação / lista / s1t0p” + str (i + 1) + “.html”:
pausa
else:
# MAIS CÓDIGO AQUI

f.write (relações (sopa))
imprimir (relações (sopa))

3. Finalize o loop While

Agora vamos pensar em como finalizar o loop while e certificar-nos de que o scraper da web tenha raspado todas as páginas. Nós não definimos a condição while, então podemos usar o contador para fazer a restrição.

 enquanto i> = 0 : (conteúdo do loop while) ... else: i = -1 

Aqui, eu não sou maior ou igual a 0, o que fará com que o loop while seja interrompido.

4. Coloque tudo junto

Vamos colocar tudo junto em uma função e deixar o Python escrever o resultado em um arquivo de texto chamado “celebrity.txt”

O código completo para a função de viragem de página:

 def pageturning (): 
f = open (“celebrity.txt”, “w +”)
i = 0

enquanto eu> = 0:
i + = 1
url_i = “ http://www.1905.com/mdb/relation/list/ " + "s1t0p” + str (i) + “.html”
referer = url_i
user_agent = 'YOUR_USER_AGENT'
headers = {'User-Agent': user_agent, 'Referer': referenciador, 'Connection': 'keep-alive'}

experimentar:
req = urllib.request.Request (url = url_i, cabeçalhos = cabeçalhos)
resposta = urlopen (req)
html = response.read ()
exceto error.HTTPError como e:
pausa

soup = BeautifulSoup (html, “lxml”)

page = soup.find_all (id = “new_page”)
para p na página:
allp = p.find_all ('a', href = True)

para x em allp:
if x.get_text () == “???”:
print (“Mais páginas à frente, continue!”)
# loop interno termina
se x ['href'] == “/ mdb / relação / lista / s1t0p” + str (i + 1) + “.html”:
quebrar
mais:
i = -1
f.write (relações (sopa))
imprimir (relações (sopa))
print ("Você chegou ao fim")

Retorna

Veja como será o resultado: a versão modificada do nosso Web scraper automaticamente transforma a página quando atinge o final da página e gera 1387 linhas de resultados no total.

Arquivo de texto de resultado “celebrity.txt”

Resumo

Espero que este artigo possa ajudá-lo a estabelecer uma ideia do desenvolvimento de um melhor scraper da Web em Python. Há definitivamente muitas outras maneiras de implementar uma função de virada de página. Se você tem certeza sobre o número total de páginas que você quer raspar, você pode simplesmente colocar o limite como sua condição de loop. No entanto, quando sites diferentes têm números de página diferentes, essa forma de implementação se aplica a casos mais gerais. Contanto que você saiba como acompanhar o número da página e conseguir definir uma restrição enquanto o seu Web scraper coleta dados, você está tudo bem.

Texto original em inglês.