Python如何从网页上爬取XML格式的RSS源

Python爬取RSS源本质是获取XML格式HTTP响应,需用requests发送带User-Agent的GET请求、显式设encoding为utf-8、检查status_code和Content-Type,再用xml.etree.ElementTree解析rss或feed根节点及item/entry条目,注意命名空间、HTML解码与日期解析等容错处理。

Python爬取RSS源本质上是获取XML格式的HTTP响应内容,不需要复杂渲染,重点在于可靠地发送请求、处理编码和解析XML结构。

使用requests获取RSS内容

RSS本质是公开的XML文件,直接用requests发起GET请求即可。注意设置合理的User-Agent避免被拒绝,多数RSS不需登录或JS执行。

  • 确保URL以.xml/feed/rss等结尾(如https://example.com/feed.xml
  • 添加headers={'User-Agent': 'Mozilla/5.0'}提高请求成功率
  • response.encoding = 'utf-8'显式指定编码,防止中文乱码
  • 检查response.status_code == 200再继续解析

用xml.etree.ElementTree解析RSS

Python标准库xml.etree.ElementTree足够处理规范RSS(如RSS 2.0、Atom),无需额外安装。

  • RSS根节点通常是,用tree.getroot()获取
  • root.findall('.//item')提取所有文章条目(RSS 2.0)或root.findall('{http://www.w3.org/2005/Atom}entry')(Atom)
  • 每个item下常用字段:titlelinkpubDatedescription,用elem.findtext('tagname')安全读取

处理常见问题

RSS源质量参差不齐,需主动容错。

  • 部分站点返回HTML而非XML(如重定向到主页),检查response.headers.get('Content-Type', '')是否含xmlrss
  • 日期格式不统一(如Sat, 01 Jan 2025 12:00:00 GMT),可用email.utils.pars

    edate_to_datetime()
    转为datetime对象
  • 描述内容含HTML标签,用html.unescape()解码,必要时用re.sub(r']+>', '', text)简单去标
  • 网络不稳定时加try/except和重试逻辑(如requests.adapters.Retry

简单示例代码

以下是一个最小可行脚本:

import requests
from xml.etree import ElementTree as ET
from urllib.parse import urljoin

url = "https://example.com/feed.xml"
headers = {"User-Agent": "Mozilla/5.0"}

try:
    resp = requests.get(url, headers=headers, timeout=10)
    resp.raise_for_status()
    resp.encoding = "utf-8"

    root = ET.fromstring(resp.text)
    items = root.findall(".//item") or root.findall(".//{http://www.w3.org/2005/Atom}entry")

    for item in items[:5]:
        title = item.findtext("title") or item.findtext("{http://www.w3.org/2005/Atom}title")
        link = item.findtext("link") or item.findtext("{http://www.w3.org/2005/Atom}link").get("href", "") if item.find("{http://www.w3.org/2005/Atom}link") else ""
        print(title.strip(), urljoin(url, link))
except Exception as e:
    print("获取失败:", e)

不复杂但容易忽略细节,关键是把RSS当普通XML文件对待,稳住请求、看清命名空间、做好异常兜底。