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

Python网页爬虫问题:按发布日期筛选排序TheHackerNews链接

解决方案:按发布日期筛选、排序TheHackerNews新闻并避免重复请求

1. 解析网页中的发布日期

先从<span class='h-datetime'>标签提取日期字符串,转换成Python可处理的datetime对象,为后续筛选和排序做准备:

from bs4 import BeautifulSoup
import requests
from datetime import datetime

def parse_hn_dates(html_content):
    soup = BeautifulSoup(html_content, 'html.parser')
    news_items = soup.find_all('div', class_='body-post clear')
    news_data = []
    
    for item in news_items:
        date_tag = item.find('span', class_='h-datetime')
        if not date_tag:
            continue
        date_str = date_tag.get_text(strip=True)
        # 兼容两种日期格式:仅日期/日期+时间
        try:
            publish_date = datetime.strptime(date_str, "%B %d, %Y")
        except ValueError:
            publish_date = datetime.strptime(date_str, "%B %d, %Y %H:%M")
        
        title_tag = item.find('h2', class_='home-title').find('a')
        news_link = title_tag['href']
        news_title = title_tag.get_text(strip=True)
        
        news_data.append({
            'title': news_title,
            'link': news_link,
            'publish_date': publish_date
        })
    return news_data

2. 按日期筛选并排序

筛选出目标日期范围内的新闻,再按发布日期降序排序(最新内容优先):

def filter_and_sort_news(news_data, target_date=None):
    if not target_date:
        target_date = datetime.now().date()
    
    # 筛选当日发布的新闻
    filtered = [item for item in news_data if item['publish_date'].date() == target_date]
    # 按发布时间降序排列
    sorted_news = sorted(filtered, key=lambda x: x['publish_date'], reverse=True)
    return sorted_news

3. 结合Redis避免重复请求

用Redis存储已处理的新闻链接,每次处理前校验链接是否已存在,避免重复发送:

import redis

def init_redis():
    return redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)

def is_link_processed(redis_conn, link):
    return redis_conn.exists(f"hn_processed:{link}")

def mark_link_processed(redis_conn, link):
    # 7天后自动过期,避免Redis存储冗余数据
    redis_conn.setex(f"hn_processed:{link}", 60*60*24*7, "1")

def process_news(sorted_news, redis_conn, keywords):
    # 筛选含指定关键词的新闻
    keyword_matched = [item for item in sorted_news 
                       if any(k.lower() in item['title'].lower() for k in keywords)]
    
    for news in keyword_matched:
        if not is_link_processed(redis_conn, news['link']):
            # 替换为你的发送逻辑(邮件/推送等)
            print(f"待发送: {news['title']} - {news['link']}")
            mark_link_processed(redis_conn, news['link'])

4. 整合每日定时任务

用schedule库实现每日定时执行逻辑:

import schedule
import time

def daily_task(keywords):
    redis_conn = init_redis()
    response = requests.get('https://thehackernews.com/')
    if response.status_code != 200:
        print("网页请求失败")
        return
    news_data = parse_hn_dates(response.text)
    sorted_news = filter_and_sort_news(news_data)
    process_news(sorted_news, redis_conn, keywords)

# 设置每日9点执行,可自定义时间和关键词
schedule.every().day.at("09:00").do(daily_task, keywords=["ransomware", "data breach"])

# 启动定时任务循环
while True:
    schedule.run_pending()
    time.sleep(60)

关键注意事项

  • 日期格式兼容:处理网页中可能出现的两种日期格式,避免解析报错
  • Redis键名设计:用hn_processed:{link}作为存储键,便于区分不同类型数据
  • 进程稳定性:若脚本长期运行,建议用supervisord等工具守护进程,防止意外退出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:10:34