XML站点地图是网站管理员用来向搜索引擎告知网站页面结构的标准化文件,通常存放在网站根目录下,文件名为sitemap.xml,里面包含了网站所有可访问页面的URL、最后更新时间、更新频率、优先级等信息,对于爬虫来说是非常高效的页面发现渠道。

解析XML站点地图的核心步骤
Python解析XML站点地图的整体流程可以分为三步:首先发送HTTP请求获取站点地图的原始内容,然后解析XML格式的内容提取需要的节点信息,最后对提取到的数据进行清洗和存储。下面我们逐步展开说明。
1. 发送请求获取站点地图内容
我们需要先通过requests库向目标网站的站点地图地址发送请求,获取返回的原始XML文本。这里需要注意处理请求异常,比如站点地图不存在、请求被拦截等情况。
import requests
def get_sitemap_content(sitemap_url):
"""获取站点地图的原始内容"""
try:
# 设置合理的请求头,模拟浏览器访问
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
response = requests.get(sitemap_url, headers=headers, timeout=10)
# 判断请求是否成功
if response.status_code == 200:
# 返回文本内容,使用响应指定的编码
return response.text
else:
print(f"请求失败,状态码:{response.status_code}")
return None
except Exception as e:
print(f"请求过程出现异常:{e}")
return None
# 测试获取站点地图内容,这里使用ipipp.com的站点地图作为示例
sitemap_url = "https://ipipp.com/sitemap.xml"
sitemap_content = get_sitemap_content(sitemap_url)
if sitemap_content:
print("成功获取站点地图内容")
2. 解析XML内容提取URL信息
获取到XML文本后,我们可以使用lxml库的etree模块来解析XML结构,提取<loc>标签中的URL内容。XML站点地图的标准命名空间是http://www.sitemaps.org/schemas/sitemap/0.9,解析时需要注意带上命名空间才能正确匹配节点。
from lxml import etree
def parse_sitemap_urls(sitemap_content):
"""解析站点地图内容,提取所有页面URL"""
if not sitemap_content:
return []
try:
# 解析XML内容
root = etree.fromstring(sitemap_content.encode("utf-8"))
# 定义站点地图的命名空间
namespace = {"sitemap": "http://www.sitemaps.org/schemas/sitemap/0.9"}
# 匹配所有loc标签,注意要带上命名空间前缀
loc_elements = root.xpath("//sitemap:loc", namespaces=namespace)
# 提取loc标签的文本内容,即页面URL
urls = [element.text for element in loc_elements if element.text]
return urls
except Exception as e:
print(f"解析XML内容出现异常:{e}")
return []
# 接上面的测试代码,解析获取到的站点地图内容
if sitemap_content:
urls = parse_sitemap_urls(sitemap_content)
print(f"解析到{len(urls)}个页面URL")
# 打印前5个URL查看效果
for url in urls[:5]:
print(url)
3. 处理嵌套的站点地图索引文件
有些大型网站的站点地图不是单个文件,而是使用站点地图索引文件,里面包含多个子站点地图的链接,这时候我们需要先解析索引文件获取所有子站点地图的地址,再逐个请求解析子站点地图的内容。
def parse_sitemap_index(sitemap_content):
"""解析站点地图索引文件,获取所有子站点地图的URL"""
if not sitemap_content:
return []
try:
root = etree.fromstring(sitemap_content.encode("utf-8"))
namespace = {"sitemap": "http://www.sitemaps.org/schemas/sitemap/0.9"}
# 提取所有子站点地图的loc标签内容
sub_sitemap_urls = root.xpath("//sitemap:loc", namespaces=namespace)
return [element.text for element in sub_sitemap_urls if element.text]
except Exception as e:
print(f"解析站点地图索引出现异常:{e}")
return []
def get_all_urls_from_sitemap(sitemap_url):
"""递归处理站点地图索引,获取所有页面URL"""
all_urls = []
content = get_sitemap_content(sitemap_url)
if not content:
return all_urls
# 先尝试解析为普通站点地图,提取页面URL
page_urls = parse_sitemap_urls(content)
if page_urls:
all_urls.extend(page_urls)
else:
# 如果不是普通站点地图,尝试解析为站点地图索引
sub_sitemap_urls = parse_sitemap_index(content)
for sub_url in sub_sitemap_urls:
# 递归处理子站点地图
sub_urls = get_all_urls_from_sitemap(sub_url)
all_urls.extend(sub_urls)
return all_urls
# 测试处理站点地图索引的场景
index_sitemap_url = "https://ipipp.com/sitemap_index.xml"
all_page_urls = get_all_urls_from_sitemap(index_sitemap_url)
print(f"总共获取到{len(all_page_urls)}个页面URL")
常见问题与注意事项
- 部分网站的站点地图会设置访问权限,需要携带合理的请求头才能正常获取,建议设置模拟浏览器的User-Agent。
- XML站点地图可能存在格式不规范的情况,解析时如果遇到异常可以尝试先对内容进行简单的清洗,比如去除多余的空白字符。
- 解析得到的URL可以去重后再使用,避免重复爬取同一个页面。
- 如果站点地图内容过大,不建议一次性加载到内存,可以使用lxml的迭代解析方式处理大文件。
扩展:提取更多站点地图信息
除了URL之外,站点地图中还包含<lastmod>(最后更新时间)、<changefreq>(更新频率)、<priority>(优先级)等信息,我们可以根据需求提取这些内容。
def parse_sitemap_detail(sitemap_content):
"""解析站点地图,提取URL、更新时间、优先级等详细信息"""
if not sitemap_content:
return []
try:
root = etree.fromstring(sitemap_content.encode("utf-8"))
namespace = {"sitemap": "http://www.sitemaps.org/schemas/sitemap/0.9"}
# 匹配所有url标签
url_elements = root.xpath("//sitemap:url", namespaces=namespace)
result = []
for url_element in url_elements:
item = {}
# 提取URL
loc = url_element.xpath("./sitemap:loc", namespaces=namespace)
item["url"] = loc[0].text if loc else None
# 提取最后更新时间
lastmod = url_element.xpath("./sitemap:lastmod", namespaces=namespace)
item["lastmod"] = lastmod[0].text if lastmod else None
# 提取更新频率
changefreq = url_element.xpath("./sitemap:changefreq", namespaces=namespace)
item["changefreq"] = changefreq[0].text if changefreq else None
# 提取优先级
priority = url_element.xpath("./sitemap:priority", namespaces=namespace)
item["priority"] = priority[0].text if priority else None
result.append(item)
return result
except Exception as e:
print(f"解析站点地图详细信息出现异常:{e}")
return []
# 测试提取详细信息
if sitemap_content:
detail_list = parse_sitemap_detail(sitemap_content)
print(f"解析到{len(detail_list)}条详细信息")
# 打印第一条信息查看结构
if detail_list:
print(detail_list[0])
Python爬虫XML_sitemap网页解析requestslxml修改时间:2026-07-13 20:51:42