You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python爬取RSS时如何提取带CDATA的pubDate并存储到数据库?

解决RSS中带CDATA的pubDate字段存储MySQL问题

问题根源

原代码存在以下核心问题导致报错:

  1. XML标签大小写不匹配:RSS中的标签是<pubDate>,但代码里用a.find('pubdate')(小写)无法正确匹配,导致提取不到日期内容
  2. CDATA内容提取未处理:带CDATA的<pubDate>内容在BeautifulSoup中需正确提取文本,原代码直接取.text可能出现空值或格式问题
  3. 日期格式不兼容:RSS的日期格式(如Wed, 17 Aug 2022 14:32:47 +0530)无法直接存入MySQL的datetime字段,需转换格式
  4. 代码语法错误:导入模块语句格式错误,存在无效代码行,且insertData方法未使用传入的date参数

修复步骤

1. 修正模块导入与无效代码

将导入语句拆分为独立行,删除无效代码:

from bs4 import BeautifulSoup
import requests
import pymysql
from datetime import datetime

2. 正确提取pubDate内容

使用正确的标签名pubDate提取内容,并用strip()去除首尾空格:

pub_date_raw = a.find('pubDate').string.strip()

3. 转换日期格式为MySQL兼容格式

利用datetime模块解析RSS日期,转换为MySQL支持的格式:

# 解析RSS日期格式
parsed_date = datetime.strptime(pub_date_raw, '%a, %d %b %Y %H:%M:%S %z')
# 转换为MySQL兼容的datetime对象
mysql_date = parsed_date.astimezone().replace(tzinfo=None)

4. 修正insertData方法

将date参数加入SQL插入语句和参数列表,确保数据库表的date字段类型为datetime或timestamp:

def insertData(self, title, date, url, description, source):
    myCursor = self.conn.cursor()
    query = "INSERT INTO `delhi`(`title`, `date`, `url`, `description`, `source`) VALUES(%s,%s,%s,%s,%s)"
    args = (title, date, url, description, source)
    myCursor.execute(query, args)
    self.conn.commit()

完整修正代码

from bs4 import BeautifulSoup
import requests
import pymysql
from datetime import datetime

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

class ReadRss:
    def __init__(self, rss_url, headers):
        self.url = rss_url
        self.headers = headers
        self.conn = None
        self.soup = None
        self.articles = []

        try:
            # 初始化数据库连接
            self.conn = pymysql.connect(
                host="localhost", 
                user="root", 
                passwd="", 
                db="my_python"
            )
            # 请求RSS内容并主动抛出HTTP错误
            self.r = requests.get(rss_url, headers=self.headers)
            self.r.raise_for_status()
        except Exception as e:
            print(f'获取URL失败: {rss_url}')
            print(f'错误信息: {e}')
            return

        try:
            # 使用xml解析器处理RSS内容
            self.soup = BeautifulSoup(self.r.text, 'xml')
        except Exception as e:
            print(f'解析XML失败: {self.url}')
            print(f'错误信息: {e}')
            return

        self.articles = self.soup.find_all('item')
        for a in self.articles:
            try:
                # 提取各字段内容
                title = a.find('title').string.strip()
                pub_date_raw = a.find('pubDate').string.strip()
                url = a.find('link').string.strip() if a.find('link') else a.link.next_sibling.replace('\n','').replace('\t','').strip()
                description = a.find('description').string.strip() if a.find('description') else ''

                # 转换日期格式
                parsed_date = datetime.strptime(pub_date_raw, '%a, %d %b %Y %H:%M:%S %z')
                mysql_date = parsed_date.astimezone().replace(tzinfo=None)

                # 插入数据库
                self.insertData(title, mysql_date, url, description, 'thehindu')
            except Exception as e:
                print(f'处理文章失败: {title if "title" in locals() else "未知标题"}')
                print(f'错误信息: {e}')
                continue
        
        # 关闭数据库连接
        if self.conn:
            self.conn.close()

    def insertData(self, title, date, url, description, source):
        try:
            myCursor = self.conn.cursor()
            query = "INSERT INTO `delhi`(`title`, `date`, `url`, `description`, `source`) VALUES(%s,%s,%s,%s,%s)"
            args = (title, date, url, description, source)
            myCursor.execute(query, args)
            self.conn.commit()
        except Exception as e:
            print(f'插入数据库失败')
            print(f'错误信息: {e}')
            self.conn.rollback()

if __name__ == '__main__':
    feed = ReadRss('https://www.thehindu.com/news/cities/Delhi/feeder/default.rss', headers)

关键注意事项

  • 数据库表结构:确保delhi表存在date字段,类型设置为datetime或timestamp
  • 解析器选择:使用xml解析器比lxml更适合处理RSS这类XML内容
  • 异常处理:新增单篇文章处理的异常捕获,避免一篇文章出错导致整个爬取中断
  • 时区处理:通过astimezone().replace(tzinfo=None)将带时区的日期转换为本地时间,适配MySQL的datetime类型

内容的提问来源于stack exchange,提问作者ASTHA JAIN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:54:28