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
相关产品推荐
相关产品推荐

