Python中如何通过robots.txt的sitemap抓取网站当天新产生的URL
有的网站有 sitemap 文件,本就是给百度这类爬虫看的,会把当天新产生的 URL 和最近更新的 URL 放在 sitemap 文件里,这样就不用整过遍历网站,节约单宽,尤其是大型网站有上千万,过亿页面这类网站,通过抓取 sitemap 来发现新增 URL 比较有效。 就像这篇文章说的一样: https://www.yuanrenxue.com/crawler/crawler-tricks-3.html
Python中如何通过robots.txt的sitemap抓取网站当天新产生的URL
2 回复
要抓取robots.txt里sitemap中的当天新URL,可以这样搞:
import requests
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from urllib.robotparser import RobotFileParser
from urllib.parse import urlparse
def get_today_urls_from_sitemap(target_url):
"""从目标网站的sitemap中提取当天生成的URL"""
# 解析robots.txt获取sitemap
parsed_url = urlparse(target_url)
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
robots_url = f"{base_url}/robots.txt"
# 获取robots.txt内容
try:
response = requests.get(robots_url, timeout=10)
response.raise_for_status()
except requests.RequestException as e:
print(f"获取robots.txt失败: {e}")
return []
# 解析sitemap地址
sitemap_urls = []
for line in response.text.split('\n'):
line = line.strip()
if line.lower().startswith('sitemap:'):
sitemap_url = line.split(':', 1)[1].strip()
sitemap_urls.append(sitemap_url)
if not sitemap_urls:
print("未在robots.txt中找到sitemap")
return []
today_urls = []
today = datetime.now(timezone.utc).date()
# 处理每个sitemap
for sitemap_url in sitemap_urls:
try:
sitemap_resp = requests.get(sitemap_url, timeout=10)
sitemap_resp.raise_for_status()
# 解析XML
root = ET.fromstring(sitemap_resp.content)
# 命名空间处理
namespaces = {'ns': 'http://www.sitemaps.org/schemas/sitemap/0.9'}
# 查找所有URL条目
for url_elem in root.findall('.//ns:url', namespaces):
loc_elem = url_elem.find('ns:loc', namespaces)
lastmod_elem = url_elem.find('ns:lastmod', namespaces)
if loc_elem is not None:
url = loc_elem.text.strip()
# 检查最后修改时间
if lastmod_elem is not None and lastmod_elem.text:
try:
# 解析时间戳
lastmod_str = lastmod_elem.text.strip()
if 'T' in lastmod_str:
lastmod_dt = datetime.fromisoformat(lastmod_str.replace('Z', '+00:00'))
else:
lastmod_dt = datetime.strptime(lastmod_str, '%Y-%m-%d')
# 转换为UTC日期
if lastmod_dt.tzinfo is None:
lastmod_dt = lastmod_dt.replace(tzinfo=timezone.utc)
else:
lastmod_dt = lastmod_dt.astimezone(timezone.utc)
# 检查是否是今天
if lastmod_dt.date() == today:
today_urls.append(url)
except (ValueError, AttributeError) as e:
print(f"解析时间失败 {url}: {e}")
continue
except requests.RequestException as e:
print(f"获取sitemap失败 {sitemap_url}: {e}")
continue
except ET.ParseError as e:
print(f"解析XML失败 {sitemap_url}: {e}")
continue
return today_urls
# 使用示例
if __name__ == "__main__":
target_site = "https://example.com" # 替换为目标网站
today_urls = get_today_urls_from_sitemap(target_site)
print(f"找到 {len(today_urls)} 个当天URL:")
for url in today_urls:
print(f" - {url}")
关键点:
- 先抓robots.txt找sitemap地址
- 解析sitemap XML,注意命名空间
- 用lastmod字段判断是否当天更新
- 处理时区问题,统一转UTC比较
注意:不是所有网站都提供lastmod字段,有些可能更新不及时。
简单说就是解析sitemap的lastmod时间过滤出当天URL。
这算不算是个骚操作?

