Iterating over list with B Soup

Asked

Viewed 31 times

1

I am trying to realize web Scrapping of a list of episodes of a series with BS. I mounted the structure below:

 #Importando todos os módulos
import bs4
from bs4 import BeautifulSoup

import urllib.request as urllib_request
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

import pandas as pd

#Colocando a URL da página
url = 'https://pt.wikipedia.org/wiki/Lista_de_epis%C3%B3dios_de_How_I_Met_Your_Mother'

#Fazer request do html para o servidor
req = Request(url)
response = urlopen(req)
html = response.read()
#Convertendo html de byte para str
html = html.decode('UTF-8')
type(html)

#Tratando a str
def trata_html(input):
    " ".join(input.split())
    input.replace('> <', '><')
    return input

html = trata_html(html)

#Criando o objeto BS
soup = BeautifulSoup(html)

#Trabalhando com as tags

#Puxando todo o conteúdo de tabelas de informações dos episódios
lista_tabela_episodios = soup.find('table', {'class': 'wikitable plainrowheaders wikiepisodetable'})

#Criando listas de elementos para o dataframe:
dataframe_infos_episodios = []

#Selecionando a lista de elementos do cabeçalho para usar como key dos dicionários
cabecalho_lista_episodios = lista_tabela_episodios.find('tr', style='color:black;text-align:center')
lista_episodios = soup.findAll('tr', class_ = 'vevent')

episodio = {}
i = 0

for linha in lista_episodios:

  # Número do episódio:
  episodio['numero_na_serie'] = lista_episodios[i].find('th', scope="row").getText()

  # Nome do episódio:
  episodio['titulo'] = lista_episodios[i].find('td', class_ = 'summary').getText()

  i += 1
  dataframe_infos_episodios.append(episodio)

As output, I expected a list with the number and title of all episodes of the list 'lista_episodios', through the iteration of each item of the list with 'i'. The problem is that my output is this:

[{'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},
 {'numero_na_serie': '207\n\n208', 'titulo': '"Last Forever"  '},

And so down the list...

Is there a problem with my iterator?

Thank you.

1 answer

2


The problem is that when you append a dictionary you are creating a pointer, not a reference (one can see the answer at that link to understand the difference between pointer and reference). When you update the value of the dictionary you are changing all the values you added in the dataframe, so at the end they all get the value of the final episode. What you can do is put the dictionary statement inside the loop, so every time Python would be allocating a position in different memory, understanding that all the dictionaries you are adding in the data frame are different.

There is another problem in your style code is that you do not need the variable i. The for linha in lista_de_episodios already put in the variable linha the value of lista_episodios[i]. The reformatted code would be:

for linha in lista_episodios:
    episodio = {}
    episodio['numero_na_serie'] = linha.find('th', scope="row").getText()
    episodio['titulo']=linha.find('td', class_ = 'summary').getText()
    dataframe_infos_episodios.append(episodio)
    

Browser other questions tagged

You are not signed in. Login or sign up in order to post.