Use a function arg in soup

Peter Otten __peter__ at web.de
Wed Aug 1 08:09:29 EDT 2018


Sayth Renshaw wrote:

> Hi.
> 
> I want to use a function argument as an argument to a bs4 search for
> attributes.
> 
> I had this working not as a function
>    # noms = soup.findAll('nomination')
>     # nom_attrs = []
>     # for attr in soup.nomination.attrs:
>     #     nom_attrs.append(attr)
> But as I wanted to keep finding other elements I thought I would turn it
> into a generator function.
> 
> 
> def attrKey(element):
>         for attr in soup.element.attrs:
>             yield attr
> 
> results in a Nonetype as soup.element.attrs is passed and the attribute
> isn't substituted.

(1) soup.nomination will only give the first <nomination>, so in the general 
case soup.find_all("nomination") is the better approach.

(2) attrs is a dict, so iterating over it will lose the values. Are you sure 
you want that?

If you use find_all() that already takes a string, so

>>> from bs4 import BeautifulSoup as BS
>>> soup = BS("<foo a=1 b=2>FOO</foo><bar b=4 c=5>BAR</bar><foo 
d=42>FOO2</foo>")
>>> def gen_attrs(soup, element):
...     for e in soup.find_all(element): yield e.attrs
... 
>>> list(gen_attrs(soup, "foo"))
[{'b': '2', 'a': '1'}, {'d': '42'}]

To access an attribute programatically there's the getattr() builtin;
foo.bar is equivalent to getattr(foo, "bar"), so

>>> def get_attrs(soup, element):
...     return getattr(soup, element).attrs
... 
>>> get_attrs(soup, "foo")
{'b': '2', 'a': '1'}

> 
> # Attempt 2
> def attrKey(element):
>         for attr in "soup.{}.attrs".format(element):
>             yield attr
> 
> # Attempt 3
> def attrKey(element):
>         search_attr = "soup.{}.attrs".format(element)
>         for attr in search_attr:
>             yield attr
> 
> 
> so I would call it like
> attrKey('nomination')
> 
> Any ideas on how the function argument can be used as the search
> attribute?
> 
> Thanks
> 
> Sayth





More information about the Python-list mailing list