Skip to content
Advertisement

BeautifulSoup – search by text inside a tag

Observe the following problem:

JavaScript

For some reason, BeautifulSoup will not match the text, when the <i> tag is there as well. Finding the tag and showing its text produces

JavaScript

Right. According to the Docs, soup uses the match function of the regular expression, not the search function. So I need to provide the DOTALL flag:

JavaScript

Alright. Looks good. Let’s try it with soup

JavaScript

Edit

My solution based on geckons answer: I implemented these helpers:

JavaScript

Now, when I want to find the element above, I just run find_by_text(soup, 'Edit', 'a', href='/customer-menu/1/accounts/1/update')

Advertisement

Answer

The problem is that your <a> tag with the <i> tag inside, doesn’t have the string attribute you expect it to have. First let’s take a look at what text="" argument for find() does.

NOTE: The text argument is an old name, since BeautifulSoup 4.4.0 it’s called string.

From the docs:

Although string is for finding strings, you can combine it with arguments that find tags: Beautiful Soup will find all tags whose .string matches your value for string. This code finds the tags whose .string is “Elsie”:

JavaScript

Now let’s take a look what Tag‘s string attribute is (from the docs again):

If a tag has only one child, and that child is a NavigableString, the child is made available as .string:

JavaScript

(…)

If a tag contains more than one thing, then it’s not clear what .string should refer to, so .string is defined to be None:

JavaScript

This is exactly your case. Your <a> tag contains a text and <i> tag. Therefore, the find gets None when trying to search for a string and thus it can’t match.

How to solve this?

Maybe there is a better solution but I would probably go with something like this:

JavaScript

I think there are not too many links pointing to /customer-menu/1/accounts/1/update so it should be fast enough.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement