TransWikia.com

Como remover espaços em branco

Stack Overflow em Português Asked by Frybii on November 7, 2021

Tenho uma lista e preciso remover espaços em branco. Estou usando replace, porém não retira o espaço do início da string após o sinal de menos, apenas do final. Esse espaço não é um caractere?

import time
import pandas as pd
import lxml
import html5lib
from bs4 import BeautifulSoup
from pandas import DataFrame
import numpy as np
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

url = "https://www.sunoresearch.com.br/acoes/itsa4/"

option = Options()
option.headless = True
driver = webdriver.Firefox()

driver.get(url)
time.sleep(10)

driver.find_element_by_xpath('//*[@id="demonstratives"]/div[2]/div[1]/div[1]/ng-select/div').click()
driver.find_element_by_xpath('//*[@id="demonstratives"]/div[2]/div[1]/div[1]/ng-select/div/ul/li[2]').click()
driver.find_element_by_xpath('//*[@id="demonstratives"]/div[2]/div[1]/div[2]/ng-select/div').click()
driver.find_element_by_xpath('//*[@id="demonstratives"]/div[2]/div[1]/div[2]/ng-select/div/ul/li[4]').click()
driver.find_element_by_xpath('//*[@id="demonstratives"]/div[2]/div[2]/div/button[2]').click()
element = driver.find_element_by_xpath('//*[@id="demonstratives"]/div[3]/div[2]')
html_content = element.get_attribute('outerHTML')

soup = BeautifulSoup(html_content, 'html.parser')
table = soup.find(name='table')

df_full = pd.read_html(str(table))[0]
pd.set_option('display.max_columns', None)
df_full= df_full.T.shift(-2,axis=0).T
dm=df_full[['Descrição','1T2020', '4T2019','3T2019','2T2019','1T2019']]
df=pd.DataFrame(dm)
df.loc[:,'1T2020']= df['1T2020'].apply(lambda x: str(x).replace(".",""))
df.loc[:,'1T2020']= df['1T2020'].apply(lambda x: str(x).replace(" ",""))
df.loc[:,'1T2020']= df['1T2020'].apply(lambda x: str(x).replace(",","."))
df.loc[:,'1T2020']= df['1T2020'].apply(lambda x: str(x).replace("M",""))

print(df)

driver.quit()

inserir a descrição da imagem aqui

Esse espaço após o sinal de menos deveria ser removido, não? Como remover?

Originalmente:

inserir a descrição da imagem aqui

One Answer

Se você entrar no site https://www.sunoresearch.com.br/acoes/itsa4 e inspecionar algum desses valores no console do browser, verá que ele usa o  , que corresponde ao no-break space (que não é o mesmo caractere que o espaço):

inserir a descrição da imagem aqui

Basicamente, o Unicode define vários caracteres diferentes para o "espaço em branco", e quando você usa ' ', está se referindo a apenas um deles (e adivinhe, esse não é o no-break space).

Enfim, uma forma de remover o no-break space seria:

df.loc[:,'1T2020']= df['1T2020'].apply(lambda x: str(x).replace('u00a0', ''))

A notação uxxxx usa o valor do code point em hexadecimal, e no caso, usei u00a0, que corresponde ao no-break space (para saber o que é um code point, leia aqui).


Você também poderia diminuir todas essas chamadas de replace usando o módulo re:

import re
def limpar_campo(s):
    return re.sub(r'[u00a0 .M]', '', s).replace(',', '.')

df.loc[:,'1T2020']= df['1T2020'].apply(limpar_campo)

Assim, ao chamar sub, eu troco o no-break space, espaço, ponto ou M por "nada" (o que é o mesmo que removê-los), e depois troco a vírgula por ponto.

Ou, se quiser ser mais "genérico" e remover quaisquer caracteres que correspondam a espaço (inclusive o próprio no-break space), pode usar s:

def limpar_campo(s):
    return re.sub(r'[s.M]', '', s).replace(',', '.')

Lembrando que o atalho s também corresponde a caracteres como o TAB e quebras de linha, além de vários outros.


Se quiser ver os code points de uma string e o respectivo nome do caractere, pode usar ord e o módulo unicodedata:

from unicodedata import name

def mostrar_chars(s):
    for c in s: # imprime o code point em hexadecimal e o nome do caractere
        print(f'{ord(c):04X} {name(c)}')

mostrar_chars('- 3.718,0 M')

No exemplo acima usei uma das strings retornadas pelo site. O resultado foi:

002D HYPHEN-MINUS
00A0 NO-BREAK SPACE
0033 DIGIT THREE
002E FULL STOP
0037 DIGIT SEVEN
0031 DIGIT ONE
0038 DIGIT EIGHT
002C COMMA
0030 DIGIT ZERO
0020 SPACE
004D LATIN CAPITAL LETTER M

Repare que o segundo caractere é o no-break space e o penúltimo é o espaço "tradicional" (por isso somente este era removido ao usar replace(" ", "")).

Answered by hkotsubo on November 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP