fix: 修复无附件文章无法标记已读的问题

- 发现标记已读的正确 API: /tools/submit_ajax.ashx?action=saveread
- 添加 mark_article_read 方法调用 saveread API 标记文章已读
- 修改 get_article_attachments 返回文章的 channel_id 和 article_id
- 对每篇文章都调用 mark_article_read,无论是否有附件
- 解决米米88、黄紫夏99等账号文章无法标记已读的问题

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-14 13:24:29 +08:00
parent 6313631b09
commit 606cad43dc

View File

@@ -351,7 +351,14 @@ class APIBrowser:
return articles, total_pages, next_page_url
def get_article_attachments(self, article_href: str):
"""获取文章的附件列表"""
"""
获取文章的附件列表和文章信息
Returns:
tuple: (attachments_list, article_info)
- attachments_list: 附件列表
- article_info: 包含 channel_id 和 article_id 的字典,用于标记文章已读
"""
if not article_href.startswith('http'):
url = f"{BASE_URL}/admin/{article_href}"
else:
@@ -361,6 +368,16 @@ class APIBrowser:
soup = BeautifulSoup(resp.text, 'html.parser')
attachments = []
article_info = {'channel_id': None, 'article_id': None}
# 从 saveread 按钮获取 channel_id 和 article_id
for elem in soup.find_all(['button', 'input']):
onclick = elem.get('onclick', '')
match = re.search(r'saveread\((\d+),(\d+)\)', onclick)
if match:
article_info['channel_id'] = match.group(1)
article_info['article_id'] = match.group(2)
break
attach_list = soup.find('div', {'class': 'attach-list2'})
if attach_list:
@@ -383,10 +400,31 @@ class APIBrowser:
})
break
return attachments
return attachments, article_info
def mark_article_read(self, channel_id: str, article_id: str) -> bool:
"""通过 saveread API 标记文章已读"""
if not channel_id or not article_id:
return False
import random
saveread_url = f"{BASE_URL}/tools/submit_ajax.ashx?action=saveread&time={random.random()}&fl={channel_id}&id={article_id}"
try:
resp = self._request_with_retry("post", saveread_url)
# 检查响应是否成功
if resp.status_code == 200:
try:
data = resp.json()
return data.get('status') == 1
except:
return True # 如果不是 JSON 但状态码 200也认为成功
return False
except:
return False
def mark_read(self, attach_id: str, channel_id: str = '1') -> bool:
"""通过访问预览通道标记已读"""
"""通过访问预览通道标记附件已读"""
download_url = f"{BASE_URL}/tools/download2.ashx?site=main&id={attach_id}&channel_id={channel_id}"
try:
@@ -499,9 +537,9 @@ class APIBrowser:
new_articles_in_page += 1
title = article['title'][:30]
# 获取附件(文章详情页)
# 获取附件和文章信息(文章详情页)
try:
attachments = self.get_article_attachments(article_href)
attachments, article_info = self.get_article_attachments(article_href)
consecutive_failures = 0
except Exception as e:
skipped_items += 1
@@ -516,12 +554,25 @@ class APIBrowser:
total_items += 1
report_progress()
# 标记文章已读(调用 saveread API
article_marked = False
if article_info.get('channel_id') and article_info.get('article_id'):
article_marked = self.mark_article_read(
article_info['channel_id'],
article_info['article_id']
)
# 处理附件(如果有)
if attachments:
for attach in attachments:
if self.mark_read(attach['id'], attach['channel_id']):
total_attachments += 1
self.log(f"[API] [{total_items}] {title} - {len(attachments)}个附件")
else:
# 没有附件的文章,只记录标记状态
status = "已标记" if article_marked else "标记失败"
self.log(f"[API] [{total_items}] {title} - 无附件({status})")
time.sleep(0.1)