增加今天的数据更新

This commit is contained in:
2025-11-19 20:43:38 +08:00
parent 40df4ee171
commit 8258c3532d
10 changed files with 9339 additions and 2888 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -114,32 +114,51 @@ class ProductHuntScraper:
try:
logger.info("模拟点击制作人链接...")
# 查找要点击的a标签
a_element = await self.page.query_selector(f'a[href*="{maker_link.split("/")[-1]}"]')
if not a_element:
# 如果找不到特定href的a标签尝试查找包含制作人文本的a标签
a_element = await self.page.query_selector(f'a:has-text("{maker_text}")')
if not a_element:
logger.warning("未找到要点击的a标签使用备用方法")
# 查找包含制作人信息的div容器class="flex flex-col gap-1"
div_container = await self.page.query_selector('div.flex.flex-col.gap-1')
if not div_container:
logger.warning("未找到class='flex flex-col gap-1'的div容器使用备用方法")
# 备用方法:直接打开新窗口
return await self._extract_maker_statement_direct_open(maker_link, maker_text)
# 获取a标签的边界框,用于点击中间位置
bbox = await a_element.bounding_box()
# 获取div容器的边界框,用于点击中间位置
bbox = await div_container.bounding_box()
if not bbox:
logger.warning("无法获取a标签边界框,使用备用方法")
logger.warning("无法获取div容器边界框,使用备用方法")
return await self._extract_maker_statement_direct_open(maker_link, maker_text)
# 计算中间位置
center_x = bbox['x'] + bbox['width'] / 2
center_y = bbox['y'] + bbox['height'] / 2
# 计算div容器中前面几个元素的高度总和
# 获取div容器内的所有子元素
child_elements = await div_container.query_selector_all('*')
logger.info(f"点击a标签中间位置: ({center_x:.1f}, {center_y:.1f})")
# 计算前面几个元素的高度总和
total_height = 0
element_count = 0
max_elements = 3 # 考虑前面3个元素的高度
for child in child_elements[:max_elements]:
child_bbox = await child.bounding_box()
if child_bbox:
total_height += child_bbox['height']
element_count += 1
logger.debug(f"元素{element_count}高度: {child_bbox['height']:.1f}px")
# 如果无法获取子元素高度使用div容器高度的一半
if total_height == 0:
center_y = bbox['y'] + bbox['height'] / 2
logger.info("使用div容器高度的一半作为点击位置")
else:
# 计算点击位置div容器的y坐标 + 前面元素高度总和
center_y = bbox['y'] + total_height
logger.info(f"使用前面{element_count}个元素高度总和作为点击位置")
center_x = bbox['x'] + bbox['width'] / 2
logger.info(f"点击位置: ({center_x:.1f}, {center_y:.1f})")
# 监听新窗口打开事件
async with self.page.context.expect_page() as new_page_info:
# 模拟点击a标签中间位置
# 模拟点击计算出的位置
await self.page.mouse.click(center_x, center_y)
# 获取新页面
@@ -197,7 +216,7 @@ class ProductHuntScraper:
new_page = await self.browser.new_page()
# 导航到制作人页面
await new_page.goto(maker_link, wait_until="domcontentloaded", timeout=300000)
await new_page.goto(maker_link, wait_until="domcontentloaded", timeout=3000000)
# 等待页面加载
await new_page.wait_for_timeout(3000)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 KiB

After

Width:  |  Height:  |  Size: 631 KiB

View File

@@ -8,4 +8,4 @@
用户数: 15K followers
提取时间: 2025-11-18 22:18:51
提取时间: 2025-11-18 22:38:38

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,155 +0,0 @@
# 右键菜单功能说明
## 功能概述
TopHub数据查看器的右键菜单功能允许用户通过右键点击表格中的项目快速执行常用操作提高操作效率。
## 新增功能
### 1. 标记为感兴趣
- **功能描述**:将选中的项目标记为感兴趣状态
- **数据库操作**:将对应记录的`is_interested`字段设置为1
- **界面显示**:在"感兴趣"列显示为"是",使用绿色粗体字体
### 2. 标记为不感兴趣
- **功能描述**:将选中的项目标记为不感兴趣状态
- **数据库操作**:将对应记录的`is_interested`字段设置为0
- **界面显示**:在"感兴趣"列显示为"否",使用普通字体和颜色
### 3. 删除选中项
- **功能描述**:删除选中的项目
- **数据库操作**:从数据库中删除对应记录
- **界面显示**:从表格中移除对应行
## 使用方法
1. 打开TopHub数据查看器
2. 在表格中右键点击任意项目
3. 在弹出的右键菜单中选择所需操作:
- 点击"标记为感兴趣"将项目标记为感兴趣
- 点击"标记为不感兴趣"将项目标记为不感兴趣
- 点击"删除选中项"删除选中的项目
## 技术实现
### 右键菜单实现
```python
# 启用右键菜单
self.table.setContextMenuPolicy(Qt.CustomContextMenu)
self.table.customContextMenuRequested.connect(self.show_context_menu)
def show_context_menu(self, position):
"""显示右键菜单"""
# 获取点击位置的行
row = self.table.rowAt(position.y())
if row < 0:
return
# 选中该行
self.table.selectRow(row)
# 创建右键菜单
menu = QMenu(self)
# 添加"标记为感兴趣"动作
mark_action = QAction("标记为感兴趣", self)
mark_action.triggered.connect(self.mark_as_interested)
menu.addAction(mark_action)
# 添加"标记为不感兴趣"动作
unmark_action = QAction("标记为不感兴趣", self)
unmark_action.triggered.connect(self.mark_as_not_interested)
menu.addAction(unmark_action)
# 添加分隔线
menu.addSeparator()
# 添加"删除"动作
delete_action = QAction("删除选中项", self)
delete_action.triggered.connect(self.delete_selected_items)
menu.addAction(delete_action)
# 显示菜单
menu.exec_(self.table.mapToGlobal(position))
```
### 标记为不感兴趣方法实现
```python
def mark_as_not_interested(self):
"""将选中的项目标记为不感兴趣"""
# 获取选中的行
selected_rows = set()
for item in self.table.selectedItems():
selected_rows.add(item.row())
# 如果没有选中的行,直接返回
if not selected_rows:
QMessageBox.information(self, "提示", "请先选中要标记的行")
return
# 弹出确认对话框
reply = QMessageBox.question(
self,
"确认标记",
f"确定要将选中的 {len(selected_rows)} 行标记为不感兴趣吗?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes
)
if reply == QMessageBox.No:
return
try:
# 连接数据库
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# 更新选中的行
updated_count = 0
for row in selected_rows:
# 获取ID
id_item = self.table.item(row, 0)
if id_item:
article_id = id_item.text()
# 更新数据库中的is_interested字段
cursor.execute("UPDATE articles SET is_interested = 0 WHERE id = ?", (article_id,))
# 更新表格中的显示
interested_item = QTableWidgetItem("")
# 不感兴趣项使用普通字体和颜色
self.table.setItem(row, 5, interested_item)
updated_count += 1
# 提交更改
conn.commit()
conn.close()
# 更新状态栏
self.status_bar.showMessage(f"已标记 {updated_count} 行为不感兴趣")
except sqlite3.Error as e:
logger.error(f"标记数据时出错: {str(e)}")
QMessageBox.critical(self, "数据库错误", f"标记数据时出错: {str(e)}")
self.status_bar.showMessage("标记失败")
except Exception as e:
logger.error(f"标记数据时出错: {str(e)}")
QMessageBox.critical(self, "错误", f"标记数据时出错: {str(e)}")
self.status_bar.showMessage("标记失败")
```
## 测试
测试脚本`test_mark_not_interested.py`验证了"标记为不感兴趣"功能的正确性。测试结果显示功能正常工作,能够正确地将项目标记为不感兴趣,并更新数据库和界面显示。
## 注意事项
1. 右键菜单操作前必须先选中要操作的项目
2. 删除操作不可撤销,请谨慎使用
3. 标记操作会直接更新数据库,确保操作前已确认选择
4. 批量操作时,所有选中的项目都会被同时处理
## 更新记录
- 2023-11-07添加"标记为不感兴趣"功能到右键菜单
- 2023-11-07完成功能测试和文档编写

View File

@@ -1,44 +0,0 @@
# 数据库字段添加总结
## 任务概述
为TopHub数据库查看器添加一个"感兴趣"字段,允许用户标记感兴趣的文章。
## 实施步骤
### 1. 数据库结构修改
- 创建了`add_interested_field.py`脚本,用于向`articles`表添加`is_interested`字段
- 字段类型INTEGER默认值0
- 脚本包含字段存在性检查、添加逻辑和验证功能
### 2. 数据库验证
- 创建了`check_db_structure.py`脚本,用于检查数据库结构
- 创建了`test_interested_field.py`脚本,用于验证字段功能
- 创建了`show_data_with_interested.py`脚本,用于显示包含感兴趣状态的记录
### 3. GUI界面修改
- 修改了`db_viewer.py`文件,添加了以下功能:
- 在表格中添加"感兴趣"列,显示`is_interested`字段值
- 添加"标记为感兴趣"按钮,允许用户将选中的文章标记为感兴趣
- 更新查询语句,包含`is_interested`字段
- 更新筛选功能,包含感兴趣列
## 测试结果
- 数据库字段成功添加默认值为0
- 可以成功将记录标记为感兴趣值为1
- GUI应用程序能够正常显示和操作感兴趣字段
- 统计功能正常工作,可以显示感兴趣和不感兴趣的记录数量
## 使用方法
1. 运行`python db_viewer.py`启动应用程序
2. 在表格中选择一条记录
3. 点击"标记为感兴趣"按钮将记录标记为感兴趣
4. 可以使用筛选功能查看感兴趣的记录
5. 统计面板会显示感兴趣和不感兴趣的记录数量
## 文件清单
- `add_interested_field.py` - 添加数据库字段的脚本
- `check_db_structure.py` - 检查数据库结构的脚本
- `test_interested_field.py` - 测试字段功能的脚本
- `show_data_with_interested.py` - 显示记录的命令行工具
- `test_gui.py` - GUI测试脚本
- `db_viewer.py` - 修改后的主应用程序

View File

@@ -1,70 +0,0 @@
# TopHub数据查看器 - 评分系统使用说明
## 概述
TopHub数据查看器已从简单的"感兴趣/不感兴趣"标记系统升级为10分评分制度。新系统提供了更精细的内容评价能力让您能够更准确地标记和管理抓取的内容。
## 评分系统说明
### 评分范围
- **最低分**: 0分 (完全不感兴趣)
- **默认分**: 5分 (中立态度)
- **最高分**: 10分 (非常感兴趣)
### 颜色编码
为了便于快速识别内容质量,系统根据分数自动显示不同颜色:
- **绿色加粗**: 8分及以上 (高价值内容)
- **蓝色**: 6-7分 (中等价值内容)
- **默认颜色**: 4-5分 (一般内容)
- **红色**: 3分及以下 (低价值内容)
## 使用方法
### 增加评分
1. 在表格中选择一行或多行
2. 右键点击选中的行
3. 从菜单中选择"增加评分(+1)"
4. 系统会将选中项的评分增加1分最高不超过10分
### 减少评分
1. 在表格中选择一行或多行
2. 右键点击选中的行
3. 从菜单中选择"减少评分(-1)"
4. 系统会将选中项的评分减少1分最低不低于0分
### 批量操作
- 可以同时选择多行进行批量评分调整
- 使用"按关键字选中"功能可以快速选择包含特定关键词的行
- 然后通过右键菜单进行批量评分调整
## 数据迁移
原有的"感兴趣/不感兴趣"数据已自动转换为新的评分系统:
- 原标记为"感兴趣"的项目已转换为7分
- 原标记为"不感兴趣"的项目已转换为5分(默认值)
## 技术细节
### 数据库结构
- 新增了`score`字段(INTEGER类型)替代原来的`is_interested`字段
- `score`字段默认值为5范围限制为0-10
### 界面更新
- 表格中的"感兴趣"列已更新为"评分"列,显示具体分数
- 右键菜单已更新为"增加评分(+1)"和"减少评分(-1)"选项
- 根据分数自动应用颜色编码,便于快速识别
## 常见问题
**Q: 为什么默认分数是5分而不是0分**
A: 5分代表中立态度更符合日常评分习惯。0分通常用于表示完全不相关或质量极差的内容。
**Q: 如何快速找到高评分内容?**
A: 高评分内容(8分及以上)会以绿色加粗显示,非常醒目。您也可以使用排序功能按评分列排序。
**Q: 可以直接设置任意分数吗?**
A: 当前版本只支持通过+1/-1的方式调整分数这样可以保持评分的一致性和可追溯性。
---
如有其他问题或建议,请随时反馈。