下面是一个url示例。
url = 'https://rapaxray.com'
# logo
html_content = requests.get(url, headers=headers).text
soup = BeautifulSoup(html_content, "lxml")
images_found = soup.findAll('img', {'src' : re.compile(r'(jpe?g)|(png)|(svg)$')})
images_found
首先,我将元素列表缩小到标签中包含jpg、png或svg的元素。在这种情况下,我只得到3个元素。然后我想过滤那些元素,只显示那些在ANY属性中有关键字"徽标"的元素。
我在这个例子中寻找的元素是这样的:
'img alt="Radiology Associates,P.A;class=";附件全尺寸全阿斯特拉标志svg";负载=";懒惰;src=";https://rapaxray.com/wp-content/uploads/2019/09/RAPA100.svg"/'
我想从所有元素中筛选出这个元素,条件是它的任何属性中都有一个关键字"徽标">
挑战在于:
- 我有数千个url,关键字徽标可能在不同url的不同属性中
- 逻辑:如果ANY中的"logo"(list_of_possible_attributes_that_this_element_has中属性的属性(与列表综合的工作方式不同,因为我找不到如何在不使用特定名称的情况下访问任何可能的属性
- 检查所有特定的名称也是有问题的,因为特定的属性可能存在于一个元素中,而不存在于引发错误的另一个元素
- 上面的例子也很有挑战性,因为属性值是一个列表,所以我们需要将其压平,以便能够检查关键字是否在其中
- 对于大多数url,我要查找的元素不会像本例中那样作为顶部元素返回,因此选择顶部优先不是一个选项
有没有一种方法可以根据其任何属性中的关键字过滤掉元素?(事先不知道属性的名称是什么?(。
如果我理解正确,你可以使用类似于这个答案的过滤函数来搜索所有标签,这样任何标签属性的值都包含val
:
def my_filter(tag, val):
types = ['.jpg','.jpeg','.svg','.png']
if tag is not None and tag.name == "img" and tag.has_attr("src"):
if all(y not in tag['src'] for y in types):
return False
for key in tag.attrs.keys():
if isinstance(tag[key], list):
if any(val in entry for entry in tag[key]):
return True
else:
if val in tag[key]:
return True
return False
res = soup.find_all(lambda tag: my_filter(tag, "logo"))