I\'m trying to extract URLs from a sitemap like this: https://www.bestbuy.com/sitemap_c_0.xml.gz
I\'ve unzipped and saved the .xml.gz file as an .xml file. The struc
We can iterate through the URLs, toss them into a list and write them to a file as such:
from xml.etree import ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
name_space = '{http://www.sitemaps.org/schemas/sitemap/0.9}'
urls = []
for child in root.iter():
for block in child.findall('{}url'.format(name_space)):
for url in block.findall('{}loc'.format(name_space)):
urls.append('{}\n'.format(url.text))
with open('sample_urls.txt', 'w+') as f:
f.writelines(urls)
You were close in your attempt but like mzjn said in a comment, you didn't account for the default namespace (xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
).
Here's an example of how to account for the namespace:
import xml.etree.ElementTree as ET
tree = ET.parse('my_local_filepath')
ns = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"}
for elem in tree.findall(".//sm:loc", ns):
print(elem.text)
output:
https://www.bestbuy.com/
https://www.bestbuy.com/site/3d-printers/3d-printer-filament/pcmcat335400050008.c?id=pcmcat335400050008
https://www.bestbuy.com/site/3d-printers/3d-printing-accessories/pcmcat748300527647.c?id=pcmcat748300527647
Note that I used the namespace prefix sm
, but you could use any NCName.
See here for more information on parsing XML with namespaces in ElementTree.
I know this is a bit of a zombie reply, but I actually just posted a tool on github that does exactly what you're looking for. And in Python! So feel free to take what you need from the source code (or use it as-is). I figured I'd comment with this so other people who come across this thread would have it.
Here it is: https://github.com/tcaldron/xmlscrape