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

Python用newspaper存数据到DataFrame遇'tzutc'不可哈希类型错误求助

嘿,我来帮你拆解这两个问题,一步步解决它们!

问题1:TypeError: unhashable type: 'tzutc'的根源

这个错误是因为newspaper库返回的article.publish_date是带时区信息(tzutc)的datetime对象,而pandas在处理这种带时区的对象时,内部哈希操作会失败——时区对象本身是不可哈希的。另外你代码里d的类型还不一致:当publish_date存在时是带时区的datetime,不存在时是date类型,这进一步加剧了DataFrame的类型混乱。

问题2:无法写入DataFrame的原因

除了上面的时区问题,还有两个小坑:

  • 当article.parse()失败时,article.title、article.text等属性可能未被初始化,直接赋值会导致空值/未定义的问题;
  • 用df.loc[index]逐行赋值的方式本身就容易因为类型不匹配触发错误,而且效率很低。

完整修复代码

smallURL= ['http://www.walesonline.co.uk/business/business-news/more-70-jobs-created-bio-12836127','http://economictimes.indiatimes.com/articleshow/61006825.cms?utm_source=contentofinterest&utm_medium=text&utm_campaign=cppst','http://100seguro.com.ar/telefonica-pone-en-venta-su-aseguradora-antares-vida/','http://13wham.com/news/local/urmc-opens-newest-urgent-care-facility']
import pandas as pd
import datetime
from newspaper import Article

# 用with语句管理文件,自动关闭更安全
with open('myfile', 'w', encoding='utf-8') as f:
    # 用列表统一收集数据,避免逐行赋值的类型冲突
    data_list = []
    
    for url in smallURL:
        article = Article(url)
        article.download()
        
        # 先设置默认值,防止parse失败导致属性缺失
        title = ""
        text = ""
        keywords = []
        publish_date = datetime.datetime.now().date()
        
        try:
            article.parse()
            title = article.title
            text = article.text
            keywords = article.keywords
            # 处理带时区的publish_date:移除时区信息后转成date类型
            if article.publish_date is not None:
                publish_date = article.publish_date.replace(tzinfo=None).date()
            # 修正文件写入的语法错误
            f.write(f"{title}\n")
        except Exception as e:
            print(f"解析URL {url} 时出错: {str(e)}")
            pass
        
        print(f"作者: {article.authors}")
        print(f"正文预览: {text[:50]}...")  # 只打印前50字避免刷屏
        print(f"关键词: {keywords}")
        print(f"URL: {url}\n")
        
        # 将当前条目的数据加入列表
        data_list.append({
            'd': publish_date,
            'datetime': datetime.datetime.now().date(),  # 如果需要完整时间,改成datetime.datetime.now().replace(tzinfo=None)
            'title': title,
            'text': text,
            'keywords': keywords,
            'url': url
        })

# 最后一次性生成DataFrame,稳定又高效
df = pd.DataFrame(data_list)
# 可以打印看看结果
print(df.head())

关键修复点说明

  1. 时区处理:用replace(tzinfo=None)移除datetime对象的时区信息,避免不可哈希的tzutc对象触发错误;同时统一publish_date为date类型,保证列类型一致。
  2. 数据收集方式:先把所有数据存入列表,最后一次性创建DataFrame,既避免了逐行赋值的类型冲突,也提升了代码效率。
  3. 异常处理优化:给所有字段设置默认值,即使parse失败也能正常赋值;同时打印错误信息,方便排查具体是哪个URL出了问题。
  4. 文件写入修正:用f-string修复了原来的语法错误,同时用with语句管理文件,避免忘记关闭文件的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:09:47