Предполагается, что вы используете Beautiful Soup 4.7 +.
Вы можете использовать селекторы для этого.То, что вы показываете, выглядит как XML, поэтому я предполагаю, что где-то в вашем документе image
определено пространство имен.В этом примере мы будем предполагать, что пространство имен определено как xmlns:image="http://somenamespace.com"
, что означает, что префикс image
(предшествующий :
) представляет пространство имен http://somenamespace.com
.Предположим, что loc
без пространства имен не имеет.И наконец, мы будем использовать |loc
, чтобы указать, что мы хотим loc
без пространства имен:
from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:image="http://somenamespace.com">
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
</root>
"""
soup = BeautifulSoup(xml, 'xml')
print(soup.select('|loc'))
Вывод
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
Но если loc
имеетпространство имен, которому не назначен префикс, мы все еще можем нацелить его.Давайте предположим, что оно имеет пространство имен по умолчанию xmlns="http://default.com"
.Желаемому loc не присваивается префикс, поэтому в этом примере он унаследует наше пространство имен по умолчанию.
Префикс в документе действительно имеет значение только для синтаксического анализатора, поэтому мы можем дать нашему целевому пространству имен произвольный префикс.название для нашего селектора, мы назовем его default
.Затем мы можем нацелиться на тег loc
с помощью default|loc
.
from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" xmlns:image="http://somenamespace.com">
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
</root>
"""
soup = BeautifulSoup(xml, 'xml')
print(soup.select('default|loc', namespaces={'default': 'http://default.com'}))
Output
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
Вы можете даже определить его как пространство имен по умолчанию без префикса, а затем просто настроить таргетингэто как loc
:
from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" xmlns:image="http://somenamespace.com">
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
</root>
"""
soup = BeautifulSoup(xml, 'xml')
print(soup.select('loc', namespaces={'': 'http://default.com'}))
Выход
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
Для тех, кто не хочет использовать селекторы, вы также можете проверить prefix
элемента.В этом случае нам нужен loc
без префикса:
from bs4 import BeautifulSoup
import re
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" xmlns:image="http://somenamespace.com">
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
</root>
"""
soup = BeautifulSoup(xml, 'xml')
print([el for el in soup.find_all('loc') if not el.prefix])