Python & Beautifulsoup 4 - 无法过滤类?



我正在尝试从此URL中抓取鞋码: http://www.jimmyjazz.com/mens/footwear/jordan-retro-13--atmosphere-grey-/414571-016?color=Grey

我试图做的是只获取可用的尺寸,例如,只获取那些没有变灰的尺寸。

尺寸都包裹在a元素中。可用大小为box类,不可用的尺寸为box piunavailable类。

我尝试过使用 lambda 函数、ifs 和 CSS 选择器 - 似乎都不起作用。我猜这是因为我的代码结构方式。

其结构如下:

if尝试

size = soup2.find('div', attrs={'class': 'psizeoptioncontainer'})
getsize = str([e.get_text() for e in size.findAll('a', attrs={'class': 'box'}) if 'piunavailable' not in e.attrs['class']])

λ尝试

size = soup2.find('div', attrs={'class': 'psizeoptioncontainer'})
getsize = str([e.get_text() for e in size.findAll(lambda tag: tag.name == 'a' and tag.get('class') == ['box piunavailable'])])

CSS 选择器尝试

size = soup2.find('div', attrs={'class': 'psizeoptioncontainer'})
getsize = str([e.get_text() for e in size.findAll('a[class="box"]'))

因此,对于提供的 URL,我希望结果是一个字符串(从列表转换而来),它是所有可用大小的 - 在撰写此问题时,它应该是 -'8', '8.5', '9', '9.5', '10', '10.5', '11', '11.5', '13'

相反,我得到了所有尺寸,'7.5', '8', '8.5', '9', '9.5', '10', '10.5', '11', '11.5', '12', '13'

有人知道如何使其工作(或知道我的问题的优雅解决方案)?提前谢谢你!

你想要一个 css :not 伪类选择器来排除其他类。 使用 bs4 4.7.1.

sizes = [item.text for item in soup.select('.box:not(.piunavailable)')]

全文:

import requests
from bs4 import BeautifulSoup
r = requests.get('http://www.jimmyjazz.com/mens/footwear/jordan-retro-13--atmosphere-grey-/414571-016?color=Grey')  
soup = BeautifulSoup(r.content,'lxml')  
sizes = [item.text for item in soup.select('.box:not(.piunavailable)')]
print(sizes)

您所要求的是获取具有特定类box而不是其他类的a标签。这可以通过将自定义函数作为筛选器传递给find_all来实现。

def my_match_function(elem):
if isinstance(elem,Tag) and elem.name=='a' and ''.join(elem.attrs.get('class',''))=='box':
return True

在这里,''.join(elem.attrs.get('class',''))=='box'确保a标签只有类box,没有其他类。

让我们看看这个在行动

from bs4 import BeautifulSoup,Tag
html="""
<a>This is also not needed.</a>
<div class="box_wrapper">
<a id="itemcode_11398535" class="box piunavailable">7.5</a>
<a href="#" id="itemcode_11398536" class="box">8</a>
<a href="#" id="itemcode_11398537" class="box">8.5</a>
<a href="#" id="itemcode_11398538" class="box">9</a>
<a href="#" id="itemcode_11398539" class="box">9.5</a>
<a href="#" id="itemcode_11398540" class="box">10</a>
<a href="#" id="itemcode_11398541" class="box">10.5</a>
<a href="#" id="itemcode_11398542" class="box">11</a>
<a href="#" id="itemcode_11398543" class="box">11.5</a>
<a id="itemcode_11398544" class="box piunavailable">12</a>
<a href="#" id="itemcode_11398545" class="box">13</a>
</div>
"""
def my_match_function(elem):
if isinstance(elem,Tag) and elem.name=='a' and ''.join(elem.attrs.get('class',''))=='box':
return True
soup=BeautifulSoup(html,'html.parser')
my_list=[x.text for x in soup.find_all(my_match_function)]
print(my_list)

输出:

['8', '8.5', '9', '9.5', '10', '10.5', '11', '11.5', '13']

最新更新