Estou tendo problemas para analisar elementos HTML com o atributo "class" usando Beautifulsoup. O código fica assim
soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
if (div["class"] == "stylelistrow"):
print div
Eu recebo um erro na mesma linha "depois" do script terminar.
File "./beautifulcoding.py", line 130, in getlanguage
if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
return self._getAttrMap()[key]
KeyError: 'class'
Como faço para me livrar desse erro?
<.. class="stylelistrow">
corresponde, mas não<.. class="stylelistrow button">
.class_
que funciona corretamente.A partir da documentação:
No Beautiful Soup 4.1.2, você pode pesquisar por classe CSS usando o argumento de palavra-chave
class_
:Qual nesse caso seria:
Também funcionaria para:
fonte
soup.find_all("a", ["stylelistrowone", "stylelistrow"])
é mais seguro se você não tiver muitas classes.soup.findAll("a", {'class':['stylelistrowone', 'stylelistrow']})
.Atualização: 2016 Na versão mais recente do beautifulsoup, o método 'findAll' foi renomeado para 'find_all'. Link para documentação oficial
Portanto, a resposta será
fonte
Específico para BeautifulSoup 3:
Encontrará todos estes:
fonte
lambda x: 'stylelistrow' in x.split()
é simples e bonitoUma maneira direta seria:
Certifique-se de pegar a caixa de findAll , não é tudo
fonte
<.. class="stylelistrow">
corresponde, mas não<.. class="stylelistrow button">
.Você pode encontrar facilmente por uma classe, mas se quiser encontrar pela interseção de duas classes, é um pouco mais difícil,
A partir da documentação (ênfase adicionada):
Para ficar claro, isso seleciona apenas as tags p que são de strikeout e de classe corporal.
Para encontrar a interseção de qualquer um em um conjunto de classes (não a interseção, mas a união), você pode dar uma lista ao
class_
argumento da palavra - chave (a partir de 4.1.2):Observe também que findAll foi renomeado do camelCase para o mais Pythonic
find_all
.fonte
Seletores CSS
primeira partida de classe única
lista de correspondências
classe composta (ou seja, E outra classe)
Os espaços nos nomes das classes compostas, por exemplo,
class = stylelistrow otherclassname
são substituídos por ".". Você pode continuar adicionando classes.lista de classes (OU - corresponde à que estiver presente
bs4 4.7.1 +
Classe específica que
innerText
contém uma sequênciaClasse específica que possui um determinado elemento filho, por exemplo,
a
tagfonte
A partir do BeautifulSoup 4+,
Se você tiver um único nome de classe, basta passar o nome da classe como parâmetro como:
Ou, se você tiver mais de um nome de classe, basta passar a lista de nomes de classe como parâmetro como:
fonte
Tente verificar se a div tem um atributo de classe primeiro, assim:
fonte
Isso funciona para eu acessar o atributo de classe (no beautifulsoup 4, ao contrário do que diz a documentação). O KeyError vem uma lista retornada, não um dicionário.
fonte
o seguinte funcionou para mim
fonte
Isso funcionou para mim:
fonte
Como alternativa, podemos usar o lxml, ele suporta xpath e muito rápido!
fonte
Isso deve funcionar:
fonte
Outras respostas não funcionaram para mim.
Em outras respostas, ele
findAll
está sendo usado no próprio objeto de sopa, mas eu precisava de uma maneira de encontrar uma busca pelo nome da classe em objetos dentro de um elemento específico extraído do objeto que obtive depois de fazerfindAll
.Se você estiver tentando fazer uma pesquisa dentro de elementos HTML aninhados para obter objetos pelo nome da classe, tente abaixo -
Pontos a serem observados:
Não estou definindo explicitamente a pesquisa para estar no atributo 'class'
findAll("li", {"class": "song_item"})
, pois é o único atributo que estou pesquisando e, por padrão, procurará o atributo class se você não informar exclusivamente em qual atributo deseja encontrar.Quando você faz um
findAll
oufind
, o objeto resultante é da classebs4.element.ResultSet
que é uma subclasse delist
. Você pode utilizar todos os métodos deResultSet
, dentro de qualquer número de elementos aninhados (desde que sejam do tipoResultSet
) para localizar ou encontrar todos.Minha versão BS4 - 4.9.1, versão Python - 3.8.1
fonte
O seguinte deve funcionar
substitua 'totalcount' pelo nome da sua classe e 'span' pela tag que você está procurando. Além disso, se sua classe contiver vários nomes com espaço, basta escolher um e usar.
PS Este encontra o primeiro elemento com determinados critérios. Se você deseja encontrar todos os elementos, substitua 'find' por 'find_all'.
fonte