chore: remove legacy code, keep only crawl directory

This commit is contained in:
kgod
2026-05-28 00:04:05 +08:00
parent c06f595559
commit 45762101bc
125 changed files with 0 additions and 8134 deletions
-3
View File
@@ -1,3 +0,0 @@
# ai-review-template
Template repository with Gitea Actions AI pull request review workflow.
-936
View File
@@ -1,936 +0,0 @@
# AI 招聘网站智能爬虫系统
## 项目目标
用户输入**公司名称**,系统自动完成:
1. 通过搜索引擎找到该公司的官网招聘页面
2. AI 分析页面结构,提取爬虫所需的 CSS 选择器配置
3. 使用配置自动爬取所有岗位数据
**核心理念**:让 AI Agent 像人一样「看懂」网页,自动生成爬虫配置,无需针对每个网站手写选择器。
---
## 整体流程
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 用户输入: 公司名称 │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 1: search_company │
│ 功能: 搜索引擎查找公司官网招聘页面 │
│ 输出: 招聘列表页 URL │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 2: page_analysis_graph │
│ 功能: 分析列表页,找到岗位项的 CSS 选择器 │
│ 输出: job_item_selector, change_type │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 3: next_page_graph │
│ 功能: 分析分页组件,找到「下一页」按钮的选择器 │
│ 输出: next_page_selector, change_type │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 4: detail_analysis_graph │
│ 功能: 进入详情页,提取各字段(标题/薪资/要求等)的选择器 │
│ 输出: field_selectors │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Step 5: crawler (待开发) │
│ 功能: 使用上述选择器配置,自动翻页爬取所有岗位数据 │
│ 输出: 结构化岗位数据列表 │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 模块说明
### 1. search_company_graph - 搜索招聘页面
**目的**: 根据公司名,通过搜索引擎找到其官网招聘列表页
**技术方案**: LangGraph 状态机 + Playwright + LLM 结构化输出
**流程**:
```
Node 0: route_entry (入口路由)
有已知 candidate_urls → 跳过搜索,直接 Node 3
无 → 进入 Node 1 搜索
Node 1: search_sogou
搜狗搜索 "{company_name} 招聘 官网"
提取结构化搜索结果(标题、URL、描述)
Node 2: extract_links
LLM 分析搜索结果
提取最多 3 个候选 URL(按可能性排序)
Node 3: visit_and_verify
访问候选 URL
LLM 判断是否为招聘列表页
判断标准:
- 包含多个岗位信息(职位名称)
- 页面有分页控件
- 或有岗位搜索/筛选功能
- 或有明确的岗位分类导航
✔️ 是 → 返回 URL ✅
❌ 不是 → 进入 Node 4
Node 4: navigate_to_recruitment
LLM 找页面上的招聘入口(避开已点击过的)
点击入口 → 回 Node 3 验证
循环最多 10 次,超过则换下一个候选 URL
```
**输入/输出**:
```python
from src.search_company_graph import search_company_recruitment
# 输入
company_name: str # 公司名称,如 "联想"
input_url: str # 已知招聘地址(可选),有值时跳过搜索直接验证
headless: bool # 是否无头模式,默认 False
# 输出 (成功)
["https://jobs.lenovo.com.cn/..."] # 招聘页面 URL 列表
# 输出 (失败)
[] # 空列表,表示未找到
```
**文件结构**:
```
src/search_company_graph/
├── __init__.py # 导出 search_company_recruitment
├── state.py # SearchState TypedDict
├── prompts.py # LLM 提示词模板
├── nodes.py # 4 个节点实现
├── graph.py # LangGraph 流程定义
└── main.py # 入口函数
```
---
### 2. page_analysis_graph - 岗位列表分析
**目的**: 分析招聘列表页,找到可点击进入岗位详情的元素 CSS 选择器
**流程**: 获取HTML → LLM找列表区域 → LLM找可点击元素 → 点击验证能否进入详情
**选择器优先级**: 岗位名称链接 > 申请/查看按钮 > 详情图标 > 整个岗位卡片
**输入/输出**:
```python
# 输入
url: str # 招聘列表页URL
headless: bool # 是否无头模式
# 输出 (成功)
{
"status": "success",
"selector": ".job-list a.title", # 可点击元素选择器
"item_count": 20, # 匹配到的岗位数
"change_type": "redirect" # 点击后的变化类型
}
# change_type: redirect(跳转) / new_tab(新标签) / in_page(页内变化)
# 输出 (失败)
{
"status": "failed",
"reason": "未找到招聘区域", # 失败原因
"tried_selectors": ["...", ...] # 尝试过的选择器
}
# 特殊情况: item_count=0 时标记为失败,不触发下一步
```
---
### 3. next_page_graph - 分页分析
**目的**: 找到「下一页」按钮的 CSS 选择器,用于翻页爬取
**流程**: 获取HTML → LLM找分页区域 → LLM找下一页按钮 → 点击验证页面变化
**输入/输出**:
```python
# 输入
url: str # 招聘列表页URL
headless: bool
# 输出 (成功 - 有分页)
{
"status": "success",
"selector": ".pagination .next", # 下一页按钮选择器
"change_type": "url_change", # 点击后的变化类型
"has_pagination": 1 # 有分页
}
# 输出 (成功 - 无分页)
{
"status": "success",
"selector": null,
"change_type": null,
"has_pagination": 0 # 无分页,一页展示完
}
# change_type: url_change(URL变化) / content_change(内容变化) / new_tab
# 输出 (失败)
{
"status": "failed",
"reason": "点击后无变化",
"tried_selectors": ["...", ...]
}
```
---
### 4. detail_analysis_graph - 详情页分析
**目的**: 从列表进入详情页,提取岗位各字段的 CSS 选择器
**流程**:
```
open_list_page → click_first_job → find_detail_area(仅in_page) → extract_field_selectors → validate_data
```
**字段提取原则**:
- `job_title``description` 是核心字段,必须提取
- `description` 包含完整岗位信息(职责、要求、公司介绍等都放这里)
- 其他字段(salary/location/company/experience/education)只有在页面上有**独立、明确的元素**时才提取,否则为 null
**输入/输出**:
```python
# 输入
url: str # 招聘列表页URL
job_item_selector: str # 来自 page_analysis_graph
change_type: str # 来自 page_analysis_graph (redirect/new_tab/in_page)
headless: bool
# 输出 (成功)
{
"status": "success",
"detail_area_selector": ".job-detail", # 详情区域选择器(仅in_page有)
"fields": {
"job_title": {"selector": "h1.title", "sample": "Python工程师"},
"description": {"selector": [".desc", ".req"], "sample": "负责...\n要求..."},
"salary": {"selector": ".salary", "sample": "25-40K"}, # 或 null
"location": {"selector": ".loc", "sample": "北京"}, # 或 null
"company": {"selector": ".company", "sample": "XX公司"}, # 或 null
"experience": {"selector": ".exp", "sample": "3-5年"}, # 或 null
"education": {"selector": ".edu", "sample": "本科"} # 或 null
}
}
```
**支持字段**: job_title, description, salary, location, company, experience, education, detail_url
```python
# 输出 (失败)
{
"status": "failed",
"error": "验证失败,无法提取有效字段" # 失败原因
}
```
---
### 5. crawler - 数据爬取 (待开发)
**目的**: 使用分析得到的选择器配置,自动爬取所有岗位数据
**预期流程**:
1. 打开列表页
2. 使用 job_item_selector 获取当前页所有岗位
3. 逐个点击进入详情页,用 field_selectors 提取数据
4. 使用 next_page_selector 翻页
5. 重复直到无下一页
**预期输入/输出**:
```python
# 输入
config: {
"url": "https://...",
"job_item_selector": "...",
"next_page_selector": "...",
"change_type": "...",
"field_selectors": {...}
}
# 输出
[
{"job_title": "...", "salary": "...", "location": "...", ...},
{"job_title": "...", "salary": "...", "location": "...", ...},
...
]
```
---
## 技术栈
- **LangGraph**: AI Agent 工作流编排
- **Playwright**: 浏览器自动化
- **LangChain + Pydantic**: LLM 调用与结构化输出
- **doubao-1-5-pro-32k**: 主力 LLM 模型
---
## 开发状态
| 模块 | 状态 | 说明 |
|-----------------------|------|------------|
| search_company | ✅ 已完成 | 基于MCP的搜索方案 |
| page_analysis_graph | ✅ 已完成 | 岗位选择器提取 |
| next_page_graph | ✅ 已完成 | 分页选择器提取 |
| detail_analysis_graph | ✅ 已完成 | 详情字段选择器提取 |
| crawler | ✅ 已完成 | 数据爬取模块 |
| company_generator | ✅ 已完成 | AI生成公司名 |
| company_importer | ✅ 已完成 | Excel表格批量导入公司 |
---
### 7. company_importer - Excel 公司名单批量导入
**目的**: 从 Excel 表格批量导入公司名称及已知招聘地址,自动创建爬虫任务
**模块位置**: `src/company_importer/`
**核心逻辑**:
1. 读取 Excel(支持超链接提取真实 URL)
2. URL 验证与清洗(过滤邮箱、微信公众号、无效地址)
3. 内存去重 + 数据库唯一约束兜底
4. 逐行插入 `app_crawl_task` + `app_task_search`(带 `input_url`
**URL 过滤规则**:
- 邮箱地址(含 `@`)→ 跳过
- 微信公众号(`mp.weixin.qq.com`)→ 跳过
- 无协议头 → 自动补 `https://`
- 无域名或域名无点 → 无效
**输入/输出**:
```python
from src.company_importer import import_companies
# 输入
result = import_companies(
file_path="xxx.xlsx", # Excel 文件路径
company_col=3, # 公司名所在列(从1开始,如 C列=3)
url_col=9, # 招聘地址所在列(如 I列=9
)
# 输出
{
"total_rows": 100,
"inserted_count": 60,
"skipped_empty_name": 5,
"skipped_empty_url": 10,
"skipped_email": 3,
"skipped_weixin": 2,
"skipped_invalid_url": 5,
"skipped_duplicate": 15,
"inserted_companies": ["公司A", "公司B", ...]
}
```
**与 Step1 的联动**: 导入时将已知 URL 写入 `app_task_search.input_url`Step1 执行时检测到 `input_url` 非空,跳过搜索直接进入验证流程。
**文件结构**:
```
src/company_importer/
├── __init__.py # 导出 import_companies
├── importer.py # 导入核心逻辑
├── url_validator.py # URL 提取、验证、清洗
└── __main__.py # 测试入口 (python -m src.company_importer)
```
---
## 数据库表结构
### 主表:app_crawl_task(爬虫任务主表)
```sql
CREATE TABLE `app_crawl_task`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`company_name` VARCHAR(255) NOT NULL COMMENT '公司名称',
-- 配置阶段(前4步)
`config_step` INT NULL DEFAULT 1 COMMENT '【配置阶段】当前步骤: 1=搜索招聘页, 2=列表分析, 3=分页分析, 4=详情分析',
`config_status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '【配置阶段】状态: pending=待执行, running=执行中, success=成功, failed=失败',
-- 爬取阶段(第5步)
`crawl_status` VARCHAR(32) DEFAULT NULL COMMENT '【爬取阶段】状态: pending=待执行, running=执行中, success=成功, failed=失败',
`total_crawl_times` INT NOT NULL DEFAULT 0 COMMENT '【爬取阶段】累计爬取次数',
`last_crawl_at` DATETIME DEFAULT NULL COMMENT '【爬取阶段】上次爬取时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE INDEX `uk_company_name` (`company_name`),
INDEX `idx_config_status` (`config_status`),
INDEX `idx_crawl_status` (`crawl_status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='爬虫任务主表';
-- 业务规则:
-- 1. 项目入口表,创建时检查 company_name 唯一索引,防止重复
-- 2. 状态初始为 pending(待执行),保存后禁止任何编辑
-- 3. 创建成功后,自动在 app_task_search 表创建一条关联任务
-- 4. 其他状态更新同步至本表
-- 5. job_periodic_crawl定时任务检查上次 crawl_status = success 且 last_crawl_at 大于15天, 更新crawl_status 为 pending,并创建app_task_crawl数据
```
### Step 1app_task_search(搜索招聘页面)
```sql
CREATE TABLE `app_task_search`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`crawl_task_id` BIGINT NOT NULL COMMENT '关联主表ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending=待执行, running=执行中, success=成功, failed=失败',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '已重试次数',
`max_retry` INT NOT NULL DEFAULT 3 COMMENT '最大重试次数',
`input_company_name` VARCHAR(255) NOT NULL COMMENT '【输入】公司名称',
`input_url` VARCHAR(1024) DEFAULT NULL COMMENT '【输入】已知招聘地址(表格导入时填入,有值时Step1跳过搜索直接验证)',
`output_url` VARCHAR(512) DEFAULT NULL COMMENT '【输出】招聘页URL',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`started_at` DATETIME DEFAULT NULL COMMENT '任务开始执行时间',
`finished_at` DATETIME DEFAULT NULL COMMENT '任务完成时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_crawl_task_id` (`crawl_task_id`),
INDEX `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Step1-搜索招聘页面任务表';
-- 业务规则:
-- 1. app_crawl_task新建数据成功时默认创建 input_company_name 来自主表
-- 2. 若由 company_importer 导入,input_url 存储已知招聘地址
-- 3. 定时任务扫描 status='pending' 的记录执行搜索,修改app_crawl_task 的 config_step=1, config_status='running'
-- 4. input_url 非空时,跳过搜索引擎搜索,直接将 input_url 作为候选链接验证
-- 5. 执行成功后 status='success'output_url 存储搜索到的招聘页URL
-- 6. 执行失败 retry_count+1,达到 max_retry 后 status='failed',修改app_crawl_task 的 config_status='failed'
-- 7. 成功后自动创建 app_task_page_analysis 任务
```
### Step 2app_task_page_analysis(岗位列表分析)
```sql
CREATE TABLE `app_task_page_analysis`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`crawl_task_id` BIGINT NOT NULL COMMENT '关联主表ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending=待执行, running=执行中, success=成功, failed=失败',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '已重试次数',
`max_retry` INT NOT NULL DEFAULT 3 COMMENT '最大重试次数',
`input_url` VARCHAR(1024) NOT NULL COMMENT '【输入】招聘页URL',
`output_selector` VARCHAR(512) DEFAULT NULL COMMENT '【输出】岗位项CSS选择器',
`output_change_type` VARCHAR(32) DEFAULT NULL COMMENT '【输出】点击变化类型: redirect=跳转, new_tab=新标签, in_page=页内变化',
`output_item_count` INT DEFAULT NULL COMMENT '【输出】匹配到的岗位数量',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`started_at` DATETIME DEFAULT NULL COMMENT '任务开始执行时间',
`finished_at` DATETIME DEFAULT NULL COMMENT '任务完成时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_crawl_task_id` (`crawl_task_id`),
INDEX `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Step2-岗位列表分析任务表';
-- 业务规则:
-- 1. 由 Step1 成功后自动创建,input_url 来自 app_task_search.output_url
-- 2. 定时任务扫描 status='pending' 的记录执行列表页分析,修改 app_crawl_task.config_step=2
-- 3. 执行成功后 status='success',输出岗位选择器、点击变化类型、匹配数量 app_crawl_task.config_status=success
-- 4. 执行失败 retry_count+1,达到 max_retry 后 status='failed',修改 app_crawl_task.config_status='failed'
-- 5. 成功后自动创建 app_task_next_page 任务(Step3
```
### Step 3app_task_next_page(分页分析)
```sql
CREATE TABLE `app_task_next_page`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`crawl_task_id` BIGINT NOT NULL COMMENT '关联主表ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending=待执行, running=执行中, success=成功, failed=失败',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '已重试次数',
`max_retry` INT NOT NULL DEFAULT 3 COMMENT '最大重试次数',
`input_url` VARCHAR(1024) NOT NULL COMMENT '【输入】招聘页URL',
`output_selector` VARCHAR(512) DEFAULT NULL COMMENT '【输出】下一页按钮选择器',
`output_change_type` VARCHAR(32) DEFAULT NULL COMMENT '【输出】翻页变化类型: url_change=URL变化, content_change=内容变化, new_tab=新页面',
`has_pagination` TINYINT(1) DEFAULT NULL COMMENT '是否有分页: 0=仅一页, 1=有分页',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`started_at` DATETIME DEFAULT NULL COMMENT '任务开始执行时间',
`finished_at` DATETIME DEFAULT NULL COMMENT '任务完成时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_crawl_task_id` (`crawl_task_id`),
INDEX `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Step3-分页分析任务表';
-- 业务规则:
-- 1. 由 Step2 成功后自动创建,input_url 来自 app_task_page_analysis.input_url
-- 2. 定时任务扫描 status='pending' 的记录执行分页分析,修改 app_crawl_task.config_step=3
-- 3. 执行成功后 status='success',输出下一页选择器、翻页变化类型、是否有分页
-- 4. 执行失败 retry_count+1,达到 max_retry 后 status='failed',修改 app_crawl_task.config_status='failed'
-- 5. 成功后自动创建 app_task_detail_analysis 任务(Step4
```
### Step 4app_task_detail_analysis(详情页分析)
```sql
CREATE TABLE `app_task_detail_analysis`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`crawl_task_id` BIGINT NOT NULL COMMENT '关联主表ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending=待执行, running=执行中, success=成功, failed=失败',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '已重试次数',
`max_retry` INT NOT NULL DEFAULT 3 COMMENT '最大重试次数',
`input_url` VARCHAR(1024) NOT NULL COMMENT '【输入】招聘页URL',
`input_job_selector` VARCHAR(512) NOT NULL COMMENT '【输入】岗位项选择器(来自Step2)',
`input_change_type` VARCHAR(32) NOT NULL COMMENT '【输入】点击变化类型(来自Step2): redirect=跳转, new_tab=新标签, in_page=页内变化',
`output_detail_selector` VARCHAR(512) DEFAULT NULL COMMENT '【输出】详情区域选择器(仅in_page时有值)',
`output_fields` JSON DEFAULT NULL COMMENT '【输出】字段选择器配置JSON, 结构: {"字段名": {"selector": "CSS选择器" 或 ["选择器1","选择器2"], "sample": "示例值"} | null}, 字段: job_title=职位名称, description=岗位描述(数组), salary=薪资, location=地点, company=公司, experience=经验, education=学历',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`started_at` DATETIME DEFAULT NULL COMMENT '任务开始执行时间',
`finished_at` DATETIME DEFAULT NULL COMMENT '任务完成时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_crawl_task_id` (`crawl_task_id`),
INDEX `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Step4-详情页分析任务表';
-- 业务规则:
-- 1. 由 Step3 成功后自动创建,input_url/input_job_selector/input_change_type 来自 Step2/Step3
-- 2. 定时任务扫描 status='pending' 的记录执行详情页分析,修改 app_crawl_task.config_step=4
-- 3. 执行成功后 status='success',输出详情区域选择器、字段选择器配置
-- 4. 执行失败 retry_count+1,达到 max_retry 后 status='failed',修改 app_crawl_task.config_status='failed'
-- 5. 成功后修改 app_crawl_task.config_status='success',自动创建 app_task_crawl 任务(Step5
```
### Step 5app_task_crawl(数据爬取)
```sql
CREATE TABLE `app_task_crawl`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`crawl_task_id` BIGINT NOT NULL COMMENT '关联主表ID',
`status` VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending=待执行, running=执行中, success=成功, failed=失败',
`retry_count` INT NOT NULL DEFAULT 0 COMMENT '已重试次数',
`max_retry` INT NOT NULL DEFAULT 3 COMMENT '最大重试次数',
`input_config` JSON NOT NULL COMMENT '【输入】完整爬取配置JSON, 包含: url=招聘页URL, job_item_selector=岗位项选择器, job_change_type=点击变化类型, next_page_selector=下一页选择器, next_change_type=翻页变化类型, detail_area_selector=详情区域选择器, fields=字段选择器配置',
`crawled_count` INT DEFAULT NULL COMMENT '【输出】本次爬取数量',
`error_message` TEXT DEFAULT NULL COMMENT '错误信息',
`started_at` DATETIME DEFAULT NULL COMMENT '任务开始执行时间',
`finished_at` DATETIME DEFAULT NULL COMMENT '任务完成时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_crawl_task_id` (`crawl_task_id`),
INDEX `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Step5-数据爬取任务表';
-- 业务规则:
-- 1. 由 Step4 成功后自动创建 / 或者job_periodic_crawl定时任务创建,input_config 汇总 Step1-4 的所有输出配置
-- 2. 定时任务扫描 status='pending' 的记录执行数据爬取,修改 app_crawl_task.crawl_status='running'
-- 3. 执行成功后 status='success',爬取的岗位数据存入 app_job_data 表
-- 4. 执行失败 retry_count+1,达到 max_retry 后 status='failed',修改 app_crawl_task.crawl_status='failed'
-- 5. 成功后修改 app_crawl_task: crawl_status='success', total_crawl_times+1, last_crawl_at=当前时间
-- 6. 周期任务:当 last_crawl_at 超过15天时,自动创建新的爬取任务
```
### 岗位数据表:app_job_data
```sql
CREATE TABLE `app_job_data`
(
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`task_crawl_id` BIGINT NOT NULL COMMENT '关联爬取任务ID',
`job_title` VARCHAR(255) DEFAULT NULL COMMENT '职位名称',
`salary` VARCHAR(128) DEFAULT NULL COMMENT '薪资',
`location` VARCHAR(128) DEFAULT NULL COMMENT '工作地点',
`company` VARCHAR(255) DEFAULT NULL COMMENT '公司名称',
`experience` VARCHAR(64) DEFAULT NULL COMMENT '经验要求',
`education` VARCHAR(64) DEFAULT NULL COMMENT '学历要求',
`description` TEXT DEFAULT NULL COMMENT '岗位详情(职责+要求+介绍)',
`detail_url` VARCHAR(1024) DEFAULT NULL COMMENT '详情页URL',
`content_hash` VARCHAR(64) NOT NULL COMMENT '内容哈希值: job_title+salary+location+company+experience+education+description+detail_url 的MD5,用于查重',
`sources` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '数据来源: 0=官网, 1=平台',
`is_independent_url` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否独立URL: 0=页内展示, 1=独立页面',
`is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效: 0=无效, 1=有效',
`expire_at` DATETIME DEFAULT NULL COMMENT '有效期',
`check_status` VARCHAR(32) DEFAULT 'pending' COMMENT '验证状态: pending=待验证, checking=验证中, checked=已验证',
`last_check_at` DATETIME DEFAULT NULL COMMENT '上次验证时间',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
INDEX `idx_task_crawl_id` (`task_crawl_id`),
INDEX `idx_content_hash` (`content_hash`),
INDEX `idx_job_title` (`job_title`),
INDEX `idx_is_valid` (`is_valid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='岗位数据表';
-- 业务规则:
-- 1. 由 Step5 爬取成功后批量创建,每条岗位数据关联到 task_crawl_id
-- 2. 插入前查询:相同 content_hash 且 is_valid=1 的记录存在则跳过,否则插入
-- 3. is_independent_url 根据 Step2 的 change_type 决定:redirect/new_tab=1, in_page=0
-- 4. 定时任务检查有效性:expire_at 已过期 → is_valid=0
-- 5. 定时任务检查有效性:访问 detail_url 返回404 → is_valid=0
-- 6. 查询时默认过滤 is_valid=1 的有效数据
```
---
## 定时任务设计
### 任务总览
| 任务名 | 频率 | 并发 | 说明 |
|--------|------|------|------|
| job_step1_search | 1分钟 | 串行 | 搜索招聘页面 |
| job_step2_page | 1分钟 | 串行 | 分析岗位列表 |
| job_step3_next | 1分钟 | 串行 | 分析分页 |
| job_step4_detail | 1分钟 | 串行 | 分析详情页 |
| job_step5_crawl | 1分钟 | 串行 | 数据爬取 |
| job_periodic_crawl | 10分钟 | 串行 | 周期爬取 |
| job_check_validity | 1分钟 | 按域名并发 | 有效性检查 |
| job_generate_company | 1天 | 单实例 | AI生成公司名 |
---
### job_step1_search(搜索招聘页面)
```
1. 查询 WHERE status='pending' LIMIT 1
2. 若无记录 → 结束
3. 更新 status='running', started_at=NOW()
4. 调用 search_company_graph 执行搜索
- 若 input_url 非空:将 input_url 作为 candidate_url 传入,跳过搜索直接验证
- 若 input_url 为空:正常执行搜索引擎搜索流程
5. 成功:
- 更新 status='success', output_url=结果URL, finished_at=NOW()
- 更新 app_crawl_task: config_status='running', config_step=1
- 创建 app_task_page_analysis 记录 (input_url=output_url)
6. 失败:
- retry_count += 1, error_message=错误信息, finished_at=NOW()
- 若 retry_count >= max_retry:
- status='failed'
- app_crawl_task.config_status='failed'
- 否则: status='pending' (下次继续重试)
异常处理: status='running'卡住的任务需手动重置为'pending'
```
---
### job_step2_page(岗位列表分析)
```
1. 查询 WHERE status='pending' LIMIT 1
2. 若无记录 → 结束
3. 更新 status='running', started_at=NOW()
4. 调用 page_analysis_graph(input_url)
5. 成功:
- 更新 status='success', finished_at=NOW()
- 保存 output_selector, output_change_type, output_item_count
- 更新 app_crawl_task: config_step=2
- 创建 app_task_next_page 记录 (input_url 来自当前任务)
6. 失败:
- retry_count += 1, error_message=错误信息, finished_at=NOW()
- 若 retry_count >= max_retry:
- status='failed'
- app_crawl_task.config_status='failed'
- 否则: status='pending'
异常处理: status='running'卡住的任务需手动重置为'pending'
```
---
### job_step3_next(分页分析)
```
1. 查询 WHERE status='pending' LIMIT 1
2. 若无记录 → 结束
3. 更新 status='running', started_at=NOW()
4. 调用 next_page_graph(input_url)
5. 成功:
- 更新 status='success', finished_at=NOW()
- 保存 output_selector, output_change_type, has_pagination
- 更新 app_crawl_task: config_step=3
- 通过 crawl_task_id 查询 Step2 输出
- 创建 app_task_detail_analysis 记录:
- input_url 来自 Step2
- input_job_selector 来自 Step2.output_selector
- input_change_type 来自 Step2.output_change_type
6. 失败:
- retry_count += 1, error_message=错误信息, finished_at=NOW()
- 若 retry_count >= max_retry:
- status='failed'
- app_crawl_task.config_status='failed'
- 否则: status='pending'
异常处理: status='running'卡住的任务需手动重置为'pending'
```
---
### job_step4_detail(详情页分析)
```
1. 查询 WHERE status='pending' LIMIT 1
2. 若无记录 → 结束
3. 更新 status='running', started_at=NOW()
4. 调用 detail_analysis_graph(input_url, input_job_selector, input_change_type)
5. 成功:
- 更新 status='success', finished_at=NOW()
- 保存 output_detail_selector, output_fields
- 更新 app_crawl_task: config_step=4, config_status='success'
- 通过 crawl_task_id 查询 Step1-4 输出,汇总 input_config:
{
url, job_item_selector, job_change_type,
next_page_selector, next_change_type, has_pagination,
detail_area_selector, fields
}
- 创建 app_task_crawl 记录
- 更新 app_crawl_task: crawl_status='pending'
6. 失败:
- retry_count += 1, error_message=错误信息, finished_at=NOW()
- 若 retry_count >= max_retry:
- status='failed'
- app_crawl_task.config_status='failed'
- 否则: status='pending'
异常处理: status='running'卡住的任务需手动重置为'pending'
```
---
### job_step5_crawl(数据爬取)
```
1. 查询 WHERE status='pending' LIMIT 1
2. 若无记录 → 结束
3. 更新 status='running', started_at=NOW()
4. 更新 app_crawl_task: crawl_status='running'
5. 调用 crawler(input_config)
6. 成功:
- 更新 status='success', crawled_count=爬取数量, finished_at=NOW()
- 批量插入 app_job_data:
- 插入前查询: 相同 content_hash 且 is_valid=1 的记录存在则跳过
- 不存在则插入, expire_at=NOW()+15天
- 更新 app_crawl_task:
- crawl_status='success'
- total_crawl_times += 1
- last_crawl_at = NOW()
7. 失败:
- retry_count += 1, error_message=错误信息, finished_at=NOW()
- 若 retry_count >= max_retry:
- status='failed'
- app_crawl_task.crawl_status='failed'
- 否则: status='pending' (主表 crawl_status 保持 running)
异常处理: status='running'卡住的任务需手动重置为'pending'
```
---
### job_periodic_crawl(周期爬取)
```
1. 查询 app_crawl_task WHERE
crawl_status='success'
AND last_crawl_at < DATE_SUB(NOW(), INTERVAL 15 DAY)
2. 遍历每条记录:
- 更新 crawl_status='pending'
- 通过 crawl_task_id 查询 Step1-4 的输出,汇总 input_config
- 创建 app_task_crawl 记录
```
---
### job_check_validity(有效性检查)
```
1. 两次查询合并(避免OR影响索引):
a. 正常待验证: WHERE is_valid=1 AND check_status='pending' AND expire_at <= NOW() LIMIT 20
b. 超时恢复: WHERE is_valid=1 AND check_status='checking' AND last_check_at < NOW() - 2小时 LIMIT 20
代码层合并结果取前 20 条
2. 若无记录 → 结束
3. 批量更新 check_status='checking', last_check_at=NOW()
4. 分流处理:
A. is_independent_url=0 (页内展示):
- 直接过期: is_valid=0
- 更新 check_status='pending'
B. is_independent_url=1 (独立页面):
- 按 detail_url 域名分组
- 不同域名并发,同域名串行验证
- GET 访问 detail_url:
- 状态码 200 → expire_at = NOW() + 配置天数
- 其他(超时/404/非200等) → is_valid=0
- 每条完成后更新 check_status='pending'
```
---
### job_generate_companyAI生成公司名)
**目的**: 使用 AI 自动生成可能有官网招聘信息的公司名称,自动创建爬取任务
**模块位置**: `src/company_generator/`
**配置参数**:
- `max_company_count`: 公司总数上限,默认 5000
- `generate_company_count`: 每次生成数量,默认 10
- `job_generate_company_interval`: 执行间隔,默认 86400秒(1天)
**执行流程**:
```
1. 检查公司总数
SELECT COUNT(*) FROM app_crawl_task
若 >= max_company_count(5000) → 结束
2. 查询所有已有公司名 → 存入内存 set
3. 随机抽样 500 个传给 LLM
- 使用 V3_2 模型
- with_structured_output(CompanyList) 结构化输出
- 生成 10 个公司名
4. 遍历生成结果
- 长度校验(2-15字符)→ 不符则跳过
- 内存 set 判重 → 已存在则跳过
- INSERT app_crawl_task (company_name)
- INSERT app_task_search (crawl_task_id, input_company_name)
- 数据库唯一约束兆底
5. 返回结果
{ inserted_count, skipped_count, inserted_companies }
```
**公司名命名规范**:
- 使用公司常用简称(如"华为"而非"华为技术有限公司")
- 不加"集团"、"有限公司"、"股份有限公司"等后缀
- 不加"(中国)"、"(北京)"等地域标注
- 2-15个字符
**去重策略**:
1. Prompt 传递已有公司名(随机抽样 500 个)
2. 代码层内存 set 判重(全量)
3. 数据库唯一约束兆底
---
### 任务执行流程图
```
┌─────────────────┐
│ 用户创建任务 │
│ (输入公司名称) │
└────────┬────────┘
┌────────────────────────────────────────────────────────────────┐
│ job_step1_search (每1分钟) │
│ 查询: app_task_search WHERE status='pending' │
│ 执行: 搜索招聘页面URL │
│ 成功: status='success', 创建Step2任务 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ job_step2_page (每1分钟) │
│ 查询: app_task_page_analysis WHERE status='pending' │
│ 执行: 分析岗位列表选择器 │
│ 成功: status='success', 创建Step3任务 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ job_step3_next (每1分钟) │
│ 查询: app_task_next_page WHERE status='pending' │
│ 执行: 分析分页选择器 │
│ 成功: status='success', 创建Step4任务 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ job_step4_detail (每1分钟) │
│ 查询: app_task_detail_analysis WHERE status='pending' │
│ 执行: 分析详情页字段选择器 │
│ 成功: config_status='success', 创建Step5任务 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ job_step5_crawl (每1分钟) │
│ 查询: app_task_crawl WHERE status='pending' │
│ 执行: 爬取岗位数据,存入app_job_data │
│ 成功: crawl_status='success', total_crawl_times+1 │
└────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ 爬取完成 │
└────────┬────────┘
┌──────────────────┴──────────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ job_periodic_crawl │ │ job_check_validity │
│ (每10分钟) │ │ (每1分钟) │
│ 检查last_crawl_at │ │ 检查expire_at已过期 │
│ 超过N天则重新爬取 │ │ 按域名并发验证URL │
└──────────────────────┘ └──────────────────────┘
```
-356
View File
@@ -1,356 +0,0 @@
# Crawler 模块设计方案
## 状态
✅ 已完成
---
## 一、输入参数
| 参数 | 来源 | 说明 |
|-----|------|-----|
| url | 初始输入 | 列表页 URL |
| job_item_selector | Step 2 | 岗位项选择器 |
| item_change_type | Step 2 | redirect / new_tab / in_page |
| next_page_selector | Step 3 | 下一页按钮选择器(None = 无分页) |
| page_change_type | Step 3 | url_change / content_change / new_tab |
| field_selectors | Step 4 | 字段选择器字典,selector 为数组格式 |
| detail_area_selector | Step 4 | 详情区域选择器(仅 in_page 有值) |
---
## 二、限制条件
- 最大页数:5 页
- 单个岗位失败:跳过继续
- 超时时间:可配置(如 10 秒)
---
## 三、数据提取范围
| item_change_type | 提取范围 | detail_url 记录 |
|-----------------|---------|---------------|
| redirect | 跳转后的详情页整页 | 详情页 URL |
| new_tab | 新标签详情页整页 | 新标签页 URL |
| in_page | detail_area_selector 内部 | 列表页 URL |
---
## 四、入口逻辑
```
results = []
IF item_change_type == "redirect":
results = 流程A_redirect()
ELSE IF item_change_type == "new_tab":
results = 流程B_new_tab()
ELSE IF item_change_type == "in_page":
results = 流程C_in_page()
RETURN results
```
---
## 五、流程 Aredirect
**特点**:点击岗位后整页跳转,返回后状态丢失,需重新打开并翻页恢复
```
初始化:
page_index = 1
item_index = 1
results = []
打开 url
等待加载完成
items_per_page = 用 job_item_selector 计算当前页岗位数
主循环:
WHILE True:
# ===== 1. 检查是否结束 =====
IF items_per_page == 0:
BREAK
IF page_index > 5:
BREAK
# ===== 2. 处理当前岗位 =====
TRY:
elements = 获取所有岗位元素(job_item_selector)
点击 elements[item_index - 1]
等待页面跳转完成(URL 变化 或 networkidle
data = 在整页范围用 field_selectors 提取数据
data["detail_url"] = 当前页面 URL
results.append(data)
CATCH:
记录失败,跳过
# ===== 3. 计算下一个位置 =====
item_index += 1
IF item_index > items_per_page:
page_index += 1
item_index = 1
IF page_index > 5:
BREAK
IF next_page_selector == None:
BREAK
# ===== 4. 重新打开并恢复到目标页 =====
goto(url)
等待加载完成
FOR i = 1 TO (page_index - 1):
success, page = click_next_page(page)
IF not success:
BREAK 主循环
items_per_page = 重新计算当前页岗位数
RETURN results
```
---
## 六、流程 Bnew_tab
**特点**:点击后新标签打开详情,关闭新标签后原页面状态保持
```
初始化:
page_index = 1
results = []
打开 url
等待加载完成
主循环:
WHILE page_index <= 5:
# ===== 1. 获取当前页岗位 =====
items_per_page = 用 job_item_selector 计算当前页岗位数
IF items_per_page == 0:
BREAK
# ===== 2. 遍历当前页所有岗位 =====
FOR item_index = 1 TO items_per_page:
TRY:
elements = 获取所有岗位元素(job_item_selector)
开始监听 context 的 "page" 事件
点击 elements[item_index - 1]
等待新标签页打开(超时则跳过)
new_page = 获取新打开的标签页
等待 new_page 加载完成
data = 在 new_page 整页范围用 field_selectors 提取数据
data["detail_url"] = new_page.url
results.append(data)
关闭 new_page
CATCH:
尝试关闭可能存在的新标签
记录失败,跳过
# ===== 3. 翻页 =====
IF next_page_selector == None:
BREAK
success, page = click_next_page(page)
IF not success:
BREAK
page_index += 1
RETURN results
```
---
## 七、流程 Cin_page
**特点**:点击后弹窗/详情区展示,通过刷新页面恢复状态,兼容性更强
```
初始化:
page_index = 1
item_index = 1
results = []
打开 url
等待加载完成
items_per_page = 用 job_item_selector 计算当前页岗位数
主循环:
WHILE True:
# ===== 1. 检查是否结束 =====
IF items_per_page == 0:
BREAK
IF page_index > 5:
BREAK
# ===== 2. 处理当前岗位 =====
TRY:
elements = 获取所有岗位元素(job_item_selector)
点击 elements[item_index - 1]
等待 detail_area_selector 出现(visible
detail_element = 获取 detail_area_selector 元素
data = 在 detail_element 内部用 field_selectors 提取数据
data["detail_url"] = 当前页面 URL
results.append(data)
CATCH:
记录失败,跳过
# ===== 3. 计算下一个位置 =====
item_index += 1
IF item_index > items_per_page:
page_index += 1
item_index = 1
IF page_index > 5:
BREAK
IF next_page_selector == None:
BREAK
# ===== 4. 刷新页面恢复状态 =====
goto(url)
等待加载完成
FOR i = 1 TO (page_index - 1):
success, page = click_next_page(page)
IF not success:
BREAK 主循环
items_per_page = 重新计算当前页岗位数
RETURN results
```
---
## 八、统一翻页函数
**返回值**(success: bool, page: Page) —— new_tab 模式时 page 引用会变
```
函数 click_next_page(page, next_page_selector, page_change_type):
# ===== 1. 检查按钮是否可点 =====
element = 查找 next_page_selector
IF element 不存在:
RETURN (false, page)
IF element 有 disabled 属性:
RETURN (false, page)
IF element 的 class 包含 "disabled":
RETURN (false, page)
IF element 不可见 (is_visible == false):
RETURN (false, page)
# ===== 2. 根据 page_change_type 处理 =====
IF page_change_type == "url_change":
before_url = page.url
点击 element
等待 URL 变化(page.url != before_url
等待加载完成(networkidle
RETURN (true, page)
ELSE IF page_change_type == "content_change":
before_text = 获取第一个岗位的文本内容
点击 element
等待第一个岗位文本变化(!= before_text
短暂等待确保渲染完成
RETURN (true, page)
ELSE IF page_change_type == "new_tab":
开始监听 context 的 "page" 事件
点击 element
等待新标签页打开
new_page = 获取新标签页
等待 new_page 加载完成
关闭原 page
RETURN (true, new_page) # 返回新的 page 引用
```
---
## 九、数据提取函数
```
函数 extract_data(scope, field_selectors):
# scope: 整个 page 或 detail_element
data = {}
FOR field_name, selector_info IN field_selectors:
TRY:
selectors = selector_info.selector # 数组格式
IF selectors 为空数组:
data[field_name] = None
CONTINUE
# 遍历所有选择器,提取文本并拼接
texts = []
FOR selector IN selectors:
element = scope.query_selector(selector)
IF element:
text = element.inner_text().strip()
IF text:
texts.append(text)
data[field_name] = "\n".join(texts) IF texts ELSE None
CATCH:
data[field_name] = None
RETURN data
```
---
## 十、字段选择器格式
`field_selectors` 统一使用数组格式:
```
{
"job_title": {"selector": ["h1.title"], "sample": "Python工程师"},
"description": {"selector": [".desc", ".req"], "sample": "负责...\n要求..."},
"salary": {"selector": [".salary"], "sample": "25-40K"},
...
}
```
- 单选择器:`["h1.title"]`
- 多选择器:`[".desc", ".req"]`,提取结果用 `\n` 拼接
---
## 十一、输出格式
```
[
{
"job_title": "...",
"salary": "...",
"location": "...",
"description": "...",
"requirements": "...",
"detail_url": "...",
...
},
...
]
```
-307
View File
@@ -1,307 +0,0 @@
# Playwright Python 使用指南
本文档覆盖项目中会用到的 Playwright 核心功能。
## 安装
```bash
pip install playwright
playwright install chromium # 安装浏览器
```
## 基本结构
```python
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
# 启动浏览器
browser = await p.chromium.launch(headless=False) # False 可看到浏览器界面
# 创建页面
page = await browser.new_page()
# 操作页面...
# 关闭
await browser.close()
```
## 核心操作
### 1. 导航
```python
# 访问 URL
await page.goto("https://example.com")
# 等待加载完成(可选策略)
await page.goto("https://example.com", wait_until="networkidle") # 网络空闲
await page.goto("https://example.com", wait_until="domcontentloaded") # DOM 加载完成
# 获取当前 URL
current_url = page.url
```
### 2. 获取内容
```python
# 获取整个页面 HTML
html = await page.content()
# 获取 body 内部 HTML
body_html = await page.inner_html("body")
# 获取元素内部 HTML
area_html = await page.inner_html(".job-list")
# 获取元素外部 HTML(包含自身标签)
outer = await page.evaluate("document.querySelector('.job-item').outerHTML")
# 获取文本内容
text = await page.inner_text(".title")
# 获取页面标题
title = await page.title()
```
### 3. 选择器与元素定位
```python
# 单个元素
element = await page.query_selector(".job-item") # 返回 ElementHandle 或 None
# 多个元素
elements = await page.query_selector_all(".job-item") # 返回列表
count = len(elements)
# 检查元素是否存在
if await page.query_selector(".job-item"):
print("存在")
# Locator API(推荐,更稳定)
locator = page.locator(".job-item")
count = await locator.count()
first = locator.first
nth = locator.nth(2) # 第3个元素
```
### 4. 点击与交互
```python
# 点击元素
await page.click(".job-item")
# 点击第一个匹配的元素
await page.locator(".job-item").first.click()
# 点击第 N 个元素
await page.locator(".job-item").nth(0).click()
# 带等待的点击
await page.click(".job-item", timeout=5000) # 最多等 5 秒
# 输入文本
await page.fill("input[name='search']", "关键词")
# 按键
await page.keyboard.press("Enter")
```
### 5. 等待
```python
import asyncio
# 简单等待(秒)
await asyncio.sleep(2)
# 等待选择器出现
await page.wait_for_selector(".job-list", timeout=10000)
# 等待选择器消失
await page.wait_for_selector(".loading", state="hidden")
# 等待导航完成
async with page.expect_navigation():
await page.click(".next-page")
# 等待网络空闲
await page.wait_for_load_state("networkidle")
```
### 6. 执行 JavaScript
```python
# 简单表达式
result = await page.evaluate("document.title")
# 带参数
selector = ".job-item"
count = await page.evaluate(f"document.querySelectorAll('{selector}').length")
# 复杂逻辑
result = await page.evaluate("""
() => {
const items = document.querySelectorAll('.job-item');
return Array.from(items).map(el => el.outerHTML);
}
""")
# 在元素上执行
element = await page.query_selector(".job-item")
html = await element.evaluate("el => el.outerHTML")
```
### 7. 截图
```python
# 整页截图
await page.screenshot(path="screenshot.png")
# 元素截图
element = await page.query_selector(".job-list")
await element.screenshot(path="element.png")
# 全页面(包括滚动区域)
await page.screenshot(path="full.png", full_page=True)
```
## 常用模式
### 模式1:获取多个元素的 HTML
```python
# 方法1evaluate
htmls = await page.evaluate("""
selector => {
const items = document.querySelectorAll(selector);
return Array.from(items).slice(0, 3).map(el => el.outerHTML);
}
""", ".job-item")
# 方法2:遍历 ElementHandle
elements = await page.query_selector_all(".job-item")
htmls = []
for el in elements[:3]:
html = await el.evaluate("el => el.outerHTML")
htmls.append(html)
```
### 模式2:检测页面变化
```python
before_url = page.url
await page.click(".job-item")
await asyncio.sleep(2)
after_url = page.url
if after_url != before_url:
print("发生了跳转")
```
### 模式3:带重试的选择器验证
```python
async def validate_selector(page, selector: str) -> int:
"""验证选择器,返回匹配数量"""
try:
elements = await page.query_selector_all(selector)
return len(elements)
except Exception:
return 0
```
### 模式4:安全获取元素内容
```python
async def safe_inner_html(page, selector: str) -> str | None:
"""安全获取元素 innerHTML"""
element = await page.query_selector(selector)
if element:
return await element.inner_html()
return None
```
## 浏览器配置
```python
# 有头模式(可见)
browser = await p.chromium.launch(headless=False)
# 无头模式(后台运行)
browser = await p.chromium.launch(headless=True)
# 慢动作(调试用)
browser = await p.chromium.launch(headless=False, slow_mo=500) # 每步慢 500ms
# 设置窗口大小
context = await browser.new_context(viewport={"width": 1280, "height": 720})
page = await context.new_page()
# 设置 User-Agent
context = await browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
```
## 错误处理
```python
from playwright.async_api import TimeoutError as PlaywrightTimeout
try:
await page.click(".not-exist", timeout=3000)
except PlaywrightTimeout:
print("元素未找到")
except Exception as e:
print(f"其他错误: {e}")
```
## 项目中的典型用法
```python
from playwright.async_api import async_playwright
async def analyze_page(url: str):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
try:
# 1. 访问页面
await page.goto(url, wait_until="networkidle")
# 2. 获取 HTML
html = await page.inner_html("body")
# 3. 验证选择器
selector = ".job-item"
elements = await page.query_selector_all(selector)
print(f"匹配到 {len(elements)} 个元素")
# 4. 点击验证
if elements:
before_url = page.url
await elements[0].click()
await asyncio.sleep(2)
after_url = page.url
print(f"跳转: {before_url} -> {after_url}")
finally:
await browser.close()
```
## 与 MCP 对比
| 操作 | MCP 方式 | 直接 Playwright |
|------|----------|-----------------|
| 导航 | `await call_tool(tools, "browser_navigate", url=url)` | `await page.goto(url)` |
| 获取 HTML | `await call_tool(tools, "browser_evaluate", function="document.body.innerHTML")` | `await page.inner_html("body")` |
| 点击 | `await call_tool(tools, "browser_evaluate", function="document.querySelector('.x').click()")` | `await page.click(".x")` |
| 获取 URL | `await call_tool(tools, "browser_evaluate", function="window.location.href")` | `page.url` |
直接用 Playwright 代码更简洁、更 Pythonic。
-729
View File
@@ -1,729 +0,0 @@
job_title,description,detail_url
[社会招聘] 三星SDSC IT售前支持,"岗位职责:
任职资格:
1. 根据客户情况提供合理的解决方案,
2. 项目的整体规划,日程管理,风险管理,品质管理,验收报告等,
3. 编写项目相关文档,确保项目资料的收集、整理、建档和保存,
4. 公司运营,采购,执行等相关部门的业务协调等。
1. 学历专业:正规院校本科及以上学历,双证齐全,专业不限;
2. 工作经验:
- 3~5年销售经验或者软件开发目管理经验
- 有大型项目参与经验者优先
3. 技术能力:
- CRM,SAP,RMS,WMS等相关系统项目管理经验
- 熟悉Java、C#等主流编程语言‌者优先
- 了解HTML、CSS、JavaScript,熟悉Vue、React等前端框架
- 了解TCP/IP、HTTP等网络协议,熟悉Socket编程
- 了解Python编程基础,熟悉Django、Flask等框架,了解MongoDB、Linux系统操作
- 了解服务器,网络设备等相关内容者优先
4. 综合素质:
- 了解韩国文化,理解韩国文化
- 为人正直,有责任心,积极主动,逻辑清晰,具备优秀沟通、宣讲及文案能力
- 具备良好的沟通能力和方案撰写能力,能够与客户和团队成员有效沟通‌
5.语言:无限制,如懂韩语优先
6.其他:取得PMP资格证优先,接受出差",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] 三星SDSC IT销售代表(韩语),"岗位职责:
任职资格:
1. 挖掘可购买公司产品及服务的企业客户与商机;
2. 挖掘可与公司开展业务合作的销售及交付合作伙伴;
3. ‌分析客户IT需求,基于公司与合作伙伴的产品及能力制定解决方案与业务提案;
4. 通过分析公司产品及能力,开发服务产品并提出销售方案等;
5.公司内部销售系统处理及管理: 订单录入,成本确认,合同处理,损益确认,计划录入等。
1. 正规院校本科及以上学历,双证齐全;
2. 工作经验:
- 拥有IT销售经验或在IT服务行业工作过经验;
- 具有云计算相关的销售或技术工作经验,特别是AWS相关经验者优先考虑;
3. 技术能力:
- 对最新的IT技术趋势的广泛理解
- 熟练使用MS Office软件(ExcelWordPPT
4. 语言要求:韩语精通(必须)
5.其他:接受短期出差",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
无线通信CUDA开发工程师,"岗位职责:
任职资格:
1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求;
2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案;
3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告;
1. 硕士及以上学历,计算机科学/通信等相关专业;
2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧;
3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力;
4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先;
5. 有基于GPU的算力利用率提升项目经验者优先;
6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
人形机器人全身运动控制算法工程师(强化学习方向),"岗位职责:
任职资格:
1. 负责基于强化学习的人形机器人全身运动控制算法研发,涵盖行走、跑跳、平衡控制、复杂地形适配、动态抗扰动、全身协同运动规划等核心场景的算法设计、迭代与优化;
2. 设计适配人形机器人高自由度特性的强化学习算法框架与深度网络架构,解决全身运动的稳定性、泛化性、实时性与安全性核心问题,持续提升机器人在复杂动态环境下的运动性能上限;
3. 负责算法的仿真验证、sim-to-real迁移优化与人形机器人真机部署调试,结合视觉、力觉、IMU等多模态传感器反馈完成闭环控制优化,完成算法性能指标的评估、迭代与落地;
4. 与感知、硬件、任务规划等跨团队紧密协作,推动算法与人形机器人本体、多模态感知系统的深度适配与集成,支撑整机运动能力的落地与产品化迭代;
5. 持续跟踪人形机器人全身运动控制、深度强化学习领域的国际前沿研究与技术动态,引入顶会顶刊的创新方法,推动核心技术的突破与技术壁垒构建;
1. 硕士及以上学历,计算机科学与技术、人工智能、自动化、控制工程、机器人工程等相关专业,具备扎实的自动控制理论、刚体动力学与机器学习理论基础;
2. 精通深度强化学习算法原理与工程落地,熟悉PPO、SAC、TD3、DQN等主流DRL算法,具备基于强化学习的机器人运动控制算法完整研发与落地经验;
3. 精通人形机器人正逆运动学、刚体动力学建模,熟悉高自由度机器人全身运动控制相关理论,具备人形机器人全身运动控制项目研发经验者优先;
4. 熟练使用PyTorch/TensorFlow等主流深度学习框架,精通Python/C++编程语言,熟悉ROS/ROS2等机器人软件框架,掌握Isaac Lab、Isaac Gym、MuJoCo、Gazebo等主流机器人仿真环境;
5. 熟悉模仿学习、逆强化学习、sim-to-real迁移、模型预测控制(MPC)、最优控制、数值优化等相关技术,具备多模态感知与运动控制融合开发经验者优先;
6. 具备良好的科研能力、工程落地能力与跨团队协作能力,在机器人、强化学习相关领域顶会顶刊(RSS、CoRL、ICRA、IROS、NeurIPS、ICML、ICLR等)发表过论文者优先。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
AI软件工程师,"岗位职责:
任职资格:
工作职责:
- 数据中心AI系统架构与系统软件设计。
任职资格:
1. 熟练使用C/C++/Python,熟悉常用数据结构与算法;
2. 熟悉大语言模型推理,有相关开发、分析和优化经验;
3. 具备AI infrastructure分析和优化经验;
4. 对系统软件研发有强烈兴趣。
5. 以下为加分项:
- 具备OpenCL,CUDA等开发和优化经验;
- 具备模拟器开发、系统仿真分析和优化经验。
其他要求:
本科/硕士学历
CET4及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。
同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
Edge AI软件工程师,"岗位职责:
任职资格:
工作职责:
- 端侧系统架构,算法及系统软件设计。
任职资格:
1. 熟练使用C/C++/Python,熟悉常用数据结构与算法;
2. 熟悉VLM、VLA,掌握模型训练、推理、优化相关知识,并有实际开发部署经验;
3. 具备模拟器开发、系统仿真分析和优化经验;
4. 有良好的沟通和学习能力。
5. 以下为加分项:
- 具备OpenCLCUDA开发和优化经验;
- 具备GPUNPU设计经验;
- 对机器人方向算法优化和系统软件研发有强烈兴趣。
其他要求:
本科及以上学历
CET4及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。
同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
技术战略分析师,"岗位职责:
任职资格:
岗位职责:
- 技术分析:从技术视角深入研究前沿科技,重点聚焦人工智能、存储技术、高性能计算等领域,开展系统性调研并撰写高质量的技术分析报告,助力技术决策与战略布局。
- 行业洞察:紧跟国内外技术发展趋势,研判技术演进方向与竞争态势,为集团战略决策提供坚实依据。
- 专家访谈:积极与行业专家保持深入沟通,建立长期合作关系,获取第一手权威见解与前沿信息。
- 论文管理:负责公司学术论文的评审与发表流程的统筹与优化,推动论文质量稳步提升,增强公司学术影响力。
- 业务支援:参与公司中长期技术规划,协助组织并推进技术创新相关活动,提升研发效率与创新能力。
岗位要求:
1. 人工智能、存储技术、计算机科学等相关专业背景,有在人工智能、存储系统、高性能计算等领域的工作经验者优先。
2. 对前沿技术保持高度关注,具备独立开展技术调研的能力,能够撰写逻辑清晰、内容详实的技术分析报告。
3. 能够熟练阅读英文技术文档与学术论文,准确把握核心思想与创新点,以及优秀的英语口语交流能力。
4. 对新技术有热情,独立问题解决能力,海外同事合作能力
5. 以下为加分项:
- 有韩语能力者优先,能进行基本的书面或口语交流。
- 有技术研发经验者优先。
- 有深度技术调研报告撰写经验者优先。
其他要求:
- 硕士/博士学历
- 人工智能、存储技术、计算机科学等相关专业
- 英语六级(CET-6)或同等级英语水平及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。
同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
存储软件开发系统工程师,"岗位职责:
任职资格:
岗位职责:
- 负责三星存储产品系统软件开发及性能优化;
- 负责三星存储系统前沿技术研究。
岗位要求:
1. 具备良好的编程基础,熟练掌握C/C++/Python至少一种编程语言;
2. 熟练掌握常用数据结构及算法;
3. 熟悉Linux系统的编程基础,熟悉Linux I/O相关协议栈。
4. 以下为加分项:
- 具有数据库,存储引擎以及文件系统相关开发和优化经验者;
- 具备AI框架下存储相关研究经验。
其他要求:
- 硕士学历
- 计算机、软件、电子,通信,自动化等相关专业
- CET4及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。
请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》
在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
分布式系统软件工程师,"岗位职责:
任职资格:
岗位职责:
- 负责三星大规模集群系统任务调度及资源管理方案的优化与开发;
- 提升大规模集群的调度系统的整体效率和资源利用率。
岗位要求:
1. 具有扎实的shell/C++/Python编程基础,熟悉数据结构和算法;
2. 掌握计算机操作系统,分布式系统等专业知识;
3. 熟悉多线程开发,有良好的代码阅读和开发能力。
4. 以下为加分项:
- 具有Slurm, LSF, Kubernetes的代码经验或者部署经验。
其他要求:
- 硕士学历
- 计算机、人工智能等相关专业
- CET4及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。
请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》
在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。
同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
存储软件工程师(AI算法方向),"岗位职责:
任职资格:
岗位职责:
- 负责三星存储产品相关AI算法的设计、训练、优化和研发。
岗位要求:
1. 精通Python,熟悉C/C++语言,熟练掌握常用的数据结构和算法;
2. 掌握机器学习/深度学习算法模型构建、训练、优化相关专业知识并有相关经验;
3. 能熟练使用PyTorch等框架进行模型的开发和优化;
4. 具有较强的动手能力和研究能力,能够快速复现论文方法,并针对特定的场景进行优化;
5. 以下为加分项:
- 具备AI框架下存储相关研究经验;
- 有顶会/顶刊论文相关成果者优先;
- 有transformer,大模型研发经验者优先。
其他要求:
- 硕士学历
- 计算机、软件、大数据、人工智能等相关专业
- CET4及以上
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》
在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
存储系统专家,"岗位职责:
任职资格:
岗位职责:
- 作为团队技术带头人,负责存储系统软件架构设计和实现以及存储系统的应用优化;
- 负责三星存储相关新技术解决方案的研究以及学术成果转化。
岗位要求:
1. 熟悉NVMe SSD相关知识且具备存储设备性能优化经验;
2. 熟悉Linux内核I/O协议栈,具备SPDK等用户态驱动开发和优化经验;
3. 较强的软件架构以及代码重构能力;
4. 了解数据库以及常用存储引擎相关知识以及体系架构 (Rocks DB, MySQL.),并有相应系统设计开发以及优化经验。
加分项:
- 熟悉新的Memory技术如CXL,有相关研究经验者优先;
- 具备AI框架下存储相关研究经验者优先;
- 在该领域顶级会议或期刊发表过论文者优先。
其他要求:
- 博士学历
- 计算机、软件、电子、通信、自动化等相关专业
- CET6及以上,英语可作为工作语言
感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!
三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。
若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。
《个人信息收集使用申明》
在本次招聘活动中,我们承诺以下事项:
1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;
2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果;
3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。
同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。
1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用;
2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;
3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;
4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;
5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。
如您需取消投递,请自行撤销简历;
若需帮助请联系HRsrcxianhr@samsung.com。",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
大模型算法工程师,"岗位职责:
任职资格:
1. 参与基础大模型和端侧大模型的研发工作,包括架构设计、预训练、后训练等,端到端构建通用大模型;
2. 负责大模型高阶能力(Coding、Agent等)的专项提升,打造模型长版特性;
3. 持续关注大模型最新研究,探索下一代大模型的架构和训练方法,做出有影响力的成果;
1. 硕士及以上学历,计算机科学、人工智能等相关专业;
2. 熟悉深度学习框架(例如pytorch等),具备大模型和端侧大模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验;
3. 对大模型架构、训练、数据、系统优化中的某一方面有深入理解,以下符合1条以上:
- 能够提出创新性的大模型架构和端侧大模型架构,探索技术的下一跳;
- 熟练掌握强化学习(RL)和模型微调(SFT)等后训练技术,并可以提出创新的后训练方法;
- 对coding、math、agent等大模型高阶能力有深入思考;
- 熟练掌握大模型预训练的Know How,可以快速诊断并修复问题,提升模型能力;
- 对预训练数据、后训练数据的生产、合成方法有深入理解;
- 熟练模型训练/推理的系统优化方法,提升模型的实际训练、推理性能;
4. 有大模型/端侧大模型架构、训练、数据、系统优化等相关实战经验者优先,在NeurIPS/ICML/ICLR/ACL/EMNLP/CVPR/ICCV/TPAMI等AI顶会发表过相关论文者优先;
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
具身智能算法工程师,"岗位职责:
任职资格:
1. 负责研发具身智能操作算法,研发基于VLA、强化学习等AI技术在机器人操作场景中的应用;
2. 设计网络架构,分析实验数据,评估算法表现,提升机器人在精准操作、长程任务、动态响应等关键领域的表现性能;
3. 负责将VLA模型在跨机器人本体和环境进行真机部署,评估模型在真机的性能指标;
4. 持续跟进最新的具身操作方向研究工作动态,引入最前沿的方法持续提升模型表现性能;
1. 硕士及以上学历,计算机科学、人工智能、自动化、机器人技术等相关专业;
2. 熟悉深度学习框架(例如pytorch、TensorFlow),具备大规模VLA模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验;
3. 具备机器学习算法在机器人领域的开发经验,包括并不限于reinforcement learning、imitation learning、transfer learning、action-conditioned world models、representation learning、dexterous manipulation、sim-to-real transfer、vision language models、motion planning等;
4. 具备机器人真机经验(例如Aloha、Franka、Fetch等),具备良好的编程能力,熟悉Python或C++编程语言,熟悉主流机器人软件框架例如ROS,熟悉主流的仿真软件例如IsaacLab、IsaacGym、Mujoco、Bullet、Gazebo等;
5. 具备良好的科研能力,在顶会或期刊发表过文章的优先,例如机器学习方向(NeurIPS、ICML、ICLR),机器人方向(RSS、CoRL、ICRA、IROS)、计算机视觉方向(CVPR、ICCV、ECCV)等;
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
高性能并行计算开发工程师,"岗位职责:
任职资格:
1. 根据无线通信模块需要,基于CPU/GPU设计适合并行计算的数据结构,利用多线程实现高效的并行计算处理编程;
2. 具有较高的并行计算/高性能计算方面SW设计及开发能力,能通过性能分析找到CPU或GPU处理的瓶颈,并提出改善方案;
1. 硕士及以上学历,计算机科学/人工智能等相关专业;
2. 精通高性能计算/并行计算软件设计及优化思想,具有多线程并行计算开发经验;
3. 熟练使用CPU/GPU性能分析工具(Nsight等)并通过性能监测找到存储,数据传输,并行计算中的瓶颈点,并结合数据访存和并行计算能力设计最优SW方案;
4. 有GPU高性能计算/CUDA开发经验者优先;
5. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
无线通信CUDA开发工程师,"岗位职责:
任职资格:
1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求;
2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案;
3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告;
1. 硕士及以上学历,计算机科学/通信等相关专业;
2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧;
3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力;
4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先;
5. 有基于GPU的算力利用率提升项目经验者优先;
6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
SCS-技术员,"岗位职责:
任职资格:
1.负责现场设备日常维护工作;
2.协助工程师进行调试工作,进行设备日常作业;
3.根据作业标准要求进行设备的操作。
1.学历:25~26届毕业大专生;
2.专业:机械类、电气类、自动化类、计算机类、电子类等理工科相关专业;
3.熟练使用Office办公软件;
4.能适应倒班工作(三班倒)。
(早班:6:00-14:00;中班:14:00-22:00;晚班:22:00-06:00,上五休二,每班工作8小时)",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
知识图谱、智能体、大模型算法工程师,"岗位职责:
任职资格:
从事知识图谱,大语言模型、多智能体优化的前沿算法研究:
- 研究方向包括:知识图谱,智能体设计, 大模型RAG, 多智能体优化
- 算法领域包括但不限于: Knowledge Graph, Graph Retrieval, AI Agent, RAG, LLM/VLM/LMM, CoT, etc.
1. 硕士及以上学历,计算机、电子、自动化、数学等相关专业;
2. 熟练掌握智能体设计,大模型微调等相关基础;
3. 对知识图谱,大模型/RAG/Agent/Retrieval 有相关开发经验;
4. 熟悉PythonPyTorch深度学习框架;
5. 对前沿技术有热情,有较强的独立工作能力(算法理解与实现,问题分析与解决);
[加分项] 在顶会NIPS,ICML等发表过高水平文章,或在权威竞赛中以主要参与者身份取得过优秀名次;
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
通信AI算法工程师,"岗位职责:
任职资格:
1. 网络优化和诊断的AI算法研究;
2. AI算法实现,优化和评估;
3. 网络性能问题研究;
1. 博士及以上学历,通信工程、电子工程、计算机等相关专业;
2. 对AI算法有深入研究;
3. 具有AI算法编码和应用经验;
4. 擅长应用问题的算法建模;
5. 有无线通信的AI算法研究经验者优先;
6. 对AI算法有广泛实用经验者优先。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
数字孪生算法工程师,"岗位职责:
任职资格:
1. 5G-A/5G+AI MAC/RLC/PDCP系统算法研究、设计工作;
2. Ray tracing/3GPP信道建模算法研究、设计工作;
3. 5G-A/5G+AI 系统级仿真分析工作;
4. 指导和协助开发 S/W实现与优化工作。
1. 硕士及以上学历,博士优先,通信工程、计算机等相关专业;
2. 对5GA/5G协议和系统有深入了解和相应研究经历;
3. 有MAC/RLC/PDCP/PHY算法设计和研究经验;
4. 有信道建模设计和研究经验;
5. 有系统级/链路级+AI仿真经验;
6. 熟练掌握C/C++Python编程;
7. 有良好的英语交流能力,积极进取,有良好的团队合作意识和技术创新意识。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
5G/5GA算法工程师,"岗位职责:
任职资格:
1. LTE/5G MAC、SON系统算法研究、设计工作;
2. LTE/5G系统级仿真、分析工作;
3. 5G 链路级仿真工作;
4. 指导和协助开发 S/W实现与测试工作;
5. 系统级advance算法相关研究工作。
1. 硕士及以上学历,博士优先,通信工程、电子相关专业;
2. 对LTE/5G/5GA协议和系统有深入了解和相应研究经历;
3. 有MAC、SON算法设计和研究经验;
4. 有系统级或者链路级仿真经验,熟练掌握C/C++/matlab/python编程;
5. 有5G/5GA标准化经验者优先考虑;
6. 有丰富MIMO, SON相关研究经验者优先考虑;
7. 有良好的英文交流能力;
8. 积极进取,有良好的团队合作意识,技术创新意识。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
通信SoC软件开发工程师,"岗位职责:
任职资格:
1. 负责OMMU/ORU LPHY模块设计和开发;
2. 负责ORAN-based LPHY模块性能优化;
1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业;
2. 精通C/C++,熟悉架构设计及优化者优先;
3. 熟悉基于通信基带SoC芯片的软件开发,优化和测试过程,有Marvell通信芯片软件开发经验者优先;
4. 熟悉3GPP协议,ORAN协议,具有ORAN Opt7-2x/Opt7-3开发经验者优先;
5. 熟悉RTOS,Linux驱动开发经验者优先;
6. 具备良好的数字信号处理背景优先;
7. 良好的英文书面和口语表达。
加分项:
- 熟悉常用AI算法模型,有广泛实用经验/模型部署移植等相关经验;
- 有DFE(digital front-end)开发经验;
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
4G/5G 物理层开发工程师,"岗位职责:
任职资格:
按照经验能力参与以下工作的一项或多项,包括:
1. 负责4G/5G物理层接收机&发送机的算法模块SW实现;
2. 负责基站侧或终端侧 Modem 架构设计及SW开发;
3. 负责AI+5G开发及优化;
4. 负责数字孪生开发和验证;
1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业;
2. 精通C/C++语言,熟悉架构设计及优化者优先;
3. 熟悉至少一种CPU结构及指令,有Intel AVX512/AMX优化经验者优先;
4. 熟悉至少一种无线通信协议,有NR、LTE、NB-IOT、2G GSM物理层研发经验优先;
5. 熟悉3GPP信道建模优化,有digital twin经验者优先;
6. 熟悉常用AI训练推理架构,熟悉常用AI算法模型者优先;
7. 熟悉linux操作系统,有内核优化经验者优先;
8. 具备良好的数字信号处理背景优先;
9. 良好的英文书面和口语表达。
公司介绍:
三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。
新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!
※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密
※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
战略企划,"岗位职责:
任职资格:
主要职责:
1. 销售数据分析及企划
2. 行业市场分析
3. 韩语翻译及部门交代的其他相关事项
岗位要求
- 学历:统招本科及以上
- 经历:销售企划相关经历者优先考虑
- 熟练掌握 M/S Office (Excel, Word, PPT)
- 韩国语能力优秀者优先考虑 (TOPIK 6级 或 近母语水平)",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory MKT|存储芯片市场,"岗位职责:
任职资格:
1. Establish and maintain the regular and close communication relationship with customers and colleague
2. Memory business Marketer
3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market
4. Working closely with our customers
5. Writing market analysis report
6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater.
1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ
2. Experience in Memroy market and product (DRAM/SSD/GFX)
3. Experience in PC martket
4. Understaing of Memory business value chain including PC Market
5. Sophisticated in PPT and Excel, with good presentation skills",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] DRAM BE|存储芯片市场营销,"岗位职责:
任职资格:
1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China;
2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers.
3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win.
4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements.
'1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory DRAM FAE|存储芯片技术支持,"岗位职责:
任职资格:
- Support DRAM failure analysis with customers and ODM venders
- Prompt and professional technical on-site support for acquiring
customer's demand of DRAM.
- Make an initial judgement for the issues from customers
- Eliminate noise and ambiguity of on-site test results
- Regular technical discussion with HQ AE team and customers and
cross functional departments independently.
- Familiar with DRAM function and system operation
(Command sequence/AC parameter/…).
- Experience in DDR module on NB, desktop
(server system design/validation is a plus)
- To have analysis ability for log
(system booting log and DRAM training log, etc.)
- To have experience of tools updating BIOS (Dediprog, etc.)
- To have basic software knowledge related to PC, Notebook
(Windows, Linux, Python, etc.)
- To have experience of operating oscilloscope and logic analyzer.
- To have good comprehension and good communication skills with
ODM & customers, HQ and related departments",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] DRAM TEC|测试技术工程师,"岗位职责:
任职资格:
1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5)
2. Attend tech. meeting with DRAM BE and CS contact window;
3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support;
4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage.
- Familiar with DRAM function and system operation
(Command sequence/AC parameter/…).
- Experience in DDR module on NB, desktop
(server system design/validation is a plus)
- To have analysis ability for log
(system booting log and DRAM training log, etc.)
- To have experience of tools updating BIOS (Dediprog, etc.)
- To have basic software knowledge related to PC, Notebook
(Windows, Linux, Python, etc.)
- To have experience of operating oscilloscope and logic analyzer.
- To have good comprehension and good communication skills with
ODM & customers, HQ and related departments",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Foundry FAE|晶圆代工技术支持,"岗位职责:
任职资格:
1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C
2. Design in (T/O) the Foundry customer product in E/C
3. Build the relationship with Tier 1/2/3 customer in E/C
Education: Bachelor degree and above
Major: Electrical/Electronics engineering
Experience Range:3 Years
Prof. Experience Experience in SOC design
Language skillsFluent in English read/write/speaking
Min. skills & knowledge:
1. Knowledge in Semiconductor Process manufacturing, device component
2. Experience on designing Digital IP, Analog IP, SOC Design
3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Auto TEC|测试技术工程师,"岗位职责:
任职资格:
1. Responsible as TEC engineer in Mobile/Auto TEC department;
2.Responsible for Auto DRAM product testing when needed.
3. Suppport on-site and DRAM Validation activities to nVIDIA;
4. Maintain and Improve customer's satisfaction with issue on-site support;
1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent;
2. Understanding Electronic Basic & Advanced Theory and semiconductor industry
3. At least 2 years experience, with Auto memory product is highly preferred;
4. Familiar with Automotive applications is highly preferred.
5. Good command of oral and written English; Good Korean is highly preferred;",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory FAE|存储芯片技术支持,"岗位职责:
任职资格:
1. Promote and Design in SSD products to PC customers in East China.
2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM
3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win.
4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements
1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ.
2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market.
3. Experience and knowledge in SSD products is preferred.",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory MKT|存储芯片市场,"岗位职责:
任职资格:
1. Establish and maintain the regular and close communication relationship with customers and colleague
2. Memory business Marketer
3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market
4. Working closely with our customers
5. Writing market analysis report
6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater.
1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ
2. Experience in Memroy market and product (DRAM/SSD/GFX)
3. Experience in PC martket
4. Understaing of Memory business value chain including PC Market
5. Sophisticated in PPT and Excel, with good presentation skills",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] DRAM BE|存储芯片市场营销,"岗位职责:
任职资格:
1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China;
2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers.
3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win.
4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements.
'1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory DRAM FAE|存储芯片技术支持,"岗位职责:
任职资格:
- Support DRAM failure analysis with customers and ODM venders
- Prompt and professional technical on-site support for acquiring
customer's demand of DRAM.
- Make an initial judgement for the issues from customers
- Eliminate noise and ambiguity of on-site test results
- Regular technical discussion with HQ AE team and customers and
cross functional departments independently.
- Familiar with DRAM function and system operation
(Command sequence/AC parameter/…).
- Experience in DDR module on NB, desktop
(server system design/validation is a plus)
- To have analysis ability for log
(system booting log and DRAM training log, etc.)
- To have experience of tools updating BIOS (Dediprog, etc.)
- To have basic software knowledge related to PC, Notebook
(Windows, Linux, Python, etc.)
- To have experience of operating oscilloscope and logic analyzer.
- To have good comprehension and good communication skills with
ODM & customers, HQ and related departments",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] DRAM TEC|测试技术工程师,"岗位职责:
任职资格:
1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5)
2. Attend tech. meeting with DRAM BE and CS contact window;
3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support;
4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage.
- Familiar with DRAM function and system operation
(Command sequence/AC parameter/…).
- Experience in DDR module on NB, desktop
(server system design/validation is a plus)
- To have analysis ability for log
(system booting log and DRAM training log, etc.)
- To have experience of tools updating BIOS (Dediprog, etc.)
- To have basic software knowledge related to PC, Notebook
(Windows, Linux, Python, etc.)
- To have experience of operating oscilloscope and logic analyzer.
- To have good comprehension and good communication skills with
ODM & customers, HQ and related departments",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Foundry FAE|晶圆代工技术支持,"岗位职责:
任职资格:
1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C
2. Design in (T/O) the Foundry customer product in E/C
3. Build the relationship with Tier 1/2/3 customer in E/C
Education: Bachelor degree and above
Major: Electrical/Electronics engineering
Experience Range:3 Years
Prof. Experience Experience in SOC design
Language skillsFluent in English read/write/speaking
Min. skills & knowledge:
1. Knowledge in Semiconductor Process manufacturing, device component
2. Experience on designing Digital IP, Analog IP, SOC Design
3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Auto TEC|测试技术工程师,"岗位职责:
任职资格:
1. Responsible as TEC engineer in Mobile/Auto TEC department;
2.Responsible for Auto DRAM product testing when needed.
3. Suppport on-site and DRAM Validation activities to nVIDIA;
4. Maintain and Improve customer's satisfaction with issue on-site support;
1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent;
2. Understanding Electronic Basic & Advanced Theory and semiconductor industry
3. At least 2 years experience, with Auto memory product is highly preferred;
4. Familiar with Automotive applications is highly preferred.
5. Good command of oral and written English; Good Korean is highly preferred;",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
[社会招聘] Memory FAE|存储芯片技术支持,"岗位职责:
任职资格:
1. Promote and Design in SSD products to PC customers in East China.
2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM
3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win.
4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements
1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ.
2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market.
3. Experience and knowledge in SSD products is preferred.",https://dearsamsung.zhiye.com/#/samsung/pc/szzw
1 job_title description detail_url
2 [社会招聘] 三星SDSC IT售前支持 岗位职责: 任职资格: 1. 根据客户情况提供合理的解决方案, 2. 项目的整体规划,日程管理,风险管理,品质管理,验收报告等, 3. 编写项目相关文档,确保项目资料的收集、整理、建档和保存, 4. 公司运营,采购,执行等相关部门的业务协调等。 1. 学历专业:正规院校本科及以上学历,双证齐全,专业不限; 2. 工作经验: - 3~5年销售经验或者软件开发目管理经验 - 有大型项目参与经验者优先 3. 技术能力: - CRM,SAP,RMS,WMS等相关系统项目管理经验 - 熟悉Java、C#等主流编程语言‌者优先 - 了解HTML、CSS、JavaScript,熟悉Vue、React等前端框架 - 了解TCP/IP、HTTP等网络协议,熟悉Socket编程 - 了解Python编程基础,熟悉Django、Flask等框架,了解MongoDB、Linux系统操作 - 了解服务器,网络设备等相关内容者优先 4. 综合素质: - 了解韩国文化,理解韩国文化 - 为人正直,有责任心,积极主动,逻辑清晰,具备优秀沟通、宣讲及文案能力 - 具备良好的沟通能力和方案撰写能力,能够与客户和团队成员有效沟通‌ 5.语言:无限制,如懂韩语优先 6.其他:取得PMP资格证优先,接受出差 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
3 [社会招聘] 三星SDSC IT销售代表(韩语) 岗位职责: 任职资格: 1. 挖掘可购买公司产品及服务的企业客户与商机; 2. 挖掘可与公司开展业务合作的销售及交付合作伙伴; 3. ‌分析客户IT需求,基于公司与合作伙伴的产品及能力制定解决方案与业务提案; 4. 通过分析公司产品及能力,开发服务产品并提出销售方案等; 5.公司内部销售系统处理及管理: 订单录入,成本确认,合同处理,损益确认,计划录入等。 1. 正规院校本科及以上学历,双证齐全; 2. 工作经验: - 拥有IT销售经验或在IT服务行业工作过经验; - 具有云计算相关的销售或技术工作经验,特别是AWS相关经验者优先考虑; 3. 技术能力: - 对最新的IT技术趋势的广泛理解 - 熟练使用MS Office软件(Excel,Word,PPT) 4. 语言要求:韩语精通(必须) 5.其他:接受短期出差 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
4 无线通信CUDA开发工程师 岗位职责: 任职资格: 1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求; 2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案; 3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告; 1. 硕士及以上学历,计算机科学/通信等相关专业; 2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧; 3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力; 4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先; 5. 有基于GPU的算力利用率提升项目经验者优先; 6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
5 人形机器人全身运动控制算法工程师(强化学习方向) 岗位职责: 任职资格: 1. 负责基于强化学习的人形机器人全身运动控制算法研发,涵盖行走、跑跳、平衡控制、复杂地形适配、动态抗扰动、全身协同运动规划等核心场景的算法设计、迭代与优化; 2. 设计适配人形机器人高自由度特性的强化学习算法框架与深度网络架构,解决全身运动的稳定性、泛化性、实时性与安全性核心问题,持续提升机器人在复杂动态环境下的运动性能上限; 3. 负责算法的仿真验证、sim-to-real迁移优化与人形机器人真机部署调试,结合视觉、力觉、IMU等多模态传感器反馈完成闭环控制优化,完成算法性能指标的评估、迭代与落地; 4. 与感知、硬件、任务规划等跨团队紧密协作,推动算法与人形机器人本体、多模态感知系统的深度适配与集成,支撑整机运动能力的落地与产品化迭代; 5. 持续跟踪人形机器人全身运动控制、深度强化学习领域的国际前沿研究与技术动态,引入顶会顶刊的创新方法,推动核心技术的突破与技术壁垒构建; 1. 硕士及以上学历,计算机科学与技术、人工智能、自动化、控制工程、机器人工程等相关专业,具备扎实的自动控制理论、刚体动力学与机器学习理论基础; 2. 精通深度强化学习算法原理与工程落地,熟悉PPO、SAC、TD3、DQN等主流DRL算法,具备基于强化学习的机器人运动控制算法完整研发与落地经验; 3. 精通人形机器人正逆运动学、刚体动力学建模,熟悉高自由度机器人全身运动控制相关理论,具备人形机器人全身运动控制项目研发经验者优先; 4. 熟练使用PyTorch/TensorFlow等主流深度学习框架,精通Python/C++编程语言,熟悉ROS/ROS2等机器人软件框架,掌握Isaac Lab、Isaac Gym、MuJoCo、Gazebo等主流机器人仿真环境; 5. 熟悉模仿学习、逆强化学习、sim-to-real迁移、模型预测控制(MPC)、最优控制、数值优化等相关技术,具备多模态感知与运动控制融合开发经验者优先; 6. 具备良好的科研能力、工程落地能力与跨团队协作能力,在机器人、强化学习相关领域顶会顶刊(RSS、CoRL、ICRA、IROS、NeurIPS、ICML、ICLR等)发表过论文者优先。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
6 AI软件工程师 岗位职责: 任职资格: 工作职责: - 数据中心AI系统架构与系统软件设计。 任职资格: 1. 熟练使用C/C++/Python,熟悉常用数据结构与算法; 2. 熟悉大语言模型推理,有相关开发、分析和优化经验; 3. 具备AI infrastructure分析和优化经验; 4. 对系统软件研发有强烈兴趣。 5. 以下为加分项: - 具备OpenCL,CUDA等开发和优化经验; - 具备模拟器开发、系统仿真分析和优化经验。 其他要求: 本科/硕士学历 CET4及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
7 Edge AI软件工程师 岗位职责: 任职资格: 工作职责: - 端侧系统架构,算法及系统软件设计。 任职资格: 1. 熟练使用C/C++/Python,熟悉常用数据结构与算法; 2. 熟悉VLM、VLA,掌握模型训练、推理、优化相关知识,并有实际开发部署经验; 3. 具备模拟器开发、系统仿真分析和优化经验; 4. 有良好的沟通和学习能力。 5. 以下为加分项: - 具备OpenCL,CUDA开发和优化经验; - 具备GPU,NPU设计经验; - 对机器人方向算法优化和系统软件研发有强烈兴趣。 其他要求: 本科及以上学历 CET4及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
8 技术战略分析师 岗位职责: 任职资格: 岗位职责: - 技术分析:从技术视角深入研究前沿科技,重点聚焦人工智能、存储技术、高性能计算等领域,开展系统性调研并撰写高质量的技术分析报告,助力技术决策与战略布局。 - 行业洞察:紧跟国内外技术发展趋势,研判技术演进方向与竞争态势,为集团战略决策提供坚实依据。 - 专家访谈:积极与行业专家保持深入沟通,建立长期合作关系,获取第一手权威见解与前沿信息。 - 论文管理:负责公司学术论文的评审与发表流程的统筹与优化,推动论文质量稳步提升,增强公司学术影响力。 - 业务支援:参与公司中长期技术规划,协助组织并推进技术创新相关活动,提升研发效率与创新能力。 岗位要求: 1. 人工智能、存储技术、计算机科学等相关专业背景,有在人工智能、存储系统、高性能计算等领域的工作经验者优先。 2. 对前沿技术保持高度关注,具备独立开展技术调研的能力,能够撰写逻辑清晰、内容详实的技术分析报告。 3. 能够熟练阅读英文技术文档与学术论文,准确把握核心思想与创新点,以及优秀的英语口语交流能力。 4. 对新技术有热情,独立问题解决能力,海外同事合作能力 5. 以下为加分项: - 有韩语能力者优先,能进行基本的书面或口语交流。 - 有技术研发经验者优先。 - 有深度技术调研报告撰写经验者优先。 其他要求: - 硕士/博士学历 - 人工智能、存储技术、计算机科学等相关专业 - 英语六级(CET-6)或同等级英语水平及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
9 存储软件开发系统工程师 岗位职责: 任职资格: 岗位职责: - 负责三星存储产品系统软件开发及性能优化; - 负责三星存储系统前沿技术研究。 岗位要求: 1. 具备良好的编程基础,熟练掌握C/C++/Python至少一种编程语言; 2. 熟练掌握常用数据结构及算法; 3. 熟悉Linux系统的编程基础,熟悉Linux I/O相关协议栈。 4. 以下为加分项: - 具有数据库,存储引擎以及文件系统相关开发和优化经验者; - 具备AI框架下存储相关研究经验。 其他要求: - 硕士学历 - 计算机、软件、电子,通信,自动化等相关专业 - CET4及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
10 分布式系统软件工程师 岗位职责: 任职资格: 岗位职责: - 负责三星大规模集群系统任务调度及资源管理方案的优化与开发; - 提升大规模集群的调度系统的整体效率和资源利用率。 岗位要求: 1. 具有扎实的shell/C++/Python编程基础,熟悉数据结构和算法; 2. 掌握计算机操作系统,分布式系统等专业知识; 3. 熟悉多线程开发,有良好的代码阅读和开发能力。 4. 以下为加分项: - 具有Slurm, LSF, Kubernetes的代码经验或者部署经验。 其他要求: - 硕士学历 - 计算机、人工智能等相关专业 - CET4及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
11 存储软件工程师(AI算法方向) 岗位职责: 任职资格: 岗位职责: - 负责三星存储产品相关AI算法的设计、训练、优化和研发。 岗位要求: 1. 精通Python,熟悉C/C++语言,熟练掌握常用的数据结构和算法; 2. 掌握机器学习/深度学习算法模型构建、训练、优化相关专业知识并有相关经验; 3. 能熟练使用PyTorch等框架进行模型的开发和优化; 4. 具有较强的动手能力和研究能力,能够快速复现论文方法,并针对特定的场景进行优化; 5. 以下为加分项: - 具备AI框架下存储相关研究经验; - 有顶会/顶刊论文相关成果者优先; - 有transformer,大模型研发经验者优先。 其他要求: - 硕士学历 - 计算机、软件、大数据、人工智能等相关专业 - CET4及以上 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
12 存储系统专家 岗位职责: 任职资格: 岗位职责: - 作为团队技术带头人,负责存储系统软件架构设计和实现以及存储系统的应用优化; - 负责三星存储相关新技术解决方案的研究以及学术成果转化。 岗位要求: 1. 熟悉NVMe SSD相关知识且具备存储设备性能优化经验; 2. 熟悉Linux内核I/O协议栈,具备SPDK等用户态驱动开发和优化经验; 3. 较强的软件架构以及代码重构能力; 4. 了解数据库以及常用存储引擎相关知识以及体系架构 (Rocks DB, MySQL.),并有相应系统设计开发以及优化经验。 加分项: - 熟悉新的Memory技术如CXL,有相关研究经验者优先; - 具备AI框架下存储相关研究经验者优先; - 在该领域顶级会议或期刊发表过论文者优先。 其他要求: - 博士学历 - 计算机、软件、电子、通信、自动化等相关专业 - CET6及以上,英语可作为工作语言 感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! 三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: 1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; 2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; 3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; 2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; 3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; 4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; 5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 如您需取消投递,请自行撤销简历; 若需帮助请联系HR:srcxianhr@samsung.com。 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
13 大模型算法工程师 岗位职责: 任职资格: 1. 参与基础大模型和端侧大模型的研发工作,包括架构设计、预训练、后训练等,端到端构建通用大模型; 2. 负责大模型高阶能力(Coding、Agent等)的专项提升,打造模型长版特性; 3. 持续关注大模型最新研究,探索下一代大模型的架构和训练方法,做出有影响力的成果; 1. 硕士及以上学历,计算机科学、人工智能等相关专业; 2. 熟悉深度学习框架(例如pytorch等),具备大模型和端侧大模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验; 3. 对大模型架构、训练、数据、系统优化中的某一方面有深入理解,以下符合1条以上: - 能够提出创新性的大模型架构和端侧大模型架构,探索技术的下一跳; - 熟练掌握强化学习(RL)和模型微调(SFT)等后训练技术,并可以提出创新的后训练方法; - 对coding、math、agent等大模型高阶能力有深入思考; - 熟练掌握大模型预训练的Know How,可以快速诊断并修复问题,提升模型能力; - 对预训练数据、后训练数据的生产、合成方法有深入理解; - 熟练模型训练/推理的系统优化方法,提升模型的实际训练、推理性能; 4. 有大模型/端侧大模型架构、训练、数据、系统优化等相关实战经验者优先,在NeurIPS/ICML/ICLR/ACL/EMNLP/CVPR/ICCV/TPAMI等AI顶会发表过相关论文者优先; 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
14 具身智能算法工程师 岗位职责: 任职资格: 1. 负责研发具身智能操作算法,研发基于VLA、强化学习等AI技术在机器人操作场景中的应用; 2. 设计网络架构,分析实验数据,评估算法表现,提升机器人在精准操作、长程任务、动态响应等关键领域的表现性能; 3. 负责将VLA模型在跨机器人本体和环境进行真机部署,评估模型在真机的性能指标; 4. 持续跟进最新的具身操作方向研究工作动态,引入最前沿的方法持续提升模型表现性能; 1. 硕士及以上学历,计算机科学、人工智能、自动化、机器人技术等相关专业; 2. 熟悉深度学习框架(例如pytorch、TensorFlow),具备大规模VLA模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验; 3. 具备机器学习算法在机器人领域的开发经验,包括并不限于reinforcement learning、imitation learning、transfer learning、action-conditioned world models、representation learning、dexterous manipulation、sim-to-real transfer、vision language models、motion planning等; 4. 具备机器人真机经验(例如Aloha、Franka、Fetch等),具备良好的编程能力,熟悉Python或C++编程语言,熟悉主流机器人软件框架例如ROS,熟悉主流的仿真软件例如IsaacLab、IsaacGym、Mujoco、Bullet、Gazebo等; 5. 具备良好的科研能力,在顶会或期刊发表过文章的优先,例如机器学习方向(NeurIPS、ICML、ICLR),机器人方向(RSS、CoRL、ICRA、IROS)、计算机视觉方向(CVPR、ICCV、ECCV)等; 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
15 高性能并行计算开发工程师 岗位职责: 任职资格: 1. 根据无线通信模块需要,基于CPU/GPU设计适合并行计算的数据结构,利用多线程实现高效的并行计算处理编程; 2. 具有较高的并行计算/高性能计算方面SW设计及开发能力,能通过性能分析找到CPU或GPU处理的瓶颈,并提出改善方案; 1. 硕士及以上学历,计算机科学/人工智能等相关专业; 2. 精通高性能计算/并行计算软件设计及优化思想,具有多线程并行计算开发经验; 3. 熟练使用CPU/GPU性能分析工具(Nsight等)并通过性能监测找到存储,数据传输,并行计算中的瓶颈点,并结合数据访存和并行计算能力设计最优SW方案; 4. 有GPU高性能计算/CUDA开发经验者优先; 5. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
16 无线通信CUDA开发工程师 岗位职责: 任职资格: 1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求; 2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案; 3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告; 1. 硕士及以上学历,计算机科学/通信等相关专业; 2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧; 3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力; 4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先; 5. 有基于GPU的算力利用率提升项目经验者优先; 6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
17 SCS-技术员 岗位职责: 任职资格: 1.负责现场设备日常维护工作; 2.协助工程师进行调试工作,进行设备日常作业; 3.根据作业标准要求进行设备的操作。 1.学历:25~26届毕业大专生; 2.专业:机械类、电气类、自动化类、计算机类、电子类等理工科相关专业; 3.熟练使用Office办公软件; 4.能适应倒班工作(三班倒)。 (早班:6:00-14:00;中班:14:00-22:00;晚班:22:00-06:00,上五休二,每班工作8小时) https://dearsamsung.zhiye.com/#/samsung/pc/szzw
18 知识图谱、智能体、大模型算法工程师 岗位职责: 任职资格: 从事知识图谱,大语言模型、多智能体优化的前沿算法研究: - 研究方向包括:知识图谱,智能体设计, 大模型RAG, 多智能体优化 - 算法领域包括但不限于: Knowledge Graph, Graph Retrieval, AI Agent, RAG, LLM/VLM/LMM, CoT, etc. 1. 硕士及以上学历,计算机、电子、自动化、数学等相关专业; 2. 熟练掌握智能体设计,大模型微调等相关基础; 3. 对知识图谱,大模型/RAG/Agent/Retrieval 有相关开发经验; 4. 熟悉Python,PyTorch深度学习框架; 5. 对前沿技术有热情,有较强的独立工作能力(算法理解与实现,问题分析与解决); [加分项] 在顶会NIPS,ICML等发表过高水平文章,或在权威竞赛中以主要参与者身份取得过优秀名次; 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
19 通信AI算法工程师 岗位职责: 任职资格: 1. 网络优化和诊断的AI算法研究; 2. AI算法实现,优化和评估; 3. 网络性能问题研究; 1. 博士及以上学历,通信工程、电子工程、计算机等相关专业; 2. 对AI算法有深入研究; 3. 具有AI算法编码和应用经验; 4. 擅长应用问题的算法建模; 5. 有无线通信的AI算法研究经验者优先; 6. 对AI算法有广泛实用经验者优先。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
20 数字孪生算法工程师 岗位职责: 任职资格: 1. 5G-A/5G+AI MAC/RLC/PDCP系统算法研究、设计工作; 2. Ray tracing/3GPP信道建模算法研究、设计工作; 3. 5G-A/5G+AI 系统级仿真分析工作; 4. 指导和协助开发 S/W实现与优化工作。 1. 硕士及以上学历,博士优先,通信工程、计算机等相关专业; 2. 对5GA/5G协议和系统有深入了解和相应研究经历; 3. 有MAC/RLC/PDCP/PHY算法设计和研究经验; 4. 有信道建模设计和研究经验; 5. 有系统级/链路级+AI仿真经验; 6. 熟练掌握C/C++,Python编程; 7. 有良好的英语交流能力,积极进取,有良好的团队合作意识和技术创新意识。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
21 5G/5GA算法工程师 岗位职责: 任职资格: 1. LTE/5G MAC、SON系统算法研究、设计工作; 2. LTE/5G系统级仿真、分析工作; 3. 5G 链路级仿真工作; 4. 指导和协助开发 S/W实现与测试工作; 5. 系统级advance算法相关研究工作。 1. 硕士及以上学历,博士优先,通信工程、电子相关专业; 2. 对LTE/5G/5GA协议和系统有深入了解和相应研究经历; 3. 有MAC、SON算法设计和研究经验; 4. 有系统级或者链路级仿真经验,熟练掌握C/C++/matlab/python编程; 5. 有5G/5GA标准化经验者优先考虑; 6. 有丰富MIMO, SON相关研究经验者优先考虑; 7. 有良好的英文交流能力; 8. 积极进取,有良好的团队合作意识,技术创新意识。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
22 通信SoC软件开发工程师 岗位职责: 任职资格: 1. 负责OMMU/ORU LPHY模块设计和开发; 2. 负责ORAN-based LPHY模块性能优化; 1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业; 2. 精通C/C++,熟悉架构设计及优化者优先; 3. 熟悉基于通信基带SoC芯片的软件开发,优化和测试过程,有Marvell通信芯片软件开发经验者优先; 4. 熟悉3GPP协议,ORAN协议,具有ORAN Opt7-2x/Opt7-3开发经验者优先; 5. 熟悉RTOS,Linux驱动开发经验者优先; 6. 具备良好的数字信号处理背景优先; 7. 良好的英文书面和口语表达。 加分项: - 熟悉常用AI算法模型,有广泛实用经验/模型部署移植等相关经验; - 有DFE(digital front-end)开发经验; 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
23 4G/5G 物理层开发工程师 岗位职责: 任职资格: 按照经验能力参与以下工作的一项或多项,包括: 1. 负责4G/5G物理层接收机&发送机的算法模块SW实现; 2. 负责基站侧或终端侧 Modem 架构设计及SW开发; 3. 负责AI+5G开发及优化; 4. 负责数字孪生开发和验证; 1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业; 2. 精通C/C++语言,熟悉架构设计及优化者优先; 3. 熟悉至少一种CPU结构及指令,有Intel AVX512/AMX优化经验者优先; 4. 熟悉至少一种无线通信协议,有NR、LTE、NB-IOT、2G GSM物理层研发经验优先; 5. 熟悉3GPP信道建模优化,有digital twin经验者优先; 6. 熟悉常用AI训练推理架构,熟悉常用AI算法模型者优先; 7. 熟悉linux操作系统,有内核优化经验者优先; 8. 具备良好的数字信号处理背景优先; 9. 良好的英文书面和口语表达。 公司介绍: 三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。 新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入! ※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密 ※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密 https://dearsamsung.zhiye.com/#/samsung/pc/szzw
24 战略企划 岗位职责: 任职资格: 主要职责: 1. 销售数据分析及企划 2. 行业市场分析 3. 韩语翻译及部门交代的其他相关事项 岗位要求 - 学历:统招本科及以上 - 经历:销售企划相关经历者优先考虑 - 熟练掌握 M/S Office (Excel, Word, PPT) - 韩国语能力优秀者优先考虑 (TOPIK 6级 或 近母语水平) https://dearsamsung.zhiye.com/#/samsung/pc/szzw
25 [社会招聘] Memory MKT|存储芯片市场 岗位职责: 任职资格: 1. Establish and maintain the regular and close communication relationship with customers and colleague 2. Memory business Marketer 3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market 4. Working closely with our customers 5. Writing market analysis report 6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater. 1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ 2. Experience in Memroy market and product (DRAM/SSD/GFX) 3. Experience in PC martket 4. Understaing of Memory business value chain including PC Market 5. Sophisticated in PPT and Excel, with good presentation skills https://dearsamsung.zhiye.com/#/samsung/pc/szzw
26 [社会招聘] DRAM BE|存储芯片市场营销 岗位职责: 任职资格: 1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China; 2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers. 3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win. 4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements. '1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered https://dearsamsung.zhiye.com/#/samsung/pc/szzw
27 [社会招聘] Memory DRAM FAE|存储芯片技术支持 岗位职责: 任职资格: - Support DRAM failure analysis with customers and ODM venders - Prompt and professional technical on-site support for acquiring customer's demand of DRAM. - Make an initial judgement for the issues from customers - Eliminate noise and ambiguity of on-site test results - Regular technical discussion with HQ AE team and customers and cross functional departments independently. - Familiar with DRAM function and system operation (Command sequence/AC parameter/…). - Experience in DDR module on NB, desktop (server system design/validation is a plus) - To have analysis ability for log (system booting log and DRAM training log, etc.) - To have experience of tools updating BIOS (Dediprog, etc.) - To have basic software knowledge related to PC, Notebook (Windows, Linux, Python, etc.) - To have experience of operating oscilloscope and logic analyzer. - To have good comprehension and good communication skills with ODM & customers, HQ and related departments https://dearsamsung.zhiye.com/#/samsung/pc/szzw
28 [社会招聘] DRAM TEC|测试技术工程师 岗位职责: 任职资格: 1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5) 2. Attend tech. meeting with DRAM BE and CS contact window; 3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support; 4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage. - Familiar with DRAM function and system operation (Command sequence/AC parameter/…). - Experience in DDR module on NB, desktop (server system design/validation is a plus) - To have analysis ability for log (system booting log and DRAM training log, etc.) - To have experience of tools updating BIOS (Dediprog, etc.) - To have basic software knowledge related to PC, Notebook (Windows, Linux, Python, etc.) - To have experience of operating oscilloscope and logic analyzer. - To have good comprehension and good communication skills with ODM & customers, HQ and related departments https://dearsamsung.zhiye.com/#/samsung/pc/szzw
29 [社会招聘] Foundry FAE|晶圆代工技术支持 岗位职责: 任职资格: 1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C 2. Design in (T/O) the Foundry customer product in E/C 3. Build the relationship with Tier 1/2/3 customer in E/C Education: Bachelor degree and above Major: Electrical/Electronics engineering Experience Range:>3 Years Prof. Experience: Experience in SOC design Language skills:Fluent in English read/write/speaking Min. skills & knowledge: 1. Knowledge in Semiconductor Process manufacturing, device component 2. Experience on designing Digital IP, Analog IP, SOC Design 3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc https://dearsamsung.zhiye.com/#/samsung/pc/szzw
30 [社会招聘] Auto TEC|测试技术工程师 岗位职责: 任职资格: 1. Responsible as TEC engineer in Mobile/Auto TEC department; 2.Responsible for Auto DRAM product testing when needed. 3. Suppport on-site and DRAM Validation activities to nVIDIA; 4. Maintain and Improve customer's satisfaction with issue on-site support; 1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent; 2. Understanding Electronic Basic & Advanced Theory and semiconductor industry 3. At least 2 years’ experience, with Auto memory product is highly preferred; 4. Familiar with Automotive applications is highly preferred. 5. Good command of oral and written English; Good Korean is highly preferred; https://dearsamsung.zhiye.com/#/samsung/pc/szzw
31 [社会招聘] Memory FAE|存储芯片技术支持 岗位职责: 任职资格: 1. Promote and Design in SSD products to PC customers in East China. 2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM 3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win. 4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements 1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market. 3. Experience and knowledge in SSD products is preferred. https://dearsamsung.zhiye.com/#/samsung/pc/szzw
32 [社会招聘] Memory MKT|存储芯片市场 岗位职责: 任职资格: 1. Establish and maintain the regular and close communication relationship with customers and colleague 2. Memory business Marketer 3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market 4. Working closely with our customers 5. Writing market analysis report 6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater. 1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ 2. Experience in Memroy market and product (DRAM/SSD/GFX) 3. Experience in PC martket 4. Understaing of Memory business value chain including PC Market 5. Sophisticated in PPT and Excel, with good presentation skills https://dearsamsung.zhiye.com/#/samsung/pc/szzw
33 [社会招聘] DRAM BE|存储芯片市场营销 岗位职责: 任职资格: 1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China; 2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers. 3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win. 4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements. '1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered https://dearsamsung.zhiye.com/#/samsung/pc/szzw
34 [社会招聘] Memory DRAM FAE|存储芯片技术支持 岗位职责: 任职资格: - Support DRAM failure analysis with customers and ODM venders - Prompt and professional technical on-site support for acquiring customer's demand of DRAM. - Make an initial judgement for the issues from customers - Eliminate noise and ambiguity of on-site test results - Regular technical discussion with HQ AE team and customers and cross functional departments independently. - Familiar with DRAM function and system operation (Command sequence/AC parameter/…). - Experience in DDR module on NB, desktop (server system design/validation is a plus) - To have analysis ability for log (system booting log and DRAM training log, etc.) - To have experience of tools updating BIOS (Dediprog, etc.) - To have basic software knowledge related to PC, Notebook (Windows, Linux, Python, etc.) - To have experience of operating oscilloscope and logic analyzer. - To have good comprehension and good communication skills with ODM & customers, HQ and related departments https://dearsamsung.zhiye.com/#/samsung/pc/szzw
35 [社会招聘] DRAM TEC|测试技术工程师 岗位职责: 任职资格: 1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5) 2. Attend tech. meeting with DRAM BE and CS contact window; 3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support; 4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage. - Familiar with DRAM function and system operation (Command sequence/AC parameter/…). - Experience in DDR module on NB, desktop (server system design/validation is a plus) - To have analysis ability for log (system booting log and DRAM training log, etc.) - To have experience of tools updating BIOS (Dediprog, etc.) - To have basic software knowledge related to PC, Notebook (Windows, Linux, Python, etc.) - To have experience of operating oscilloscope and logic analyzer. - To have good comprehension and good communication skills with ODM & customers, HQ and related departments https://dearsamsung.zhiye.com/#/samsung/pc/szzw
36 [社会招聘] Foundry FAE|晶圆代工技术支持 岗位职责: 任职资格: 1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C 2. Design in (T/O) the Foundry customer product in E/C 3. Build the relationship with Tier 1/2/3 customer in E/C Education: Bachelor degree and above Major: Electrical/Electronics engineering Experience Range:>3 Years Prof. Experience: Experience in SOC design Language skills:Fluent in English read/write/speaking Min. skills & knowledge: 1. Knowledge in Semiconductor Process manufacturing, device component 2. Experience on designing Digital IP, Analog IP, SOC Design 3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc https://dearsamsung.zhiye.com/#/samsung/pc/szzw
37 [社会招聘] Auto TEC|测试技术工程师 岗位职责: 任职资格: 1. Responsible as TEC engineer in Mobile/Auto TEC department; 2.Responsible for Auto DRAM product testing when needed. 3. Suppport on-site and DRAM Validation activities to nVIDIA; 4. Maintain and Improve customer's satisfaction with issue on-site support; 1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent; 2. Understanding Electronic Basic & Advanced Theory and semiconductor industry 3. At least 2 years’ experience, with Auto memory product is highly preferred; 4. Familiar with Automotive applications is highly preferred. 5. Good command of oral and written English; Good Korean is highly preferred; https://dearsamsung.zhiye.com/#/samsung/pc/szzw
38 [社会招聘] Memory FAE|存储芯片技术支持 岗位职责: 任职资格: 1. Promote and Design in SSD products to PC customers in East China. 2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM 3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win. 4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements 1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market. 3. Experience and knowledge in SSD products is preferred. https://dearsamsung.zhiye.com/#/samsung/pc/szzw
File diff suppressed because one or more lines are too long
-187
View File
@@ -1,187 +0,0 @@
[
{
"job_title": "[社会招聘] 三星SDSC IT售前支持",
"description": "岗位职责:\n任职资格:\n1. 根据客户情况提供合理的解决方案,\n2. 项目的整体规划,日程管理,风险管理,品质管理,验收报告等,\n3. 编写项目相关文档,确保项目资料的收集、整理、建档和保存,\n4. 公司运营,采购,执行等相关部门的业务协调等。\n1. 学历专业:正规院校本科及以上学历,双证齐全,专业不限;\n2. 工作经验:\n- 3~5年销售经验或者软件开发目管理经验\n- 有大型项目参与经验者优先\n3. 技术能力:\n- CRM,SAP,RMS,WMS等相关系统项目管理经验\n- 熟悉Java、C#等主流编程语言‌者优先\n- 了解HTML、CSS、JavaScript,熟悉Vue、React等前端框架\n- 了解TCP/IP、HTTP等网络协议,熟悉Socket编程\n- 了解Python编程基础,熟悉Django、Flask等框架,了解MongoDB、Linux系统操作\n- 了解服务器,网络设备等相关内容者优先\n4. 综合素质:\n- 了解韩国文化,理解韩国文化\n- 为人正直,有责任心,积极主动,逻辑清晰,具备优秀沟通、宣讲及文案能力\n- 具备良好的沟通能力和方案撰写能力,能够与客户和团队成员有效沟通‌\n5.语言:无限制,如懂韩语优先\n6.其他:取得PMP资格证优先,接受出差",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] 三星SDSC IT销售代表(韩语)",
"description": "岗位职责:\n任职资格:\n1. 挖掘可购买公司产品及服务的企业客户与商机;\n2. 挖掘可与公司开展业务合作的销售及交付合作伙伴;\n3. ‌分析客户IT需求,基于公司与合作伙伴的产品及能力制定解决方案与业务提案;\n4. 通过分析公司产品及能力,开发服务产品并提出销售方案等;\n5.公司内部销售系统处理及管理: 订单录入,成本确认,合同处理,损益确认,计划录入等。\n1. 正规院校本科及以上学历,双证齐全;\n2. 工作经验:\n- 拥有IT销售经验或在IT服务行业工作过经验;\n- 具有云计算相关的销售或技术工作经验,特别是AWS相关经验者优先考虑;\n3. 技术能力:\n- 对最新的IT技术趋势的广泛理解\n- 熟练使用MS Office软件(ExcelWordPPT\n4. 语言要求:韩语精通(必须)\n5.其他:接受短期出差",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "无线通信CUDA开发工程师",
"description": "岗位职责:\n任职资格:\n1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求;\n2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案;\n3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告;\n1. 硕士及以上学历,计算机科学/通信等相关专业;\n2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧;\n3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力;\n4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先;\n5. 有基于GPU的算力利用率提升项目经验者优先;\n6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "人形机器人全身运动控制算法工程师(强化学习方向)",
"description": "岗位职责:\n任职资格:\n1. 负责基于强化学习的人形机器人全身运动控制算法研发,涵盖行走、跑跳、平衡控制、复杂地形适配、动态抗扰动、全身协同运动规划等核心场景的算法设计、迭代与优化;\n2. 设计适配人形机器人高自由度特性的强化学习算法框架与深度网络架构,解决全身运动的稳定性、泛化性、实时性与安全性核心问题,持续提升机器人在复杂动态环境下的运动性能上限;\n3. 负责算法的仿真验证、sim-to-real迁移优化与人形机器人真机部署调试,结合视觉、力觉、IMU等多模态传感器反馈完成闭环控制优化,完成算法性能指标的评估、迭代与落地;\n4. 与感知、硬件、任务规划等跨团队紧密协作,推动算法与人形机器人本体、多模态感知系统的深度适配与集成,支撑整机运动能力的落地与产品化迭代;\n5. 持续跟踪人形机器人全身运动控制、深度强化学习领域的国际前沿研究与技术动态,引入顶会顶刊的创新方法,推动核心技术的突破与技术壁垒构建;\n1. 硕士及以上学历,计算机科学与技术、人工智能、自动化、控制工程、机器人工程等相关专业,具备扎实的自动控制理论、刚体动力学与机器学习理论基础;\n2. 精通深度强化学习算法原理与工程落地,熟悉PPO、SAC、TD3、DQN等主流DRL算法,具备基于强化学习的机器人运动控制算法完整研发与落地经验;\n3. 精通人形机器人正逆运动学、刚体动力学建模,熟悉高自由度机器人全身运动控制相关理论,具备人形机器人全身运动控制项目研发经验者优先;\n4. 熟练使用PyTorch/TensorFlow等主流深度学习框架,精通Python/C++编程语言,熟悉ROS/ROS2等机器人软件框架,掌握Isaac Lab、Isaac Gym、MuJoCo、Gazebo等主流机器人仿真环境;\n5. 熟悉模仿学习、逆强化学习、sim-to-real迁移、模型预测控制(MPC)、最优控制、数值优化等相关技术,具备多模态感知与运动控制融合开发经验者优先;\n6. 具备良好的科研能力、工程落地能力与跨团队协作能力,在机器人、强化学习相关领域顶会顶刊(RSS、CoRL、ICRA、IROS、NeurIPS、ICML、ICLR等)发表过论文者优先。\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "AI软件工程师",
"description": "岗位职责:\n任职资格:\n工作职责:\n- 数据中心AI系统架构与系统软件设计。\n任职资格:\n1. 熟练使用C/C++/Python,熟悉常用数据结构与算法;\n2. 熟悉大语言模型推理,有相关开发、分析和优化经验;\n3. 具备AI infrastructure分析和优化经验;\n4. 对系统软件研发有强烈兴趣。\n5. 以下为加分项:\n- 具备OpenCL,CUDA等开发和优化经验;\n- 具备模拟器开发、系统仿真分析和优化经验。\n\n其他要求:\n本科/硕士学历\nCET4及以上\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。\n 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: \n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 \n同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; \n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; \n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "Edge AI软件工程师",
"description": "岗位职责:\n任职资格:\n工作职责:\n- 端侧系统架构,算法及系统软件设计。\n任职资格:\n1. 熟练使用C/C++/Python,熟悉常用数据结构与算法;\n2. 熟悉VLM、VLA,掌握模型训练、推理、优化相关知识,并有实际开发部署经验;\n3. 具备模拟器开发、系统仿真分析和优化经验;\n4. 有良好的沟通和学习能力。\n5. 以下为加分项:\n- 具备OpenCL,CUDA开发和优化经验;\n- 具备GPU,NPU设计经验;\n- 对机器人方向算法优化和系统软件研发有强烈兴趣。\n其他要求:\n本科及以上学历\nCET4及以上\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。\n 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: \n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 \n同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; \n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; \n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "技术战略分析师",
"description": "岗位职责:\n任职资格:\n岗位职责:\n- 技术分析:从技术视角深入研究前沿科技,重点聚焦人工智能、存储技术、高性能计算等领域,开展系统性调研并撰写高质量的技术分析报告,助力技术决策与战略布局。\n- 行业洞察:紧跟国内外技术发展趋势,研判技术演进方向与竞争态势,为集团战略决策提供坚实依据。\n- 专家访谈:积极与行业专家保持深入沟通,建立长期合作关系,获取第一手权威见解与前沿信息。\n- 论文管理:负责公司学术论文的评审与发表流程的统筹与优化,推动论文质量稳步提升,增强公司学术影响力。\n- 业务支援:参与公司中长期技术规划,协助组织并推进技术创新相关活动,提升研发效率与创新能力。\n岗位要求:\n1. 人工智能、存储技术、计算机科学等相关专业背景,有在人工智能、存储系统、高性能计算等领域的工作经验者优先。\n2. 对前沿技术保持高度关注,具备独立开展技术调研的能力,能够撰写逻辑清晰、内容详实的技术分析报告。\n3. 能够熟练阅读英文技术文档与学术论文,准确把握核心思想与创新点,以及优秀的英语口语交流能力。\n4. 对新技术有热情,独立问题解决能力,海外同事合作能力\n5. 以下为加分项:\n- 有韩语能力者优先,能进行基本的书面或口语交流。\n- 有技术研发经验者优先。\n- 有深度技术调研报告撰写经验者优先。\n其他要求:\n- 硕士/博士学历\n- 人工智能、存储技术、计算机科学等相关专业\n- 英语六级(CET-6)或同等级英语水平及以上\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。\n 《个人信息收集使用申明》 在本次招聘活动中,我们承诺以下事项: \n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 \n同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; \n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; \n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "存储软件开发系统工程师",
"description": "岗位职责:\n任职资格:\n岗位职责:\n- 负责三星存储产品系统软件开发及性能优化;\n- 负责三星存储系统前沿技术研究。\n岗位要求:\n1. 具备良好的编程基础,熟练掌握C/C++/Python至少一种编程语言;\n2. 熟练掌握常用数据结构及算法;\n3. 熟悉Linux系统的编程基础,熟悉Linux I/O相关协议栈。\n4. 以下为加分项:\n- 具有数据库,存储引擎以及文件系统相关开发和优化经验者;\n- 具备AI框架下存储相关研究经验。\n其他要求:\n- 硕士学历\n- 计算机、软件、电子,通信,自动化等相关专业\n- CET4及以上\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 \n请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 \n《个人信息收集使用申明》 \n在本次招聘活动中,我们承诺以下事项:\n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息;\n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; \n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;\n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "分布式系统软件工程师",
"description": "岗位职责:\n任职资格:\n岗位职责:\n- 负责三星大规模集群系统任务调度及资源管理方案的优化与开发;\n- 提升大规模集群的调度系统的整体效率和资源利用率。\n岗位要求:\n1. 具有扎实的shell/C++/Python编程基础,熟悉数据结构和算法;\n2. 掌握计算机操作系统,分布式系统等专业知识;\n3. 熟悉多线程开发,有良好的代码阅读和开发能力。\n4. 以下为加分项:\n- 具有Slurm, LSF, Kubernetes的代码经验或者部署经验。\n其他要求:\n- 硕士学历\n- 计算机、人工智能等相关专业\n- CET4及以上\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 \n请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。\n《个人信息收集使用申明》 \n在本次招聘活动中,我们承诺以下事项:\n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 \n同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。\n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;\n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查;\n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密;\n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "存储软件工程师(AI算法方向)",
"description": "岗位职责:\n任职资格:\n岗位职责:\n- 负责三星存储产品相关AI算法的设计、训练、优化和研发。\n岗位要求:\n1. 精通Python,熟悉C/C++语言,熟练掌握常用的数据结构和算法;\n2. 掌握机器学习/深度学习算法模型构建、训练、优化相关专业知识并有相关经验;\n3. 能熟练使用PyTorch等框架进行模型的开发和优化;\n4. 具有较强的动手能力和研究能力,能够快速复现论文方法,并针对特定的场景进行优化;\n5. 以下为加分项:\n- 具备AI框架下存储相关研究经验;\n- 有顶会/顶刊论文相关成果者优先;\n- 有transformer,大模型研发经验者优先。\n其他要求:\n- 硕士学历\n- 计算机、软件、大数据、人工智能等相关专业\n- CET4及以上\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注! \n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。\n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 \n《个人信息收集使用申明》 \n在本次招聘活动中,我们承诺以下事项: \n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为;\n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; \n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "存储系统专家",
"description": "岗位职责:\n任职资格:\n岗位职责:\n- 作为团队技术带头人,负责存储系统软件架构设计和实现以及存储系统的应用优化; \n- 负责三星存储相关新技术解决方案的研究以及学术成果转化。\n岗位要求:\n1. 熟悉NVMe SSD相关知识且具备存储设备性能优化经验;\n2. 熟悉Linux内核I/O协议栈,具备SPDK等用户态驱动开发和优化经验;\n3. 较强的软件架构以及代码重构能力;\n4. 了解数据库以及常用存储引擎相关知识以及体系架构 (Rocks DB, MySQL.),并有相应系统设计开发以及优化经验。\n加分项: \n- 熟悉新的Memory技术如CXL,有相关研究经验者优先;\n- 具备AI框架下存储相关研究经验者优先; \n- 在该领域顶级会议或期刊发表过论文者优先。\n其他要求:\n- 博士学历\n- 计算机、软件、电子、通信、自动化等相关专业\n- CET6及以上,英语可作为工作语言\n\n\n\n感谢您对三星(中国)半导体有限公司下属西安三星电子研究所的关注!\n三星(中国)半导体有限公司高度重视用户的个人信息,并严格遵守《中华人民共和国个人信息保护法》及相关法律法规进行个人信息的收集、使用、安全管理。 请您在投递简历前认真认真阅读以下内容,确认后完成简历投递。 \n若您已经成功投递简历则表示您已经同意授权个人信息至西安三星电子研究所招聘活动并承诺以下申明。 \n《个人信息收集使用申明》 \n在本次招聘活动中,我们承诺以下事项: \n1.我们收到的个人信息仅用于本次您所投递三星(中国)半导体有限公司下属西安三星电子研究所的招聘岗位及可能录取后的招聘活动管理中,并保证未经本人同意不向第三方披露; 如果您没有被录取,我们将在招聘结束后销毁文本和电子信息; 个人信息及包括但不限于以下信息:姓名、性别、出生日期、籍贯、现居住城市、电话、邮箱、教育背景(学校、学历学位、专业、在学时间)、工作履历(公司名称、职位、在职时间、离职原因、税前工资)等一般个人信息;个人照片等敏感个人信息; \n2.我们不会在招聘中询问您现在或以前工作单位的任何商业秘密,并保证不会因此影响招聘结果; \n3.在招聘中如果有任何您认为不适当的行为或询问,您都有权拒绝;我们保证不会因此影响招聘结果。 \n同时也请您阅读以下事项,并保证以下内容真实性;如果内容虚假,本人愿意接受因此为三星(中国)半导体有限公司下属西安三星电子研究所带来的任何不良后果,并承担由此给公司造成的任何损失。 \n1.我在自愿的情况下同意投递三星(中国)半导体有限公司下属西安三星电子研究所招聘岗位收集以上信息,并允许公司在招聘和可能录取后的招聘活动管理中使用; \n2.我保证在本次招聘中提供的个人信息真实,并认可公司对虚假个人信息的处理行为; \n3.我允许招聘公司对我提供的个人信息在法律许可的范围内进行背景调查; \n4.我在此次招聘或将来入职后,将对现公司、前公司的商业秘密进行保密; \n5.若本人还存在与原公司在有效期内的竞业限制协议,将在招聘过程中如实告知公司。 \n如您需取消投递,请自行撤销简历;\n若需帮助请联系HRsrcxianhr@samsung.com。",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "大模型算法工程师",
"description": "岗位职责:\n任职资格:\n1. 参与基础大模型和端侧大模型的研发工作,包括架构设计、预训练、后训练等,端到端构建通用大模型;\n2. 负责大模型高阶能力(Coding、Agent等)的专项提升,打造模型长版特性;\n3. 持续关注大模型最新研究,探索下一代大模型的架构和训练方法,做出有影响力的成果;\n1. 硕士及以上学历,计算机科学、人工智能等相关专业;\n2. 熟悉深度学习框架(例如pytorch等),具备大模型和端侧大模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验;\n3. 对大模型架构、训练、数据、系统优化中的某一方面有深入理解,以下符合1条以上:\n- 能够提出创新性的大模型架构和端侧大模型架构,探索技术的下一跳;\n- 熟练掌握强化学习(RL)和模型微调(SFT)等后训练技术,并可以提出创新的后训练方法;\n- 对coding、math、agent等大模型高阶能力有深入思考;\n- 熟练掌握大模型预训练的Know How,可以快速诊断并修复问题,提升模型能力;\n- 对预训练数据、后训练数据的生产、合成方法有深入理解;\n- 熟练模型训练/推理的系统优化方法,提升模型的实际训练、推理性能;\n4. 有大模型/端侧大模型架构、训练、数据、系统优化等相关实战经验者优先,在NeurIPS/ICML/ICLR/ACL/EMNLP/CVPR/ICCV/TPAMI等AI顶会发表过相关论文者优先;\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "具身智能算法工程师",
"description": "岗位职责:\n任职资格:\n1. 负责研发具身智能操作算法,研发基于VLA、强化学习等AI技术在机器人操作场景中的应用;\n2. 设计网络架构,分析实验数据,评估算法表现,提升机器人在精准操作、长程任务、动态响应等关键领域的表现性能;\n3. 负责将VLA模型在跨机器人本体和环境进行真机部署,评估模型在真机的性能指标;\n4. 持续跟进最新的具身操作方向研究工作动态,引入最前沿的方法持续提升模型表现性能;\n1. 硕士及以上学历,计算机科学、人工智能、自动化、机器人技术等相关专业;\n2. 熟悉深度学习框架(例如pytorch、TensorFlow),具备大规模VLA模型的算法开发经验,具备数据处理、模型架构设计、大规模训练等经验;\n3. 具备机器学习算法在机器人领域的开发经验,包括并不限于reinforcement learning、imitation learning、transfer learning、action-conditioned world models、representation learning、dexterous manipulation、sim-to-real transfer、vision language models、motion planning等;\n4. 具备机器人真机经验(例如Aloha、Franka、Fetch等),具备良好的编程能力,熟悉Python或C++编程语言,熟悉主流机器人软件框架例如ROS,熟悉主流的仿真软件例如IsaacLab、IsaacGym、Mujoco、Bullet、Gazebo等;\n5. 具备良好的科研能力,在顶会或期刊发表过文章的优先,例如机器学习方向(NeurIPS、ICML、ICLR),机器人方向(RSS、CoRL、ICRA、IROS)、计算机视觉方向(CVPR、ICCV、ECCV)等;\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "高性能并行计算开发工程师",
"description": "岗位职责:\n任职资格:\n1. 根据无线通信模块需要,基于CPU/GPU设计适合并行计算的数据结构,利用多线程实现高效的并行计算处理编程;\n2. 具有较高的并行计算/高性能计算方面SW设计及开发能力,能通过性能分析找到CPU或GPU处理的瓶颈,并提出改善方案;\n1. 硕士及以上学历,计算机科学/人工智能等相关专业;\n2. 精通高性能计算/并行计算软件设计及优化思想,具有多线程并行计算开发经验;\n3. 熟练使用CPU/GPU性能分析工具(Nsight等)并通过性能监测找到存储,数据传输,并行计算中的瓶颈点,并结合数据访存和并行计算能力设计最优SW方案;\n4. 有GPU高性能计算/CUDA开发经验者优先;\n5. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "无线通信CUDA开发工程师",
"description": "岗位职责:\n任职资格:\n1 基于Nvidia GPU架构进行无线通信物理层核心算法的CUDA加速实现,包括OFDM调制,信道估计,检测均衡等模块,满足5G/6G商用化部署实时性要求;\n2 针对无线通信中密集计算模块优化CUDA内存代码,实现基于GPU的高效并行计算和内存访问,提供有竞争力的CUDA SW设计方案;\n3 能联合无线通信基带算法团队,完成CUDA加速模块开发;能支持与CPU等其他处理器联调测试及优化,输出相关的优化报告;\n1. 硕士及以上学历,计算机科学/通信等相关专业;\n2. 精通CUDA C/C++编程模型,深入理解GPU内存层次(全局,共享,常量,寄存器等)、线程调度机制、掌握CUDA core/Tensor Core并行加速技巧;\n3. 熟练使用Nvidia性能分析工具(Nsight/nvprof等)具备复杂算法的并行设计与调优能力;\n4. 熟悉异构架构(GPU+CPU),有CPU/GPU混合编程优化经验者优先;\n5. 有基于GPU的算力利用率提升项目经验者优先;\n6. 出色的英文表达能力,以及在快节奏环境中独立和协作工作的能力。\n\n公司介绍:\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\n\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "SCS-技术员",
"description": "岗位职责:\n任职资格:\n1.负责现场设备日常维护工作;\n2.协助工程师进行调试工作,进行设备日常作业;\n3.根据作业标准要求进行设备的操作。\n1.学历:25~26届毕业大专生;\n2.专业:机械类、电气类、自动化类、计算机类、电子类等理工科相关专业;\n3.熟练使用Office办公软件;\n4.能适应倒班工作(三班倒)。\n(早班:6:00-14:00;中班:14:00-22:00;晚班:22:00-06:00,上五休二,每班工作8小时)",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "知识图谱、智能体、大模型算法工程师",
"description": "岗位职责:\n任职资格:\n从事知识图谱,大语言模型、多智能体优化的前沿算法研究:\r\n- 研究方向包括:知识图谱,智能体设计, 大模型RAG, 多智能体优化\r\n- 算法领域包括但不限于: Knowledge Graph, Graph Retrieval, AI Agent, RAG, LLM/VLM/LMM, CoT, etc.\n1. 硕士及以上学历,计算机、电子、自动化、数学等相关专业;\r\n2. 熟练掌握智能体设计,大模型微调等相关基础;\r\n3. 对知识图谱,大模型/RAG/Agent/Retrieval 有相关开发经验;\r\n4. 熟悉PythonPyTorch深度学习框架;\r\n5. 对前沿技术有热情,有较强的独立工作能力(算法理解与实现,问题分析与解决);\r\n[加分项] 在顶会NIPS,ICML等发表过高水平文章,或在权威竞赛中以主要参与者身份取得过优秀名次;\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "通信AI算法工程师",
"description": "岗位职责:\n任职资格:\n1. 网络优化和诊断的AI算法研究; \r\n2. AI算法实现,优化和评估; \r\n3. 网络性能问题研究;\n1. 博士及以上学历,通信工程、电子工程、计算机等相关专业;\r\n2. 对AI算法有深入研究; \r\n3. 具有AI算法编码和应用经验; \r\n4. 擅长应用问题的算法建模; \r\n5. 有无线通信的AI算法研究经验者优先; \r\n6. 对AI算法有广泛实用经验者优先。\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "数字孪生算法工程师",
"description": "岗位职责:\n任职资格:\n1. 5G-A/5G+AI MAC/RLC/PDCP系统算法研究、设计工作;\r\n2. Ray tracing/3GPP信道建模算法研究、设计工作;\r\n3. 5G-A/5G+AI 系统级仿真分析工作;\r\n4. 指导和协助开发 S/W实现与优化工作。\n1. 硕士及以上学历,博士优先,通信工程、计算机等相关专业;\r\n2. 对5GA/5G协议和系统有深入了解和相应研究经历;\r\n3. 有MAC/RLC/PDCP/PHY算法设计和研究经验;\r\n4. 有信道建模设计和研究经验;\r\n5. 有系统级/链路级+AI仿真经验;\r\n6. 熟练掌握C/C++Python编程;\r\n7. 有良好的英语交流能力,积极进取,有良好的团队合作意识和技术创新意识。\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "5G/5GA算法工程师",
"description": "岗位职责:\n任职资格:\n1. LTE/5G MAC、SON系统算法研究、设计工作;\r\n2. LTE/5G系统级仿真、分析工作;\r\n3. 5G 链路级仿真工作;\r\n4. 指导和协助开发 S/W实现与测试工作;\r\n5. 系统级advance算法相关研究工作。\n1. 硕士及以上学历,博士优先,通信工程、电子相关专业;\r\n2. 对LTE/5G/5GA协议和系统有深入了解和相应研究经历;\r\n3. 有MAC、SON算法设计和研究经验;\r\n4. 有系统级或者链路级仿真经验,熟练掌握C/C++/matlab/python编程;\r\n5. 有5G/5GA标准化经验者优先考虑;\r\n6. 有丰富MIMO, SON相关研究经验者优先考虑;\r\n7. 有良好的英文交流能力;\r\n8. 积极进取,有良好的团队合作意识,技术创新意识。\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "通信SoC软件开发工程师",
"description": "岗位职责:\n任职资格:\n1. 负责OMMU/ORU LPHY模块设计和开发;\r\n2. 负责ORAN-based LPHY模块性能优化;\n1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业;\r\n2. 精通C/C++,熟悉架构设计及优化者优先;\r\n3. 熟悉基于通信基带SoC芯片的软件开发,优化和测试过程,有Marvell通信芯片软件开发经验者优先;\r\n4. 熟悉3GPP协议,ORAN协议,具有ORAN Opt7-2x/Opt7-3开发经验者优先;\r\n5. 熟悉RTOS,Linux驱动开发经验者优先;\r\n6. 具备良好的数字信号处理背景优先; \r\n7. 良好的英文书面和口语表达。\r\n加分项:\r\n- 熟悉常用AI算法模型,有广泛实用经验/模型部署移植等相关经验;\r\n- 有DFE(digital front-end)开发经验;\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "4G/5G 物理层开发工程师",
"description": "岗位职责:\n任职资格:\n按照经验能力参与以下工作的一项或多项,包括:\r\n1. 负责4G/5G物理层接收机&发送机的算法模块SW实现;\r\n2. 负责基站侧或终端侧 Modem 架构设计及SW开发;\r\n3. 负责AI+5G开发及优化;\r\n4. 负责数字孪生开发和验证;\n1. 硕士及以上学历,通信、信号处理、计算机、电子及相关专业;\r\n2. 精通C/C++语言,熟悉架构设计及优化者优先;\r\n3. 熟悉至少一种CPU结构及指令,有Intel AVX512/AMX优化经验者优先;\r\n4. 熟悉至少一种无线通信协议,有NR、LTE、NB-IOT、2G GSM物理层研发经验优先;\r\n5. 熟悉3GPP信道建模优化,有digital twin经验者优先;\r\n6. 熟悉常用AI训练推理架构,熟悉常用AI算法模型者优先;\r\n7. 熟悉linux操作系统,有内核优化经验者优先;\r\n8. 具备良好的数字信号处理背景优先; \r\n9. 良好的英文书面和口语表达。\r\n\r\n公司介绍:\r\n三星电子中国研究院是三星电子在华投资设立的具有独立法人资格的研发机构,是具备博士后工作站运营资质、聚集了600人研发团队,并由国家批准认定的软件企业。研究院专注于人工智能、5G/6G通信技术研究和标准化等前沿技术,也积极进行商用化的开发、推动先进技术在三星产品中的商用化落地,提升三星电子产品的竞争力。\r\n新时代,新机遇。三星电子中国研究院希望把握人工智能、5G/6G与IoT技术发展的时代机遇,凝聚海内外计算机、电子及通信领域的优秀人才,坚守“做中国人民喜爱的企业,贡献于中国社会的企业”的承诺,与您一起携手共赢、创造未来! 真诚欢迎您的加入!\r\n\r\n※ 请应聘者在应聘过程中对现公司、 前公司的商业秘密进行保密\r\n※ 请应聘者确认您投递的简历不包含现公司、前公司的商业秘密",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "战略企划",
"description": "岗位职责:\n任职资格:\n主要职责:\n1. 销售数据分析及企划\n2. 行业市场分析\n3. 韩语翻译及部门交代的其他相关事项\n岗位要求 \n- 学历:统招本科及以上 \n- 经历:销售企划相关经历者优先考虑 \n- 熟练掌握 M/S Office (Excel, Word, PPT)\n- 韩国语能力优秀者优先考虑 (TOPIK 6级 或 近母语水平)",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory MKT|存储芯片市场",
"description": "岗位职责:\n任职资格:\n1. Establish and maintain the regular and close communication relationship with customers and colleague\r\n2. Memory business Marketer\r\n3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market\r\n4. Working closely with our customers \r\n5. Writing market analysis report\r\n6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater.\n1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ\r\n2. Experience in Memroy market and product (DRAM/SSD/GFX)\r\n3. Experience in PC martket\r\n4. Understaing of Memory business value chain including PC Market\r\n5. Sophisticated in PPT and Excel, with good presentation skills",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] DRAM BE|存储芯片市场营销",
"description": "岗位职责:\n任职资格:\n1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China;\r\n2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers.\r\n3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win.\r\n4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements.\n'1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory DRAM FAE|存储芯片技术支持",
"description": "岗位职责:\n任职资格:\n- Support DRAM failure analysis with customers and ODM venders\r\n- Prompt and professional technical on-site support for acquiring\r\n customer's demand of DRAM.\r\n - Make an initial judgement for the issues from customers\r\n - Eliminate noise and ambiguity of on-site test results\r\n - Regular technical discussion with HQ AE team and customers and \r\ncross functional departments independently.\n- Familiar with DRAM function and system operation \r\n(Command sequence/AC parameter/…).\r\n- Experience in DDR module on NB, desktop\r\n(server system design/validation is a plus)\r\n - To have analysis ability for log \r\n(system booting log and DRAM training log, etc.)\r\n - To have experience of tools updating BIOS (Dediprog, etc.)\r\n- To have basic software knowledge related to PC, Notebook\r\n(Windows, Linux, Python, etc.)\r\n- To have experience of operating oscilloscope and logic analyzer.\r\n - To have good comprehension and good communication skills with\r\nODM & customers, HQ and related departments",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] DRAM TEC|测试技术工程师",
"description": "岗位职责:\n任职资格:\n1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5)\r\n2. Attend tech. meeting with DRAM BE and CS contact window;\r\n3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support;\r\n4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage.\n- Familiar with DRAM function and system operation \r\n(Command sequence/AC parameter/…).\r\n- Experience in DDR module on NB, desktop\r\n(server system design/validation is a plus)\r\n - To have analysis ability for log \r\n(system booting log and DRAM training log, etc.)\r\n - To have experience of tools updating BIOS (Dediprog, etc.)\r\n- To have basic software knowledge related to PC, Notebook\r\n(Windows, Linux, Python, etc.)\r\n- To have experience of operating oscilloscope and logic analyzer.\r\n - To have good comprehension and good communication skills with\r\nODM & customers, HQ and related departments",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Foundry FAE|晶圆代工技术支持",
"description": "岗位职责:\n任职资格:\n1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C\r\n2. Design in (T/O) the Foundry customer product in E/C\r\n3. Build the relationship with Tier 1/2/3 customer in E/C\nEducation: Bachelor degree and above\r\nMajor: Electrical/Electronics engineering \r\nExperience Range:3 Years \r\nProf. Experience Experience in SOC design \r\nLanguage skillsFluent in English read/write/speaking \r\nMin. skills & knowledge: \r\n1. Knowledge in Semiconductor Process manufacturing, device component\r\n2. Experience on designing Digital IP, Analog IP, SOC Design\r\n3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Auto TEC|测试技术工程师",
"description": "岗位职责:\n任职资格:\n1. Responsible as TEC engineer in Mobile/Auto TEC department;\r\n2.Responsible for Auto DRAM product testing when needed.\r\n3. Suppport on-site and DRAM Validation activities to nVIDIA;\r\n4. Maintain and Improve customer's satisfaction with issue on-site support;\n1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent;\r\n2. Understanding Electronic Basic & Advanced Theory and semiconductor industry\r\n3. At least 2 years experience, with Auto memory product is highly preferred;\r\n4. Familiar with Automotive applications is highly preferred.\r\n5. Good command of oral and written English; Good Korean is highly preferred;",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory FAE|存储芯片技术支持",
"description": "岗位职责:\n任职资格:\n1. Promote and Design in SSD products to PC customers in East China.\r\n2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM\r\n3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win.\r\n4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements\n1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ.\r\n2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market.\r\n3. Experience and knowledge in SSD products is preferred.",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory MKT|存储芯片市场",
"description": "岗位职责:\n任职资格:\n1. Establish and maintain the regular and close communication relationship with customers and colleague\r\n2. Memory business Marketer\r\n3. Understanding Memory trend, perform PC market sensing, gather information of main players in PC market\r\n4. Working closely with our customers \r\n5. Writing market analysis report\r\n6. Contact closely with investiative companies such as IDC, Gartner, and Egdewater.\n1. Chinese standard language and fluent English literacy for smooth communication with customers and Korea HQ\r\n2. Experience in Memroy market and product (DRAM/SSD/GFX)\r\n3. Experience in PC martket\r\n4. Understaing of Memory business value chain including PC Market\r\n5. Sophisticated in PPT and Excel, with good presentation skills",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] DRAM BE|存储芯片市场营销",
"description": "岗位职责:\n任职资格:\n1. Promote and Design DRAM in GPU/CPU products(HBM/GDDR/SoCAMM..etc) to GPU & CPU customers in China;\r\n2. On-site Technical support to GPU/CPU Customers and manage qualification issues of customers.\r\n3. Build contact between Samsung HQ and customers, CO-work with Sales/MKT team for make products design-win.\r\n4. Regularly meet with customers to introduce Samsung memory, undertand customers' requirements.\n'1. Chinese standard language and fluent English literacy for smooth communication with customers and Samsung HQ. 2. Understanding Electronics basis, memory theory and Semiconductor industry, GPU/CPU/Server market. 3. Experience in DRAM analysis and knowledge in memory products is prefered",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory DRAM FAE|存储芯片技术支持",
"description": "岗位职责:\n任职资格:\n- Support DRAM failure analysis with customers and ODM venders\r\n- Prompt and professional technical on-site support for acquiring\r\n customer's demand of DRAM.\r\n - Make an initial judgement for the issues from customers\r\n - Eliminate noise and ambiguity of on-site test results\r\n - Regular technical discussion with HQ AE team and customers and \r\ncross functional departments independently.\n- Familiar with DRAM function and system operation \r\n(Command sequence/AC parameter/…).\r\n- Experience in DDR module on NB, desktop\r\n(server system design/validation is a plus)\r\n - To have analysis ability for log \r\n(system booting log and DRAM training log, etc.)\r\n - To have experience of tools updating BIOS (Dediprog, etc.)\r\n- To have basic software knowledge related to PC, Notebook\r\n(Windows, Linux, Python, etc.)\r\n- To have experience of operating oscilloscope and logic analyzer.\r\n - To have good comprehension and good communication skills with\r\nODM & customers, HQ and related departments",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] DRAM TEC|测试技术工程师",
"description": "岗位职责:\n任职资格:\n1. New DRAM product tech. support to customers(SOCAMM, LP5x, DDR5)\r\n2. Attend tech. meeting with DRAM BE and CS contact window;\r\n3. Quick FA support to S/C customers,improve customer's satisfaction with issue on-site support;\r\n4. To setup open lab with Main CPU vendor to minimize DRAM issue in early stage.\n- Familiar with DRAM function and system operation \r\n(Command sequence/AC parameter/…).\r\n- Experience in DDR module on NB, desktop\r\n(server system design/validation is a plus)\r\n - To have analysis ability for log \r\n(system booting log and DRAM training log, etc.)\r\n - To have experience of tools updating BIOS (Dediprog, etc.)\r\n- To have basic software knowledge related to PC, Notebook\r\n(Windows, Linux, Python, etc.)\r\n- To have experience of operating oscilloscope and logic analyzer.\r\n - To have good comprehension and good communication skills with\r\nODM & customers, HQ and related departments",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Foundry FAE|晶圆代工技术支持",
"description": "岗位职责:\n任职资格:\n1. Develop and Design Award (D/A) Tier 1/2/3 Foundry customer in E/C\r\n2. Design in (T/O) the Foundry customer product in E/C\r\n3. Build the relationship with Tier 1/2/3 customer in E/C\nEducation: Bachelor degree and above\r\nMajor: Electrical/Electronics engineering \r\nExperience Range:3 Years \r\nProf. Experience Experience in SOC design \r\nLanguage skillsFluent in English read/write/speaking \r\nMin. skills & knowledge: \r\n1. Knowledge in Semiconductor Process manufacturing, device component\r\n2. Experience on designing Digital IP, Analog IP, SOC Design\r\n3. Experience on standard cell characterization, timing sign off (STA), synthesis, P&R, etc",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Auto TEC|测试技术工程师",
"description": "岗位职责:\n任职资格:\n1. Responsible as TEC engineer in Mobile/Auto TEC department;\r\n2.Responsible for Auto DRAM product testing when needed.\r\n3. Suppport on-site and DRAM Validation activities to nVIDIA;\r\n4. Maintain and Improve customer's satisfaction with issue on-site support;\n1. Electronic Engineering, Electronic Automation, Computer Science, Telecommunication or equivalent;\r\n2. Understanding Electronic Basic & Advanced Theory and semiconductor industry\r\n3. At least 2 years experience, with Auto memory product is highly preferred;\r\n4. Familiar with Automotive applications is highly preferred.\r\n5. Good command of oral and written English; Good Korean is highly preferred;",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
},
{
"job_title": "[社会招聘] Memory FAE|存储芯片技术支持",
"description": "岗位职责:\n任职资格:\n1. Promote and Design in SSD products to PC customers in East China.\r\n2. Technical support to PC Customers and manage SSD qualification process&status&issue with customer and its ODM\r\n3. Build contact between Samsung HQ and customers, co-work with Sales/MKT team for making products design-win.\r\n4. Regularly meet with customers and Samsung HQ to introduce Samsung SSD product, understand customers' requirements\n1. Chinese standard language and fluent English literacy for smooth communication with customers and HQ.\r\n2. Understanding Electronics basis, memory theory and Semiconductor industry, Smartphone/Consumer electronics market.\r\n3. Experience and knowledge in SSD products is preferred.",
"detail_url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
}
]
-32
View File
@@ -1,32 +0,0 @@
# LangChain
langchain>=0.3.0
langchain-core>=0.3.48
langchain-openai>=0.3.0
langchain-deepseek>=0.1.0
langgraph>=0.2.0
# MCP
mcp>=1.0.0
langchain-mcp-adapters>=0.1.0,<=0.1.14
# Browser
playwright>=1.40.0
playwright-stealth>=1.0.0
# Database
sqlalchemy>=2.0.0
pymysql>=1.1.0
# Scheduler
apscheduler>=3.10.0
# HTTP Client
httpx>=0.27.0
# Excel
openpyxl>=3.1.0
# Web Framework
fastapi>=0.115.0
uvicorn>=0.30.0
-173
View File
@@ -1,173 +0,0 @@
"""Manual entry point for testing the formal Step5 crawl-and-save pipeline."""
from __future__ import annotations
import argparse
import asyncio
import logging
import sys
from contextlib import contextmanager
from datetime import datetime
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from src.config import settings # noqa: E402
from src.database import CrawlTask, JobData, SessionLocal, TaskCrawl # noqa: E402
from src.scheduler.jobs import job_step5_crawl # noqa: E402
SAMSUNG_CONFIG = {
"url": "https://dearsamsung.zhiye.com/#/samsung/pc/szzw",
"job_item_selector": ".BHGkB li",
"item_change_type": "in_page",
"next_page_selector": "._8x6MD .ant-pagination-next:not([aria-disabled='true']) .ant-pagination-item-link",
"page_change_type": "content_change",
"detail_area_selector": ".FLf6j",
"field_selectors": {
"job_title": {"selector": ["h2"]},
"description": {"selector": [".aCl-8 p", ".aCl-8 pre"]},
},
}
@contextmanager
def temporarily_pause_other_pending_tasks(db, current_task_id: int):
"""Make job_step5_crawl pick the task created by this script."""
paused_ids = [
row.id
for row in db.query(TaskCrawl.id)
.filter(TaskCrawl.status == "pending", TaskCrawl.id != current_task_id)
.all()
]
if paused_ids:
db.query(TaskCrawl).filter(TaskCrawl.id.in_(paused_ids)).update(
{TaskCrawl.status: "manual_paused"},
synchronize_session=False,
)
db.commit()
try:
yield paused_ids
finally:
if paused_ids:
db.query(TaskCrawl).filter(TaskCrawl.id.in_(paused_ids)).update(
{TaskCrawl.status: "pending"},
synchronize_session=False,
)
db.commit()
def create_manual_task(company_name: str) -> tuple[int, int]:
db = SessionLocal()
try:
crawl_task = db.query(CrawlTask).filter(CrawlTask.company_name == company_name).first()
if crawl_task is None:
crawl_task = CrawlTask(
company_name=company_name,
config_step=4,
config_status="success",
crawl_status="pending",
)
db.add(crawl_task)
db.flush()
else:
crawl_task.config_step = 4
crawl_task.config_status = "success"
crawl_task.crawl_status = "pending"
task_crawl = TaskCrawl(
crawl_task_id=crawl_task.id,
status="pending",
max_retry=1,
input_config=SAMSUNG_CONFIG,
)
db.add(task_crawl)
db.commit()
return crawl_task.id, task_crawl.id
finally:
db.close()
def print_result(crawl_task_id: int, task_crawl_id: int) -> None:
db = SessionLocal()
try:
task = db.query(TaskCrawl).filter(TaskCrawl.id == task_crawl_id).first()
inserted_count = db.query(JobData).filter(JobData.task_crawl_id == task_crawl_id).count()
print()
print("Manual Step5 crawl finished")
print(f"crawl_task_id: {crawl_task_id}")
print(f"task_crawl_id: {task_crawl_id}")
print(f"status: {task.status if task else 'missing'}")
print(f"crawled_count: {task.crawled_count if task else None}")
print(f"inserted_count: {inserted_count}")
if task and task.error_message:
print(f"error_message: {task.error_message}")
print()
print("Check task status:")
print(
"SELECT id,status,crawled_count,error_message,started_at,finished_at "
"FROM table_comple.app_task_crawl "
f"WHERE id = {task_crawl_id};"
)
print()
print("Check saved jobs:")
print(
"SELECT id,job_title,company,recruit_category,created_at "
"FROM table_comple.app_job_data "
f"WHERE task_crawl_id = {task_crawl_id} "
"ORDER BY id LIMIT 50;"
)
finally:
db.close()
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Create one formal Step5 crawl task and run job_step5_crawl()."
)
parser.add_argument(
"--company",
default=f"manual_samsung_test_{datetime.now():%Y%m%d_%H%M%S}",
help="Company name saved into app_crawl_task/app_job_data.company.",
)
parser.add_argument(
"--headless",
action="store_true",
help="Run Chromium in headless mode. Default opens a visible browser.",
)
return parser.parse_args()
async def main() -> None:
args = parse_args()
settings.browser_headless = bool(args.headless)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
crawl_task_id, task_crawl_id = create_manual_task(args.company)
print(f"Created formal Step5 task: crawl_task_id={crawl_task_id}, task_crawl_id={task_crawl_id}")
db = SessionLocal()
try:
with temporarily_pause_other_pending_tasks(db, task_crawl_id) as paused_ids:
if paused_ids:
print(f"Temporarily paused other pending Step5 tasks: {paused_ids}")
await job_step5_crawl()
finally:
db.close()
print_result(crawl_task_id, task_crawl_id)
if __name__ == "__main__":
asyncio.run(main())
-79
View File
@@ -1,79 +0,0 @@
#!/bin/bash
# 配置
APP_NAME="crawler"
APP_DIR="/opt/app/crawler"
VENV_DIR="$APP_DIR/venv"
LOG_FILE="$APP_DIR/app.log"
PID_FILE="$APP_DIR/app.pid"
DISPLAY_NUM=":1"
# 启动
start() {
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "$APP_NAME 已经在运行 (PID: $(cat $PID_FILE))"
return 1
fi
echo "启动 $APP_NAME..."
cd "$APP_DIR"
source "$VENV_DIR/bin/activate"
nohup env DISPLAY=$DISPLAY_NUM python -m uvicorn src.main:app --host 0.0.0.0 --port 8000 > "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
echo "$APP_NAME 已启动 (PID: $!)"
}
# 停止
stop() {
if [ ! -f "$PID_FILE" ]; then
echo "$APP_NAME 未运行"
return 1
fi
PID=$(cat "$PID_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "停止 $APP_NAME (PID: $PID)..."
kill "$PID"
rm -f "$PID_FILE"
echo "$APP_NAME 已停止"
else
echo "$APP_NAME 未运行,清理 PID 文件"
rm -f "$PID_FILE"
fi
}
# 重启
restart() {
stop
sleep 2
start
}
# 状态
status() {
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
echo "$APP_NAME 运行中 (PID: $(cat $PID_FILE))"
else
echo "$APP_NAME 未运行"
fi
}
# 查看日志
logs() {
tail -f "$LOG_FILE"
}
# 使用说明
usage() {
echo "用法: $0 {start|stop|restart|status|logs}"
}
# 主逻辑
case "$1" in
start) start ;;
stop) stop ;;
restart) restart ;;
status) status ;;
logs) logs ;;
*) usage ;;
esac
-1
View File
@@ -1 +0,0 @@
"""src 包"""
Binary file not shown.
Binary file not shown.
-91
View File
@@ -1,91 +0,0 @@
from langchain_openai import ChatOpenAI
from openai import OpenAI
from src.config import settings
################################
##### 基础模型
################################
V3_2 = ChatOpenAI(
base_url=settings.ai_base_url,
model="deepseek-v3-2-251201",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature,
model_kwargs={"response_format": {"type": "json_object"}} # 强制 JSON 模式
)
Pro32 = ChatOpenAI(
base_url=settings.ai_base_url,
model="doubao-1-5-pro-32k-250115",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature
)
Gemini25 = ChatOpenAI(
base_url="https://api-i.xykjy.com/v1",
model="gemini-2.5-flash",
api_key="sk-8NxoLe7ZTJveGSmtPENBm4NwN9ai4YLGw8y6fqueZrPTo4Uu",
temperature=settings.ai_temperature
)
K2 = ChatOpenAI(
base_url=settings.ai_base_url,
model="kimi-k2-thinking-251104",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature,
model_kwargs={
"response_format": {"type": "json_object"},
} # 强制 JSON 模式
)
V3_1 = ChatOpenAI(
base_url=settings.ai_base_url,
model="deepseek-v3-1-terminus",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature,
model_kwargs={
"response_format": {"type": "json_object"}
} # 强制 JSON 模式
)
Seed_2_Code = ChatOpenAI(
base_url=settings.ai_base_url,
model="doubao-seed-2-0-code-preview-260215",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature
)
Seed_Code = ChatOpenAI(
base_url=settings.ai_base_url,
model="doubao-seed-code-preview-251028",
api_key=settings.ai_api_key,
temperature=settings.ai_temperature
)
Opus = ChatOpenAI(
base_url="https://ai.hhhl.cc/v1",
model="claude-opus-4-5-20251101",
api_key="sk-txcM6uEk0LBGFUmw70sCdeeVoVrP7LxX",
temperature=settings.ai_temperature
)
# 通用模型
GeneralLlm = V3_2
# 分析主要模型
AnalyseLlm = K2
if __name__ == "__main__":
client = OpenAI(
base_url="https://ai.hhhl.cc/v1",
api_key="sk-txcM6uEk0LBGFUmw70sCdeeVoVrP7LxX"
)
for m in client.models.list().data:
print(m.id)
-126
View File
@@ -1,126 +0,0 @@
"""全局浏览器管理"""
import random
from playwright.async_api import async_playwright, Browser, BrowserContext, Playwright
from playwright_stealth import Stealth
from src.config import settings
_playwright: Playwright | None = None
_browser: Browser | None = None
# 指纹配置池
VIEWPORTS = [
{"width": 1920, "height": 1080},
{"width": 1366, "height": 768},
{"width": 1536, "height": 864},
{"width": 1440, "height": 900},
{"width": 1280, "height": 720},
{"width": 1600, "height": 900},
{"width": 1680, "height": 1050},
{"width": 1280, "height": 800},
{"width": 1024, "height": 768},
{"width": 1920, "height": 1200},
{"width": 2560, "height": 1440},
{"width": 1360, "height": 768},
{"width": 1280, "height": 1024},
{"width": 1600, "height": 1200},
{"width": 1440, "height": 960},
]
USER_AGENTS = [
# Chrome Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
# Chrome Mac
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
# Firefox Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:119.0) Gecko/20100101 Firefox/119.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0",
# Firefox Mac
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:120.0) Gecko/20100101 Firefox/120.0",
# Safari Mac
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
# Edge Windows
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0",
# Chrome Linux
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
# Firefox Linux
"Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0",
"Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
]
LOCALES = [
"zh-CN", "zh-TW", "zh-HK",
"en-US", "en-GB", "en-AU", "en-CA",
"ja-JP", "ko-KR",
]
TIMEZONES = [
"Asia/Shanghai", "Asia/Hong_Kong", "Asia/Taipei", "Asia/Tokyo", "Asia/Seoul",
"America/New_York", "America/Los_Angeles", "America/Chicago",
"Europe/London", "Europe/Paris", "Europe/Berlin",
"Australia/Sydney",
]
async def get_browser() -> Browser:
"""获取全局浏览器实例"""
global _playwright, _browser
if _browser is None:
_playwright = await async_playwright().start()
_browser = await _playwright.chromium.launch(
headless=settings.browser_headless,
args=[
"--disable-blink-features=AutomationControlled", # 隐藏自动化标志
]
)
return _browser
async def create_stealth_context() -> BrowserContext:
"""创建带随机指纹的隐身 context"""
browser = await get_browser()
# 随机选择指纹配置
context = await browser.new_context(
viewport=random.choice(VIEWPORTS),
user_agent=random.choice(USER_AGENTS),
locale=random.choice(LOCALES),
timezone_id=random.choice(TIMEZONES),
)
# 应用 stealth
stealth = Stealth()
await stealth.apply_stealth_async(context)
return context
async def close_browser():
"""关闭全局浏览器"""
global _playwright, _browser
if _browser:
await _browser.close()
_browser = None
if _playwright:
await _playwright.stop()
_playwright = None
Binary file not shown.
-3
View File
@@ -1,3 +0,0 @@
from src.company_generator.generator import generate_companies
__all__ = ["generate_companies"]
-134
View File
@@ -1,134 +0,0 @@
"""公司名生成器"""
import random
import logging
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from src.bash_model import K2
from src.config import settings
from src.database import SessionLocal, CrawlTask, TaskSearch
from src.company_generator.prompts import SYSTEM_PROMPT, USER_PROMPT
logger = logging.getLogger(__name__)
class CompanyList(BaseModel):
"""生成的公司名列表"""
companies: list[str] = Field(
description="公司名称列表,使用常用简称,2-15字符,不带集团/有限公司等后缀。示例:华为、比亚迪、宁德时代、海尔、格力"
)
def generate_companies(count: int = None) -> dict:
"""
生成公司名称并插入数据库
Args:
count: 生成数量,默认使用配置值
Returns:
{"inserted_count": N, "skipped_count": N, "inserted_companies": [...]}
"""
if count is None:
count = settings.generate_company_count
db = SessionLocal()
try:
# 1. 检查公司总数
total = db.query(CrawlTask).count()
if total >= settings.max_company_count:
logger.info(f"公司总数已达上限 {total}/{settings.max_company_count},跳过生成")
return {
"inserted_count": 0,
"skipped_count": 0,
"inserted_companies": [],
"reason": "达到上限"
}
# 2. 查询所有已有公司名
existing_rows = db.query(CrawlTask.company_name).all()
existing_set = {row[0] for row in existing_rows}
existing_list = list(existing_set)
# 3. 随机抽样传给 LLM(最多2000个,不足则全部)
sample_size = min(2000, len(existing_list))
sample_companies = random.sample(existing_list, sample_size) if existing_list else []
# 4. 调用 LLM
prompt = USER_PROMPT.format(
count=count,
existing_companies="".join(sample_companies) if sample_companies else ""
)
chain = K2 | PydanticOutputParser(pydantic_object=CompanyList)
result = chain.invoke([
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": prompt}
])
# 5. 遍历插入
inserted = []
skipped = 0
for company_name in result.companies:
company_name = company_name.strip()
# 长度校验
if not (2 <= len(company_name) <= 30):
skipped += 1
logger.debug(f"跳过(长度不符): {company_name}")
continue
# 内存去重
if company_name in existing_set:
skipped += 1
logger.debug(f"跳过(已存在): {company_name}")
continue
savepoint = None
try:
# 使用 savepoint 避免单条失败影响整个事务
savepoint = db.begin_nested()
# 插入主表
crawl_task = CrawlTask(company_name=company_name)
db.add(crawl_task)
db.flush() # 获取 ID
# 插入 Step1 任务
task_search = TaskSearch(
crawl_task_id=crawl_task.id,
input_company_name=company_name
)
db.add(task_search)
savepoint.commit()
inserted.append(company_name)
existing_set.add(company_name) # 防止本批次重复
except Exception as e:
# 唯一约束冲突或其他错误,回滚 savepoint
if savepoint:
savepoint.rollback()
skipped += 1
logger.warning(f"插入失败 {company_name}: {e}")
continue
db.commit()
logger.info(f"生成完成: 插入 {len(inserted)} 个,跳过 {skipped}")
return {
"inserted_count": len(inserted),
"skipped_count": skipped,
"inserted_companies": inserted
}
except Exception as e:
logger.error(f"生成异常: {e}")
db.rollback()
raise
finally:
db.close()
-35
View File
@@ -1,35 +0,0 @@
"""公司生成提示词"""
SYSTEM_PROMPT = "你是一个企业招聘信息专家,熟悉中国各行业的知名企业。"
USER_PROMPT = """
请生成 {count} 个中国企业名称。
## 要求
1. 企业必须真实存在
2. 企业有自己的官方网站(不是仅在招聘平台)
3. 官网上有校园招聘或社会招聘入口
4. 行业不限:互联网、金融、制造、零售、医疗、教育、能源等均可
5. 规模不限:大型企业、独角兽、上市公司、知名民企均可
## 命名规范
- 使用公司最常用的简称
- 不加"集团""有限公司""股份有限公司""科技""网络"等后缀
- 不加"(中国)""(北京)""(上海)"等地域标注
- 2-15个字符
正确示例:华为、比亚迪、宁德时代、海尔、格力、中国平安、招商银行、顺丰、海底捞、蔚来
错误示例:华为技术有限公司、比亚迪股份有限公司、北京字节跳动科技有限公司
## 下面是已有公司,需要排除 (如果下方显示“无”,则表示没有需要排除的公司)
{existing_companies}
## 输出格式
**严格只输出有效的 JSON 对象,不要有任何额外文字、解释或标记。**
输出格式示例:
{{"companies": ["公司名1", "公司名2", "公司名3"]}}
"""
-3
View File
@@ -1,3 +0,0 @@
from src.company_importer.importer import import_companies
__all__ = ["import_companies"]
-15
View File
@@ -1,15 +0,0 @@
"""测试入口: python -m src.company_importer"""
import json
import logging
from src.company_importer import import_companies
logging.basicConfig(level=logging.DEBUG, format="%(levelname)s %(name)s %(message)s")
if __name__ == "__main__":
result = import_companies(
file_path=r"C:\Users\sim18\Downloads\见识星球-校招投递链接(1.13).xlsx",
company_col=3, # C 列
url_col=9, # I 列
)
print(json.dumps(result, ensure_ascii=False, indent=2, default=str))
-155
View File
@@ -1,155 +0,0 @@
"""Excel 公司名单导入"""
import logging
from pathlib import Path
from openpyxl import load_workbook
from src.database import SessionLocal, CrawlTask, TaskSearch
from src.company_importer.url_validator import extract_url, validate_url, clean_url
logger = logging.getLogger(__name__)
def import_companies(
file_path: str,
company_col: int = 1,
url_col: int = 2,
) -> dict:
"""
从 Excel 导入公司名单并创建爬虫任务
Args:
file_path: Excel 文件完整路径(.xlsx
company_col: 公司名所在列索引(从1开始)
url_col: 招聘地址所在列索引(从1开始)
Returns:
导入统计结果
"""
# 1. 验证文件
path = Path(file_path)
if not path.exists():
raise FileNotFoundError(f"文件不存在: {file_path}")
if path.suffix.lower() != ".xlsx":
raise ValueError(f"仅支持 .xlsx 格式,当前文件: {path.suffix}")
# 2. 读取 Excel
wb = load_workbook(file_path, read_only=False) # read_only=False 以读取 hyperlink
ws = wb.active
# 验证列索引
max_col = ws.max_column or 0
if company_col > max_col or url_col > max_col:
wb.close()
raise ValueError(f"列索引超出范围,表格共{max_col}列,company_col={company_col}, url_col={url_col}")
# 统计计数
stats = {
"total_rows": 0,
"inserted_count": 0,
"skipped_empty_name": 0,
"skipped_empty_url": 0,
"skipped_email": 0,
"skipped_weixin": 0,
"skipped_invalid_url": 0,
"skipped_duplicate": 0,
"inserted_companies": [],
}
# 3. 查询已有公司名(内存去重)
db = SessionLocal()
try:
existing_rows = db.query(CrawlTask.company_name).all()
existing_set = {row[0] for row in existing_rows}
# 4. 逐行处理(跳过表头)
for row_idx, row in enumerate(ws.iter_rows(min_row=2), start=2):
stats["total_rows"] += 1
# 4.1 读取公司名
company_cell = row[company_col - 1]
company_name = str(company_cell.value).strip() if company_cell.value else ""
if not company_name:
stats["skipped_empty_name"] += 1
logger.debug(f"{row_idx}行: 公司名为空,跳过")
continue
# 4.2 读取并提取 URL
url_cell = row[url_col - 1]
raw_url = extract_url(url_cell)
if not raw_url:
stats["skipped_empty_url"] += 1
logger.debug(f"{row_idx}行: {company_name} 地址为空,跳过")
continue
# 4.3 验证 URL
is_valid, reason = validate_url(raw_url)
if not is_valid:
if reason == "email":
stats["skipped_email"] += 1
elif reason == "weixin":
stats["skipped_weixin"] += 1
elif reason == "empty_url":
stats["skipped_empty_url"] += 1
else:
stats["skipped_invalid_url"] += 1
logger.debug(f"{row_idx}行: {company_name} 地址无效({reason}): {raw_url}")
continue
# 4.4 清理 URL
url = clean_url(raw_url)
# 4.5 内存去重
if company_name in existing_set:
stats["skipped_duplicate"] += 1
logger.debug(f"{row_idx}行: {company_name} 已存在,跳过")
continue
# 4.6 单条事务入库
try:
# 插入主表
crawl_task = CrawlTask(company_name=company_name)
db.add(crawl_task)
db.flush()
# 插入 Step1 任务(带 input_url
task_search = TaskSearch(
crawl_task_id=crawl_task.id,
input_company_name=company_name,
input_url=url,
)
db.add(task_search)
db.commit()
stats["inserted_count"] += 1
stats["inserted_companies"].append(company_name)
existing_set.add(company_name)
except Exception as e:
db.rollback()
stats["skipped_duplicate"] += 1
logger.warning(f"{row_idx}行: {company_name} 插入失败: {e}")
continue
logger.info(
f"导入完成: 总{stats['total_rows']}行, "
f"成功{stats['inserted_count']}条, "
f"空名{stats['skipped_empty_name']}, "
f"空地址{stats['skipped_empty_url']}, "
f"邮箱{stats['skipped_email']}, "
f"微信{stats['skipped_weixin']}, "
f"无效{stats['skipped_invalid_url']}, "
f"重复{stats['skipped_duplicate']}"
)
return stats
except Exception as e:
logger.error(f"导入异常: {e}")
db.rollback()
raise
finally:
db.close()
wb.close()
-88
View File
@@ -1,88 +0,0 @@
"""URL 清洗与验证"""
from urllib.parse import urlparse
# 需要过滤的域名
BLOCKED_DOMAINS = [
"mp.weixin.qq.com",
]
def extract_url(cell) -> str | None:
"""
从 Excel 单元格提取真实 URL
优先取 hyperlink 地址,其次取文本值
Args:
cell: openpyxl 单元格对象
Returns:
提取到的 URL 字符串,无效则返回 None
"""
url = None
# 优先取超链接地址
if cell.hyperlink and cell.hyperlink.target:
url = str(cell.hyperlink.target).strip()
# 其次取单元格文本值
if not url and cell.value:
url = str(cell.value).strip()
return url if url else None
def validate_url(url: str) -> tuple[bool, str]:
"""
验证 URL 是否合法
Args:
url: 待验证的 URL
Returns:
(是否合法, 不合法的原因)
"""
if not url:
return False, "empty_url"
# 过滤邮箱
if "@" in url:
return False, "email"
# 补全协议头
if not url.startswith(("http://", "https://")):
url = "https://" + url
# 解析 URL
try:
parsed = urlparse(url)
except Exception:
return False, "invalid_url"
# 检查基本结构:有协议、有域名、域名含点(如 example.com
if not parsed.scheme or not parsed.netloc or "." not in parsed.netloc:
return False, "invalid_url"
# 过滤黑名单域名
domain = parsed.netloc.lower()
for blocked in BLOCKED_DOMAINS:
if blocked in domain:
return False, "weixin"
return True, ""
def clean_url(url: str) -> str:
"""
清理并补全 URL
Args:
url: 原始 URL
Returns:
清理后的 URL
"""
url = url.strip()
if not url.startswith(("http://", "https://")):
url = "https://" + url
return url
-3
View File
@@ -1,3 +0,0 @@
from src.config.config import settings, get_settings
__all__ = ["settings", "get_settings"]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-19
View File
@@ -1,19 +0,0 @@
"""配置入口"""
from src.config.development import DevelopmentSettings
from src.config.production import ProductionSettings
def get_settings():
"""根据本地配置返回对应环境的配置"""
try:
from .local_config import ENV
except ImportError:
ENV = "dev" # 默认开发环境
if ENV == "pro":
return ProductionSettings()
return DevelopmentSettings()
# 全局配置实例
settings = get_settings()
-19
View File
@@ -1,19 +0,0 @@
"""开发环境配置"""
from src.config.settings import Settings
class DevelopmentSettings(Settings):
"""开发环境"""
env: str = "dev"
# AI 配置 - 火山引擎
ai_api_key: str = "fd065993-bee2-4f31-8bf2-56d5d3012c02"
ai_base_url: str = "https://ark.cn-beijing.volces.com/api/v3"
ai_temperature: float = 0.1
# 数据库配置
db_host: str = "192.168.31.105"
db_port: int = 3306
db_username: str = "root"
db_password: str = "123456"
db_database: str = "table_comple"
-19
View File
@@ -1,19 +0,0 @@
"""生产环境配置"""
from src.config.settings import Settings
class ProductionSettings(Settings):
"""生产环境"""
env: str = "pro"
# AI 配置 - 火山引擎
ai_api_key: str = "fd065993-bee2-4f31-8bf2-56d5d3012c02"
ai_base_url: str = "https://ark.cn-beijing.volces.com/api/v3"
ai_temperature: float = 0.1
# 数据库配置
db_host: str = "192.168.31.105"
db_port: int = 3306
db_username: str = "root"
db_password: str = "123456"
db_database: str = "table_comple"
-47
View File
@@ -1,47 +0,0 @@
"""基础配置类"""
class Settings:
"""配置基类"""
# 项目名
project_name: str = "Crawler"
# 项目版本
version: str = "1.0.0"
# AI 配置
ai_api_key: str = ""
ai_base_url: str = ""
ai_temperature: float = 0.1
# 数据库配置
db_host: str = ""
db_port: int = 3306
db_username: str = ""
db_password: str = ""
db_database: str = ""
# 浏览器配置
browser_headless: bool = False # 无头模式
# 定时任务频率配置 (单位: 秒)
job_step1_search_interval: int = 30 # 搜索招聘页面
job_step2_page_interval: int = 5 # 岗位列表分析
job_step3_next_interval: int = 5 # 分页分析
job_step4_detail_interval: int = 5 # 详情页分析
job_step5_crawl_interval: int = 10 # 数据爬取
job_periodic_crawl_interval: int = 60*60 # 周期爬取 (1小时)
job_check_validity_interval: int = 60 # 有效性检查
# 业务时间配置 (单位: 天)
crawl_interval_days: int = 15 # 周期爬取间隔
job_expire_days: int = 15 # 岗位有效期/延长天数
# 公司生成任务配置
max_company_count: int = 10000 # 公司总数上限
job_generate_company_interval: int = 1*30*60 # 生成间隔 30 分钟
generate_company_count: int = 20 # 每次生成数量
@property
def db_url(self) -> str:
"""获取数据库连接URL"""
return f"mysql+pymysql://{self.db_username}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_database}"
-11
View File
@@ -1,11 +0,0 @@
"""Crawler 模块 - 使用配置爬取岗位数据"""
from .config import CrawlerConfig, FieldSelector, MAX_PAGES, DEFAULT_TIMEOUT
from .main import crawl
__all__ = [
"crawl",
"CrawlerConfig",
"FieldSelector",
"MAX_PAGES",
"DEFAULT_TIMEOUT",
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-32
View File
@@ -1,32 +0,0 @@
"""Crawler 配置定义"""
from typing import TypedDict, Literal
class FieldSelector(TypedDict, total=False):
"""字段选择器"""
selector: list[str] # CSS选择器数组,多个选择器的结果会用换行拼接
sample: str | None
class CrawlerConfig(TypedDict, total=False):
"""Crawler 输入配置"""
# 初始输入
url: str
# Step 2: page_analysis
job_item_selector: str
item_change_type: Literal["redirect", "new_tab", "in_page"]
# Step 3: next_page
next_page_selector: str | None # None = 无分页
page_change_type: Literal["url_change", "content_change", "new_tab"]
# Step 4: detail_analysis
field_selectors: dict[str, FieldSelector]
detail_area_selector: str | None # 仅 in_page 有值
# 常量
MAX_PAGES = 10 # 最大页数
DEFAULT_TIMEOUT = 10000 # 默认超时时间(毫秒)
-326
View File
@@ -1,326 +0,0 @@
"""三种爬取流程实现"""
import asyncio
import random
from playwright.async_api import Page, BrowserContext
from .config import CrawlerConfig, MAX_PAGES, DEFAULT_TIMEOUT
from .utils import click_next_page, extract_data, safe_click
async def crawl_redirect(
page: Page,
context: BrowserContext,
config: CrawlerConfig
) -> list[dict]:
"""
流程 Aredirect
特点:点击岗位后整页跳转,返回后状态丢失,需重新打开并翻页恢复
"""
url = config["url"]
job_item_selector = config["job_item_selector"]
next_page_selector = config.get("next_page_selector")
page_change_type = config.get("page_change_type", "url_change")
field_selectors = config["field_selectors"]
results: list[dict] = []
page_index = 1
item_index = 1
# 初始化:获取当前页岗位数
elements = await page.query_selector_all(job_item_selector)
items_per_page = len(elements)
while True:
# 1. 检查是否结束
if items_per_page == 0:
break
if page_index > MAX_PAGES:
break
# 随机睡眠
await asyncio.sleep(random.uniform(0.2, 1.0))
# 2. 处理当前岗位
try:
elements = await page.query_selector_all(job_item_selector)
if item_index - 1 < len(elements):
await safe_click(elements[item_index - 1])
await page.wait_for_load_state("networkidle")
# 等待详情内容加载
desc_selectors = field_selectors.get("description", {}).get("selector", [])
first_selector = desc_selectors[0] if desc_selectors else None
if first_selector and first_selector.strip():
try:
await page.wait_for_selector(first_selector, timeout=10000)
except Exception:
pass
else:
await asyncio.sleep(1)
# 等待标题
job_title_selectors = field_selectors.get("job_title", {}).get("selector", [])
first_selector = job_title_selectors[0] if desc_selectors else None
if first_selector and first_selector.strip():
try:
await page.wait_for_selector(first_selector, timeout=10000)
except Exception:
pass
else:
await asyncio.sleep(1)
# 等待
await asyncio.sleep(0.5)
# 提取数据
data = await extract_data(page, field_selectors)
data["detail_url"] = page.url
results.append(data)
except Exception as e:
print(f"处理岗位失败 (page={page_index}, item={item_index}): {e}")
# 3. 计算下一个位置
item_index += 1
if item_index > items_per_page:
page_index += 1
item_index = 1
if page_index > MAX_PAGES:
break
if not next_page_selector or not next_page_selector.strip():
break
# 4. 重新打开并恢复到目标页
# SPA 网站需要 reload 或先访问空白页再返回
try:
await page.goto("about:blank")
await page.goto(url, wait_until="load", timeout=60000)
try:
await page.wait_for_selector(job_item_selector, timeout=10000)
except Exception:
pass # 超时也继续,让后续逻辑处理空结果
except Exception as e:
print(f"恢复页面失败: {e}")
return results
# 翻页到目标页码
for i in range(page_index - 1):
if not next_page_selector or not next_page_selector.strip():
break
success, page = await click_next_page(
page, context, next_page_selector, page_change_type,
job_item_selector
)
if not success:
return results
# 重新计算当前页岗位数
elements = await page.query_selector_all(job_item_selector)
items_per_page = len(elements)
return results
async def crawl_new_tab(
page: Page,
context: BrowserContext,
config: CrawlerConfig
) -> list[dict]:
"""
流程 Bnew_tab
特点:点击后新标签打开详情,关闭新标签后原页面状态保持
"""
job_item_selector = config["job_item_selector"]
next_page_selector = config.get("next_page_selector")
page_change_type = config.get("page_change_type", "url_change")
field_selectors = config["field_selectors"]
results: list[dict] = []
page_index = 1
while page_index <= MAX_PAGES:
# 1. 获取当前页岗位
all_elements = await page.query_selector_all(job_item_selector)
items_per_page = len(all_elements)
if items_per_page == 0:
break
# 随机睡眠
await asyncio.sleep(random.uniform(0.2, 1.0))
# 2. 遍历当前页所有岗位
for item_index in range(1, items_per_page + 1):
try:
elements = await page.query_selector_all(job_item_selector)
if item_index - 1 >= len(elements):
continue
# 监听新标签页
async with context.expect_page(timeout=DEFAULT_TIMEOUT) as new_page_info:
await safe_click(elements[item_index - 1])
new_page = await new_page_info.value
# 等待详情内容加载
desc_selectors = field_selectors.get("description", {}).get("selector", [])
first_selector = desc_selectors[0] if desc_selectors else None
if first_selector and first_selector.strip():
try:
await new_page.wait_for_selector(first_selector, timeout=10000)
except Exception:
pass
else:
await asyncio.sleep(1)
# 等待标题
job_title_selectors = field_selectors.get("job_title", {}).get("selector", [])
first_selector = job_title_selectors[0] if desc_selectors else None
if first_selector and first_selector.strip():
try:
await new_page.wait_for_selector(first_selector, timeout=10000)
except Exception:
pass
else:
await asyncio.sleep(1)
# 等待
await asyncio.sleep(0.5)
# 提取数据
data = await extract_data(new_page, field_selectors)
data["detail_url"] = new_page.url
results.append(data)
# 关闭新标签
await new_page.close()
except Exception as e:
print(f"处理岗位失败 (page={page_index}, item={item_index}): {e}")
# 尝试关闭可能存在的新标签
try:
pages = context.pages
if len(pages) > 1:
await pages[-1].close()
except Exception:
pass
# 3. 翻页
if not next_page_selector or not next_page_selector.strip():
break
success, page = await click_next_page(
page, context, next_page_selector, page_change_type,
job_item_selector
)
if not success:
break
page_index += 1
return results
async def crawl_in_page(
page: Page,
context: BrowserContext,
config: CrawlerConfig
) -> list[dict]:
"""
流程 Cin_page
特点:点击后弹窗/详情区展示,通过刷新页面恢复状态,兼容性更强
"""
url = config["url"]
job_item_selector = config["job_item_selector"]
next_page_selector = config.get("next_page_selector")
page_change_type = config.get("page_change_type", "url_change")
field_selectors = config["field_selectors"]
detail_area_selector = config.get("detail_area_selector")
if not detail_area_selector:
raise ValueError("in_page 模式需要 detail_area_selector")
results: list[dict] = []
page_index = 1
item_index = 1
# 初始化:获取当前页岗位数
elements = await page.query_selector_all(job_item_selector)
items_per_page = len(elements)
while True:
# 1. 检查是否结束
if items_per_page == 0:
break
if page_index > MAX_PAGES:
break
# 2. 处理当前岗位
try:
elements = await page.query_selector_all(job_item_selector)
if item_index - 1 < len(elements):
await safe_click(elements[item_index - 1])
# 等待详情区域出现
await page.wait_for_timeout(timeout=1000)
# 随机睡眠
await asyncio.sleep(random.uniform(0.2, 0.6))
# 在详情区域内提取数据
detail_element = await page.query_selector(detail_area_selector)
if detail_element:
data = await extract_data(detail_element, field_selectors)
else:
data = await extract_data(page, field_selectors)
data["detail_url"] = url # in_page 记录列表页 URL
results.append(data)
except Exception as e:
print(f"处理岗位失败 (page={page_index}, item={item_index}): {e}")
# 3. 计算下一个位置
item_index += 1
if item_index > items_per_page:
page_index += 1
item_index = 1
if page_index > MAX_PAGES:
break
if not next_page_selector or not next_page_selector.strip():
break
# 4. 刷新页面恢复状态
try:
await page.goto("about:blank")
await page.goto(url, wait_until="load", timeout=60000)
try:
await page.wait_for_selector(job_item_selector, timeout=DEFAULT_TIMEOUT)
except Exception:
pass
except Exception as e:
print(f"恢复页面失败: {e}")
return results
# 翻页到目标页码
for i in range(page_index - 1):
if not next_page_selector or not next_page_selector.strip():
break
success, page = await click_next_page(
page, context, next_page_selector, page_change_type,
job_item_selector
)
if not success:
return results
# 重新计算当前页岗位数
elements = await page.query_selector_all(job_item_selector)
items_per_page = len(elements)
return results
-54
View File
@@ -1,54 +0,0 @@
"""Crawler 入口"""
from playwright.async_api import async_playwright
from .config import CrawlerConfig
from .crawler import crawl_redirect, crawl_new_tab, crawl_in_page
async def crawl(config: CrawlerConfig, headless: bool = False) -> list[dict]:
"""
爬取岗位数据
Args:
config: 爬取配置
headless: 是否无头模式
Returns:
岗位数据列表
"""
url = config["url"]
item_change_type = config["item_change_type"]
async with async_playwright() as p:
browser = await p.chromium.launch(headless=headless)
context = await browser.new_context()
page = await context.new_page()
try:
# 打开列表页
await page.goto(url, wait_until="load", timeout=60000)
# 等待岗位元素出现(最多等 10 秒)
job_item_selector = config["job_item_selector"]
try:
await page.wait_for_selector(job_item_selector, timeout=10000)
except Exception:
pass # 超时也继续,让后续逻辑处理空结果
# 根据 item_change_type 分发到对应流程
if item_change_type == "redirect":
results = await crawl_redirect(page, context, config)
elif item_change_type == "new_tab":
results = await crawl_new_tab(page, context, config)
elif item_change_type == "in_page":
results = await crawl_in_page(page, context, config)
else:
raise ValueError(f"未知的 item_change_type: {item_change_type}")
return results
except Exception as e:
print(e)
finally:
await browser.close()
-200
View File
@@ -1,200 +0,0 @@
"""工具函数"""
import asyncio
from playwright.async_api import Page, BrowserContext, ElementHandle, Locator
from .config import FieldSelector, DEFAULT_TIMEOUT
async def safe_click(target: Page | Locator | ElementHandle, selector: str | None = None, timeout: int = 30000) -> None:
"""
安全点击:处理 hover 显示的元素
Args:
target: Page、Locator 或 ElementHandle
selector: 当 target 是 Page 时需要提供选择器
timeout: 点击超时时间
"""
# 获取 locator
if isinstance(target, Page):
if not selector:
raise ValueError("当 target 是 Page 时必须提供 selector")
element = target.locator(selector).first
elif isinstance(target, Locator):
element = target
else:
# ElementHandle: 直接操作
await target.scroll_into_view_if_needed()
await asyncio.sleep(0.2)
await target.hover()
await asyncio.sleep(0.3)
await target.click(timeout=timeout)
return
# Locator: 滚动 -> hover -> 点击
await element.scroll_into_view_if_needed()
await asyncio.sleep(0.2)
await element.hover()
await asyncio.sleep(0.3)
await element.click(timeout=timeout)
async def is_button_clickable(page: Page, selector: str | None) -> bool:
"""检查按钮是否可点击"""
# 空选择器
if not selector or not selector.strip():
return False
element = await page.query_selector(selector)
if not element:
return False
# 检查 disabled 属性
disabled = await element.get_attribute("disabled")
if disabled is not None:
return False
# 检查 class 是否包含 disabled
class_name = await element.get_attribute("class") or ""
if "disabled" in class_name.lower():
return False
# 检查是否可见
is_visible = await element.is_visible()
if not is_visible:
return False
return True
async def click_next_page(
page: Page,
context: BrowserContext,
next_page_selector: str,
page_change_type: str,
job_item_selector: str,
timeout: int = DEFAULT_TIMEOUT
) -> tuple[bool, Page]:
"""
统一翻页函数
返回: (success, page) - new_tab 模式时 page 引用会变
"""
# 检查按钮是否可点
if not await is_button_clickable(page, next_page_selector):
return False, page
try:
if page_change_type == "url_change":
before_url = page.url
await safe_click(page, next_page_selector, timeout=timeout)
await page.wait_for_url(lambda url: url != before_url, timeout=timeout)
await page.wait_for_load_state("networkidle")
return True, page
elif page_change_type == "content_change":
# 记录翻页前第一个岗位的内容
first_item = await page.query_selector(job_item_selector)
before_text = ""
if first_item:
before_text = await first_item.inner_text()
await safe_click(page, next_page_selector, timeout=timeout)
# 等待内容变化
await page.wait_for_function(
"""(args) => {
const el = document.querySelector(args.selector);
return el && el.innerText !== args.text;
}""",
arg={"selector": job_item_selector, "text": before_text},
timeout=timeout
)
await asyncio.sleep(0.5)
return True, page
elif page_change_type == "new_tab":
# 监听新标签页
async with context.expect_page(timeout=timeout) as new_page_info:
await safe_click(page, next_page_selector, timeout=timeout)
new_page = await new_page_info.value
await new_page.wait_for_load_state("networkidle")
# 关闭原标签
await page.close()
return True, new_page
else:
return False, page
except Exception as e:
print(f"翻页失败: {e}")
return False, page
async def extract_data(
scope: Page | ElementHandle,
field_selectors: dict[str, FieldSelector]
) -> dict[str, str | None]:
"""
数据提取函数
Args:
scope: 提取范围(整个 page 或 detail_element
field_selectors: 字段选择器字典
Returns:
提取的数据字典
"""
data: dict[str, str | None] = {}
for field_name, selector_info in field_selectors.items():
try:
# 获取选择器,统一转为数组
raw_selectors = selector_info.get("selector") or selector_info.get("selectors") or []
if isinstance(raw_selectors, str):
selectors = [raw_selectors] if raw_selectors.strip() else []
else:
selectors = raw_selectors
if not selectors:
data[field_name] = None
continue
# 遍历所有选择器,提取文本并拼接
texts: list[str] = []
for selector in selectors:
# 跳过空选择器
if not selector or not selector.strip():
continue
# 仅仅在详情允许查多个
if field_name == "description":
elements = await scope.query_selector_all(selector)
# 标签特殊处理
elif field_name == "job_title":
element = await scope.query_selector(selector)
if element is None or not (await element.inner_text()).strip():
elements = await scope.query_selector_all(selector)
else:
elements = [element] if element else []
else:
element = await scope.query_selector(selector)
elements = [element] if element else []
for element in elements:
text = await element.inner_text()
if text:
texts.append(text.strip())
# 去重
unique_texts = []
for text in texts:
if text not in unique_texts: # 直接判断是否已在列表中
unique_texts.append(text)
data[field_name] = "\n".join(unique_texts) if unique_texts else None
except Exception:
data[field_name] = None
return data
-25
View File
@@ -1,25 +0,0 @@
from src.database.connection import engine, SessionLocal, get_db
from src.database.base import Base
from src.database.models import (
CrawlTask,
TaskSearch,
TaskPageAnalysis,
TaskNextPage,
TaskDetailAnalysis,
TaskCrawl,
JobData,
)
__all__ = [
"engine",
"SessionLocal",
"get_db",
"Base",
"CrawlTask",
"TaskSearch",
"TaskPageAnalysis",
"TaskNextPage",
"TaskDetailAnalysis",
"TaskCrawl",
"JobData",
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
-7
View File
@@ -1,7 +0,0 @@
"""模型基类"""
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
"""SQLAlchemy 声明式基类"""
pass
-26
View File
@@ -1,26 +0,0 @@
"""数据库连接管理"""
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from src.config import settings
# 创建引擎
engine = create_engine(
settings.db_url,
pool_size=5,
max_overflow=10,
pool_recycle=3600,
echo=False
)
# 创建会话工厂
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
def get_db() -> Session:
"""获取数据库会话"""
db = SessionLocal()
try:
yield db
finally:
db.close()
-17
View File
@@ -1,17 +0,0 @@
from src.database.models.crawl_task import CrawlTask
from src.database.models.task_search import TaskSearch
from src.database.models.task_page import TaskPageAnalysis
from src.database.models.task_next import TaskNextPage
from src.database.models.task_detail import TaskDetailAnalysis
from src.database.models.task_crawl import TaskCrawl
from src.database.models.job_data import JobData
__all__ = [
"CrawlTask",
"TaskSearch",
"TaskPageAnalysis",
"TaskNextPage",
"TaskDetailAnalysis",
"TaskCrawl",
"JobData",
]
-27
View File
@@ -1,27 +0,0 @@
"""爬虫任务主表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class CrawlTask(Base):
"""爬虫任务主表 app_crawl_task"""
__tablename__ = "app_crawl_task"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
company_name: Mapped[str] = mapped_column(String(255), nullable=False, unique=True)
# 配置阶段
config_step: Mapped[int] = mapped_column(Integer, default=1)
config_status: Mapped[str] = mapped_column(String(32), default="pending")
# 爬取阶段
crawl_status: Mapped[str | None] = mapped_column(String(32), default=None)
total_crawl_times: Mapped[int] = mapped_column(Integer, default=0)
last_crawl_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
# 时间戳
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-41
View File
@@ -1,41 +0,0 @@
"""Job data table."""
from datetime import datetime
from sqlalchemy import BigInteger, String, DateTime, Text, SmallInteger
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class JobData(Base):
"""岗位数据表 app_job_data"""
__tablename__ = "app_job_data"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
task_crawl_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
job_title: Mapped[str | None] = mapped_column(String(255), default=None, index=True)
salary: Mapped[str | None] = mapped_column(String(128), default=None)
location: Mapped[str | None] = mapped_column(String(2048), default=None)
company: Mapped[str | None] = mapped_column(String(255), default=None)
experience: Mapped[str | None] = mapped_column(String(64), default=None)
education: Mapped[str | None] = mapped_column(String(64), default=None)
description: Mapped[str | None] = mapped_column(Text, default=None)
detail_url: Mapped[str | None] = mapped_column(String(1024), default=None)
company_name_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
job_unique_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
content_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
recruit_category: Mapped[int] = mapped_column(SmallInteger, default=0, index=True)
sources: Mapped[int] = mapped_column(SmallInteger, default=0)
is_independent_url: Mapped[int] = mapped_column(SmallInteger, default=1)
is_valid: Mapped[int] = mapped_column(SmallInteger, default=1, index=True)
expire_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
check_status: Mapped[str] = mapped_column(String(32), default="pending")
last_check_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-30
View File
@@ -1,30 +0,0 @@
"""Step5-数据爬取任务表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime, Text, JSON
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class TaskCrawl(Base):
"""数据爬取任务表 app_task_crawl"""
__tablename__ = "app_task_crawl"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
crawl_task_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
max_retry: Mapped[int] = mapped_column(Integer, default=1)
# 输入
input_config: Mapped[dict] = mapped_column(JSON, nullable=False)
# 输出
crawled_count: Mapped[int | None] = mapped_column(Integer, default=None)
error_message: Mapped[str | None] = mapped_column(Text, default=None)
started_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-33
View File
@@ -1,33 +0,0 @@
"""Step4-详情页分析任务表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime, Text, JSON
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class TaskDetailAnalysis(Base):
"""详情页分析任务表 app_task_detail_analysis"""
__tablename__ = "app_task_detail_analysis"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
crawl_task_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
max_retry: Mapped[int] = mapped_column(Integer, default=1)
# 输入
input_url: Mapped[str] = mapped_column(String(1024), nullable=False)
input_job_selector: Mapped[str] = mapped_column(String(512), nullable=False)
input_change_type: Mapped[str] = mapped_column(String(32), nullable=False)
# 输出
output_detail_selector: Mapped[str | None] = mapped_column(String(512), default=None)
output_fields: Mapped[dict | None] = mapped_column(JSON, default=None)
error_message: Mapped[str | None] = mapped_column(Text, default=None)
started_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-32
View File
@@ -1,32 +0,0 @@
"""Step3-分页分析任务表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime, Text, SmallInteger
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class TaskNextPage(Base):
"""分页分析任务表 app_task_next_page"""
__tablename__ = "app_task_next_page"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
crawl_task_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
max_retry: Mapped[int] = mapped_column(Integer, default=1)
# 输入
input_url: Mapped[str] = mapped_column(String(1024), nullable=False)
# 输出
output_selector: Mapped[str | None] = mapped_column(String(512), default=None)
output_change_type: Mapped[str | None] = mapped_column(String(32), default=None)
has_pagination: Mapped[int | None] = mapped_column(SmallInteger, default=None)
error_message: Mapped[str | None] = mapped_column(Text, default=None)
started_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-32
View File
@@ -1,32 +0,0 @@
"""Step2-岗位列表分析任务表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime, Text
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class TaskPageAnalysis(Base):
"""岗位列表分析任务表 app_task_page_analysis"""
__tablename__ = "app_task_page_analysis"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
crawl_task_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
max_retry: Mapped[int] = mapped_column(Integer, default=1)
# 输入
input_url: Mapped[str] = mapped_column(String(1024), nullable=False)
# 输出
output_selector: Mapped[str | None] = mapped_column(String(512), default=None)
output_change_type: Mapped[str | None] = mapped_column(String(32), default=None)
output_item_count: Mapped[int | None] = mapped_column(Integer, default=None)
error_message: Mapped[str | None] = mapped_column(Text, default=None)
started_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-29
View File
@@ -1,29 +0,0 @@
"""Step1-搜索招聘页面任务表"""
from datetime import datetime
from sqlalchemy import BigInteger, String, Integer, DateTime, Text
from sqlalchemy.orm import Mapped, mapped_column
from src.database.base import Base
class TaskSearch(Base):
"""搜索招聘页面任务表 app_task_search"""
__tablename__ = "app_task_search"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
crawl_task_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
status: Mapped[str] = mapped_column(String(32), default="pending", index=True)
retry_count: Mapped[int] = mapped_column(Integer, default=0)
max_retry: Mapped[int] = mapped_column(Integer, default=1)
# 输入输出
input_company_name: Mapped[str] = mapped_column(String(255), nullable=False)
input_url: Mapped[str | None] = mapped_column(String(1024), default=None, comment="已知招聘地址(表格导入)")
output_url: Mapped[str | None] = mapped_column(String(512), default=None)
error_message: Mapped[str | None] = mapped_column(Text, default=None)
started_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
finished_at: Mapped[datetime | None] = mapped_column(DateTime, default=None)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=datetime.now)
-5
View File
@@ -1,5 +0,0 @@
"""详情页分析模块"""
from .main import analyze_job_detail
from .graph import create_graph
__all__ = ["analyze_job_detail", "create_graph"]
-89
View File
@@ -1,89 +0,0 @@
"""图定义"""
from langgraph.graph import StateGraph, END
from .state import DetailAnalysisState
from .nodes import (
open_list_page,
click_first_job,
find_detail_area,
extract_field_selectors,
validate_data
)
def check_error(state: DetailAnalysisState) -> str:
"""检查是否有错误"""
if state.get("error"):
return "error"
return "continue"
def check_need_find_area(state: DetailAnalysisState) -> str:
"""检查是否需要找详情区域"""
# in_page 需要找弹窗区域,redirect/new_tab 直接用整个页面
if state.get("change_type") == "in_page":
return "find_area"
return "skip"
def check_validation(state: DetailAnalysisState) -> str:
"""检查验证结果"""
if state.get("is_valid"):
return "success"
retry_count = state.get("retry_count", 0)
if retry_count >= 3:
return "max_retry"
return "retry"
def create_graph():
"""创建流程图"""
graph = StateGraph(DetailAnalysisState)
# 添加节点
graph.add_node("open_list_page", open_list_page)
graph.add_node("click_first_job", click_first_job)
graph.add_node("find_detail_area", find_detail_area)
graph.add_node("extract_field_selectors", extract_field_selectors)
graph.add_node("validate_data", validate_data)
# 入口
graph.set_entry_point("open_list_page")
# 流程
graph.add_conditional_edges(
"open_list_page",
check_error,
{"error": END, "continue": "click_first_job"}
)
# 根据 change_type 决定是否找详情区域
graph.add_conditional_edges(
"click_first_job",
check_need_find_area,
{
"find_area": "find_detail_area",
"skip": "extract_field_selectors"
}
)
graph.add_conditional_edges(
"find_detail_area",
check_error,
{"error": END, "continue": "extract_field_selectors"}
)
graph.add_edge("extract_field_selectors", "validate_data")
graph.add_conditional_edges(
"validate_data",
check_validation,
{
"success": END,
"max_retry": END,
"retry": "extract_field_selectors"
}
)
return graph.compile()
-108
View File
@@ -1,108 +0,0 @@
"""入口"""
import asyncio
import sys
from pathlib import Path
# 支持直接运行
if __name__ == "__main__":
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from playwright.async_api import async_playwright
from src.detail_analysis_graph.graph import create_graph
async def analyze_job_detail(url: str, job_item_selector: str, change_type: str, headless: bool = False) -> dict:
"""
分析岗位详情页,提取字段选择器
Args:
url: 列表页 URL
job_item_selector: 岗位项选择器
change_type: 点击后变化类型 (redirect / new_tab / in_page)
Returns:
{
"status": "success" | "failed",
"detail_area_selector": str,
"fields": {
"job_title": {"selector": str, "sample": str},
"description": {"selectors": list[str], "sample": str},
"salary": {"selector": str | None, "sample": str | None},
"location": {"selector": str | None, "sample": str | None},
"company": {"selector": str | None, "sample": str | None},
"experience": {"selector": str | None, "sample": str | None},
"education": {"selector": str | None, "sample": str | None},
"detail_url": {"sample": str}
},
"error": str | None
}
"""
async with async_playwright() as p:
browser = await p.chromium.launch(headless=headless)
context = await browser.new_context(viewport={"width": 1280, "height": 800})
page = await context.new_page()
try:
graph = create_graph()
result = await graph.ainvoke({
"url": url,
"job_item_selector": job_item_selector,
"change_type": change_type,
"page": page
})
if result.get("error"):
return {
"status": "failed",
"error": result["error"]
}
if result.get("is_valid"):
return {
"status": "success",
"detail_area_selector": result.get("detail_area_selector"),
"fields": result.get("fields")
}
else:
return {
"status": "failed",
"error": "验证失败,已达最大重试次数",
"failed_attempts": result.get("failed_attempts")
}
finally:
await browser.close()
async def main():
"""测试"""
url = "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
job_item_selector = ".BHGkB li"
change_type = "in_page"
result = await analyze_job_detail(url, job_item_selector, change_type)
print("\n最终结果:")
if result["status"] == "success":
print(f"✅ 成功")
print(f" 详情区域: {result['detail_area_selector']}")
print(" 字段:")
for name, info in result["fields"].items():
sample = str(info.get('sample', ''))
# detail_url 不截断,其他字段截断显示
if name != "detail_url":
sample = sample[:50]
if "selector" in info:
print(f" {name}: {info['selector']} -> {sample}")
elif "selectors" in info:
print(f" {name}: {info['selectors']} -> {sample}")
else:
print(f" {name}: {sample}")
else:
print(f"❌ 失败")
print(f" 原因: {result.get('error')}")
if __name__ == "__main__":
asyncio.run(main())
-331
View File
@@ -1,331 +0,0 @@
"""节点实现"""
import asyncio
import re
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from langchain_core.messages import HumanMessage
from src.bash_model import GeneralLlm, AnalyseLlm
from .state import DetailAnalysisState
from .prompts import FIND_DETAIL_AREA_PROMPT, EXTRACT_FIELDS_PROMPT, VALIDATE_DATA_PROMPT
# 结构化输出模型
class SelectorResult(BaseModel):
selector: str | None = Field(description="CSS选择器")
reason: str = Field(description="原因")
class FieldSelectors(BaseModel):
job_title: str = Field(description="岗位名称选择器")
description: list[str] = Field(description="岗位详情选择器列表")
salary: str | None = Field(description="薪资选择器")
location: str | None = Field(description="地点选择器")
company: str | None = Field(description="公司选择器")
experience: str | None = Field(description="经验选择器")
education: str | None = Field(description="学历选择器")
class ValidationResult(BaseModel):
is_valid: bool = Field(description="是否有效")
reason: str = Field(description="判断依据")
async def safe_wait_networkidle(page, timeout=5000):
"""尝试等待 networkidle,超时则忽略(处理长连接/心跳网站)"""
try:
await page.wait_for_load_state("networkidle", timeout=timeout)
except:
pass
def get_active_page(state: DetailAnalysisState):
"""获取当前活动页面(处理 new_tab 情况)"""
page = state["page"]
if state["change_type"] == "new_tab":
context = page.context
if len(context.pages) > 1:
return context.pages[-1]
return page
async def open_list_page(state: DetailAnalysisState) -> dict:
"""节点1: 打开列表页"""
url = state["url"]
job_item_selector = state["job_item_selector"]
page = state["page"]
print(f"[节点1] 打开列表页: {url}")
await page.goto(url, wait_until="load", timeout=60000)
try:
await page.wait_for_selector(job_item_selector, timeout=10000)
except Exception:
await asyncio.sleep(3)
# 验证选择器
count = await page.locator(job_item_selector).count()
if count == 0:
return {"error": f"job_item_selector 未匹配到元素: {job_item_selector}"}
print(f"[节点1] 找到 {count} 个岗位")
return {"failed_attempts": [], "retry_count": 0}
async def click_first_job(state: DetailAnalysisState) -> dict:
"""节点2: 点击第1个岗位"""
job_item_selector = state["job_item_selector"]
change_type = state["change_type"]
page = state["page"]
print("【节点2】 点击第1个岗位...")
context = page.context
tabs_before = len(context.pages)
# 记录点击前的 URL
url_before = page.url
# 点击(先 hover 触发可能的显示效果)
element = page.locator(job_item_selector).first
await element.scroll_into_view_if_needed()
await asyncio.sleep(0.2)
await element.hover()
await asyncio.sleep(0.3)
await element.click()
# 延时等待
await asyncio.sleep(1)
# 根据 change_type 处理,获取当前活动页面
active_page = page
if change_type == "new_tab":
await asyncio.sleep(2)
if len(context.pages) > tabs_before:
active_page = context.pages[-1]
await active_page.wait_for_load_state("load")
await safe_wait_networkidle(active_page, 3000)
else:
return {"error": "点击后未打开新标签页"}
elif change_type == "redirect":
# 等待 URL 变化(包括 hash 路由)
for _ in range(30):
await asyncio.sleep(0.2)
if page.url != url_before:
break
await page.wait_for_load_state("load")
await safe_wait_networkidle(page, 3000)
await asyncio.sleep(2)
else: # in_page
# 等待详情区域加载(页内弹窗/抽屉)
await asyncio.sleep(2)
await safe_wait_networkidle(page, 3000)
await asyncio.sleep(1)
# 获取详情页 URL(使用活动页面)
detail_url = active_page.url
print(f"【节点2】 详情页 URL: {detail_url}")
# 获取清理后的 HTML(使用活动页面)
html = await active_page.evaluate("""
() => {
const clone = document.body.cloneNode(true);
clone.querySelectorAll('style, script, noscript, svg, link').forEach(el => el.remove());
return clone.innerHTML;
}
""")
print(f"【节点2】 获取 HTML 完成,长度: {len(html)}")
return {
"detail_html": html,
"detail_url": detail_url
}
async def find_detail_area(state: DetailAnalysisState) -> dict:
"""节点3: 找详情区域"""
detail_html = state["detail_html"]
page = get_active_page(state)
print("[节点3] 分析详情区域...")
# 截断
display_html = detail_html
# if len(display_html) > 100000:
# display_html = display_html[:100000] + "\n... (已截断)"
# LLM 分析
prompt = FIND_DETAIL_AREA_PROMPT.format(html=display_html)
chain = AnalyseLlm | PydanticOutputParser(pydantic_object=SelectorResult)
result = await chain.ainvoke([HumanMessage(content=prompt)])
# llm = AnalyseLlm.with_structured_output(SelectorResult)
# result = await llm.ainvoke([HumanMessage(content=prompt)])
if not result.selector:
return {"error": f"未找到详情区域: {result.reason}"}
print(f"[节点3] 找到详情区域: {result.selector}")
# 获取区域 HTML
try:
locator = page.locator(result.selector).first
await locator.wait_for(state="visible", timeout=5000)
detail_area_html = await locator.inner_html(timeout=5000)
print(f"[节点3] 详情区域 HTML 长度: {len(detail_area_html)}")
except Exception as e:
return {"error": f"详情区域选择器无效: {result.selector}, {e}"}
return {
"detail_area_selector": result.selector,
"detail_area_html": detail_area_html
}
async def extract_field_selectors(state: DetailAnalysisState) -> dict:
"""节点4: 提取字段选择器"""
detail_url = state["detail_url"]
failed_attempts = state.get("failed_attempts", [])
retry_count = state.get("retry_count", 0)
page = get_active_page(state)
# 根据是否有详情区域决定使用的 HTML
detail_area_selector = state.get("detail_area_selector")
if detail_area_selector:
detail_area_html = state["detail_area_html"]
else:
# redirect/new_tab: 用整个页面
detail_area_html = state["detail_html"]
detail_area_selector = "body"
print(f"[节点4] 提取字段选择器... (重试: {retry_count}, 区域: {detail_area_selector})")
# LLM 分析
prompt = EXTRACT_FIELDS_PROMPT.format(
detail_area_html=detail_area_html,
detail_area_selector=detail_area_selector,
failed_attempts=str(failed_attempts) if failed_attempts else ""
)
chain = AnalyseLlm | PydanticOutputParser(pydantic_object=FieldSelectors)
result = await chain.ainvoke([HumanMessage(content=prompt)])
# llm = AnalyseLlm.with_structured_output(FieldSelectors)
# result = await llm.ainvoke([HumanMessage(content=prompt)])
# 用选择器提取数据
fields = {}
# job_title (单选择器)
job_title_text = await extract_text(page, detail_area_selector, result.job_title)
fields["job_title"] = {"selector": result.job_title, "sample": job_title_text}
# description (多选择器拼接)
desc_parts = []
used_selectors = []
for sel in result.description:
text = await extract_text(page, detail_area_selector, sel)
if text:
desc_parts.append(text)
used_selectors.append(sel)
fields["description"] = {
"selectors": used_selectors,
"sample": "\n".join(desc_parts)
}
# 其他字段 (单选择器,独立元素才提取)
for field_name in ["salary", "location", "company", "experience", "education"]:
selector = getattr(result, field_name)
if selector:
text = await extract_text(page, detail_area_selector, selector)
fields[field_name] = {"selector": selector, "sample": text}
else:
fields[field_name] = {"selector": None, "sample": None}
# detail_url
fields["detail_url"] = {"sample": detail_url}
print(f"[节点4] job_title: {fields['job_title']['sample'][:50] if fields['job_title']['sample'] else 'None'}...")
return {"fields": fields}
async def validate_data(state: DetailAnalysisState) -> dict:
"""节点5: 验证数据"""
fields = state["fields"]
failed_attempts = state.get("failed_attempts", [])
retry_count = state.get("retry_count", 0)
print("[节点5] 验证数据...")
job_title = fields.get("job_title", {}).get("sample", "")
description = fields.get("description", {}).get("sample", "")
# 检查必须字段
if not job_title:
print("[节点5] job_title 为空")
return {
"is_valid": False,
"failed_attempts": failed_attempts + [{"reason": "job_title为空", "fields": fields}],
"retry_count": retry_count + 1
}
if not description:
print(f"[节点5] description 为空, 选择器: {fields.get('description', {}).get('selectors')}")
return {
"is_valid": False,
"failed_attempts": failed_attempts + [{"reason": "description为空", "fields": fields}],
"retry_count": retry_count + 1
}
# LLM 验证
extracted_data = f"job_title: {job_title}\ndescription: {description[:500]}..."
prompt = VALIDATE_DATA_PROMPT.format(extracted_data=extracted_data)
llm = GeneralLlm.with_structured_output(ValidationResult)
result = await llm.ainvoke([HumanMessage(content=prompt)])
if result.is_valid:
print("[节点5] 验证成功!")
return {"is_valid": True}
else:
print(f"[节点5] 验证失败: {result.reason}")
return {
"is_valid": False,
"failed_attempts": failed_attempts + [{"reason": result.reason, "fields": fields}],
"retry_count": retry_count + 1
}
async def extract_text(page, area_selector: str, field_selector: str) -> str:
"""从页面提取文本,匹配多个元素时全部提取"""
if not field_selector:
return ""
# 拼接完整选择器
if area_selector and area_selector != "body":
full_selector = f"{area_selector} {field_selector}"
else:
full_selector = field_selector
# 获取所有匹配的元素
try:
elements = await page.query_selector_all(full_selector)
if elements:
texts = []
for el in elements:
text = (await el.inner_text()).strip()
if text:
texts.append(text)
return "\n".join(texts)
except Exception:
pass
return ""
-107
View File
@@ -1,107 +0,0 @@
"""LLM 提示词"""
# 节点3: 找详情区域
FIND_DETAIL_AREA_PROMPT = """分析以下 HTML,找到岗位详情内容所在的区域。
## HTML
{html}
## 任务
找到包含岗位详情信息的容器的 CSS 选择器。
## 重要要求
找到的区域必须同时包含:
1. 岗位名称/标题
2. 岗位描述/要求
如果标题和描述在不同容器,请选择它们共同的父容器。
## 重要约束
1. 选择器必须唯一匹配一个元素
2. 如果基础选择器匹配多个元素,必须使用伪类精确定位,例如:
- .list:nth-child(2)
- .container > ul:first-of-type
- #main .job-list:nth-of-type(1)
3. 避免使用随机/哈希 class
## 常见结构
- 弹窗: .modal, [role="dialog"], .popup, .drawer
- 详情页: .detail, .job-info, .position-detail, main, .content
## 输出
仅输出 JSON:
{{
"selector": "CSS选择器",
"reason": "选择原因" #字数限制30字
}}
找不到则:
{{
"selector": null,
"reason": "原因" #字数限制30字
}}
"""
# 节点4: 提取字段选择器
EXTRACT_FIELDS_PROMPT = """分析以下岗位详情 HTML,提取各字段的 CSS 选择器。
## 详情区域 HTML
{detail_area_html}
## 详情区域选择器
{detail_area_selector}
## 之前失败的尝试(避免重复)
{failed_attempts}
## 任务
找到各字段的 CSS 选择器。
## 重要原则
1. job_title 和 description 是核心字段,必须提取
2. description 应包含完整的岗位信息(职责、要求、公司介绍等都放这里)
3. 其他字段(salary/location/company/experience/education)只有在页面上有**独立、明确的元素**时才提取
4. 如果这些字段的信息混在详情文本中,不要单独提取,设为 null
5. 选择器规范:优先使用标签选择器(h1、h2、p、ul等)或常规类名,避免使用包含特殊字符(+、-、$、@)的类名
## 字段说明
1. job_title (必须): 岗位名称,一个选择器
2. description (必须): 完整的岗位详情,可用多个选择器拼接(职责、要求、介绍等)
3. salary: 薪资 - 必须是独立元素(如单独显示"15-25K"),否则为 null
4. location: 工作地点 - 必须是独立元素,否则为 null
5. company: 公司名称 - 必须是独立元素,否则为 null
6. experience: 经验要求 - 必须是独立元素(如"3-5年"),否则为 null
7. education: 学历要求 - 必须是独立元素(如"本科及以上"),否则为 null
## 输出
仅输出 JSON:
{{
"job_title": "选择器",
"description": ["选择器1", "选择器2"],
"salary": "选择器"或null,
"location": "选择器"或null,
"company": "选择器"或null,
"experience": "选择器"或null,
"education": "选择器"或null
}}
"""
# 节点5: 验证数据
VALIDATE_DATA_PROMPT = """判断以下提取的数据是否为有效的岗位信息。
## 提取的数据
{extracted_data}
## 判断标准(宽松判断)
1. job_title 不为空且看起来像岗位名称(如"软件工程师""产品经理"等)
2. description 不为空且包含岗位相关内容(职责、要求、介绍等)
只要不是明显的乱码、无关内容或空白,就应该返回 true。
## 输出
仅输出 JSON:
{{
"is_valid": true或false,
"reason": "判断依据" #字数限制30字
}}
"""
-34
View File
@@ -1,34 +0,0 @@
"""状态定义"""
from typing import TypedDict
from playwright.async_api import Page
class DetailAnalysisState(TypedDict, total=False):
"""岗位详情解析状态"""
# 输入
url: str
job_item_selector: str
change_type: str # redirect / new_tab / in_page
page: Page
# 节点2: click_first_job
detail_html: str
detail_url: str
# 节点3: find_detail_area
detail_area_selector: str
detail_area_html: str
# 节点4: extract_field_selectors
fields: dict # {field_name: {selector/selectors, sample}}
# 节点5: validate_data
is_valid: bool
# 重试
failed_attempts: list[dict]
retry_count: int
# 错误
error: str
-43
View File
@@ -1,43 +0,0 @@
"""项目主入口"""
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI
from src.scheduler import start_scheduler, shutdown_scheduler
from src.browser import close_browser
# 配置日志
import sys
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s: %(message)s",
stream=sys.stdout
)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
# 启动时
start_scheduler()
yield
# 关闭时
shutdown_scheduler()
await close_browser()
app = FastAPI(
title="Crawler",
version="1.0.0",
lifespan=lifespan
)
@app.get("/health")
def health_check():
"""健康检查"""
return {"status": "ok"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
-5
View File
@@ -1,5 +0,0 @@
from .main import analyze_next_page
from .graph import create_graph
from .state import NextPageState
__all__ = ["analyze_next_page", "create_graph", "NextPageState"]
Binary file not shown.
-90
View File
@@ -1,90 +0,0 @@
"""LangGraph 流程定义"""
from langgraph.graph import StateGraph, END
from .state import NextPageState
from .nodes import fetch_page, find_pagination_area, find_next_button, validate_next
def check_pagination_area(state: NextPageState) -> str:
"""检查分页区域结果"""
# 无分页或已标记成功,直接结束
if state.get("is_valid"):
return "done"
return "continue"
def check_find_next(state: NextPageState) -> str:
"""检查节点3结果"""
# 仅一页(无可点击按钮但成功)
if state.get("is_valid"):
return "done"
if state.get("selector"):
return "validate"
retry_count = state.get("retry_count", 0)
if retry_count >= 3:
return "max_retry"
return "retry"
def check_validation(state: NextPageState) -> str:
"""检查验证结果"""
if state.get("is_valid"):
return "success"
retry_count = state.get("retry_count", 0)
if retry_count >= 3:
return "max_retry"
return "retry"
def create_graph() -> StateGraph:
"""创建流程图"""
graph = StateGraph(NextPageState)
# 添加节点
graph.add_node("fetch_page", fetch_page)
graph.add_node("find_pagination_area", find_pagination_area)
graph.add_node("find_next_button", find_next_button)
graph.add_node("validate_next", validate_next)
# 入口
graph.set_entry_point("fetch_page")
# 流程
graph.add_edge("fetch_page", "find_pagination_area")
# 节点2: 无分页直接结束,有分页继续找按钮
graph.add_conditional_edges(
"find_pagination_area",
check_pagination_area,
{"done": END, "continue": "find_next_button"}
)
# 节点3: 仅一页直接结束,有按钮去验证,失败重试
graph.add_conditional_edges(
"find_next_button",
check_find_next,
{
"done": END,
"validate": "validate_next",
"retry": "find_next_button",
"max_retry": END
}
)
# 节点4: 验证成功结束,失败重试
graph.add_conditional_edges(
"validate_next",
check_validation,
{
"success": END,
"max_retry": END,
"retry": "find_next_button"
}
)
return graph.compile()
-85
View File
@@ -1,85 +0,0 @@
"""入口"""
import asyncio
import sys
from pathlib import Path
# 支持直接运行
if __name__ == "__main__":
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from playwright.async_api import async_playwright
from src.next_page_graph.graph import create_graph
async def analyze_next_page(url: str, headless: bool = False) -> dict:
"""
分析分页列表页,提取"下一页"的 CSS 选择器
Args:
url: 分页列表页 URL
headless: 是否无头模式
Returns:
dict: {status, selector, change_type} 或 {status, reason, tried_selectors}
"""
async with async_playwright() as p:
browser = await p.chromium.launch(headless=headless)
context = await browser.new_context()
page = await context.new_page()
try:
graph = create_graph()
initial_state = {
"url": url,
"page": page
}
print(f"\n{'='*50}")
print(f"开始分析: {url}")
print(f"{'='*50}\n")
final_state = await graph.ainvoke(initial_state)
print(f"\n{'='*50}")
print("分析完成")
print(f"{'='*50}\n")
# 构造结果
if final_state.get("is_valid"):
return {
"status": "success",
"selector": final_state["selector"],
"change_type": final_state["change_type"]
}
else:
return {
"status": "failed",
"reason": final_state.get("error", "验证失败"),
"tried_selectors": final_state.get("failed_selectors", [])
}
finally:
await browser.close()
async def main():
"""测试"""
url = "https://dearsamsung.zhiye.com/#/samsung/pc/szzw"
result = await analyze_next_page(url)
print("\n最终结果:")
if result["status"] == "success":
print(f"✅ 成功")
print(f" 选择器: {result['selector']}")
print(f" 变化类型: {result['change_type']}")
else:
print(f"❌ 失败")
print(f" 原因: {result['reason']}")
if result.get("tried_selectors"):
print(f" 尝试过: {result['tried_selectors']}")
if __name__ == "__main__":
asyncio.run(main())
-227
View File
@@ -1,227 +0,0 @@
"""节点实现"""
import asyncio
import hashlib
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from langchain_core.messages import HumanMessage
from src.bash_model import GeneralLlm, AnalyseLlm
from .state import NextPageState
from .prompts import FIND_PAGINATION_AREA_PROMPT, FIND_NEXT_BUTTON_PROMPT
# 结构化输出模型
class SelectorResult(BaseModel):
"""选择器结果"""
selector: str | None = Field(description="CSS选择器,找不到则为None")
reason: str = Field(description="选择或找不到的原因")
async def fetch_page(state: NextPageState) -> dict:
"""节点1: 获取页面 HTML"""
url = state["url"]
page = state["page"]
print(f"[节点1] 访问页面: {url}")
await page.goto(url, wait_until="load", timeout=60000)
await asyncio.sleep(3)
# 获取清理后的 HTMLa
html = await page.evaluate("""
() => {
const clone = document.body.cloneNode(true);
clone.querySelectorAll('style, script, noscript, svg, link').forEach(el => el.remove());
return clone.innerHTML;
}
""")
print(f"[节点1] 获取 HTML 完成,长度: {len(html)}")
return {
"html": html,
"failed_selectors": [],
"retry_count": 0
}
async def find_pagination_area(state: NextPageState) -> dict:
"""节点2: 找分页区域"""
html = state["html"]
page = state["page"]
print("[节点2] 分析分页区域...")
# LLM 分析
prompt = FIND_PAGINATION_AREA_PROMPT.format(html=html)
chain = AnalyseLlm | PydanticOutputParser(pydantic_object=SelectorResult)
result = await chain.ainvoke([HumanMessage(content=prompt)])
#
# llm = AnalyseLlm.with_structured_output(SelectorResult)
# result = await llm.ainvoke([HumanMessage(content=prompt)])
if not result.selector:
# 无分页控件,直接成功
print(f"[节点2] 无分页控件: {result.reason}")
return {
"has_pagination": 0,
"is_valid": True
}
print(f"[节点2] 找到分页区域: {result.selector}")
# 获取区域 HTML
try:
pagination_html = await page.inner_html(result.selector)
except Exception as e:
# 选择器无效,当作无分页
print(f"[节点2] 选择器无效: {result.selector}, {e}")
return {
"has_pagination": 0,
"is_valid": True
}
return {
"has_pagination": 1,
"pagination_selector": result.selector,
"pagination_html": pagination_html
}
async def find_next_button(state: NextPageState) -> dict:
"""节点3: 找下一页按钮"""
pagination_html = state["pagination_html"]
pagination_selector = state["pagination_selector"]
failed_selectors = state.get("failed_selectors", [])
retry_count = state.get("retry_count", 0)
page = state["page"]
print(f"[节点3] 分析下一页按钮... (重试: {retry_count})")
# LLM 分析
prompt = FIND_NEXT_BUTTON_PROMPT.format(
pagination_html=pagination_html,
failed_selectors="\n".join(failed_selectors) if failed_selectors else ""
)
chain = AnalyseLlm | PydanticOutputParser(pydantic_object=SelectorResult)
result = await chain.ainvoke([HumanMessage(content=prompt)])
# llm = AnalyseLlm.with_structured_output(SelectorResult)
# result = await llm.ainvoke([HumanMessage(content=prompt)])
next_selector = result.selector
if not next_selector:
# 有分页控件但无可点击的下一页(仅一页),统一设为无分页
print(f"[节点3] 无可点击的下一页: {result.reason}")
return {
"selector": None,
"has_pagination": 0,
"is_valid": True
}
# 组合完整选择器
selector = f"{pagination_selector} {next_selector}"
# 检查是否已失败过
if selector in failed_selectors:
print(f"[节点3] 选择器已失败过: {selector}")
return {
"selector": None,
"failed_selectors": failed_selectors,
"retry_count": retry_count + 1
}
print(f"[节点3] 选择器: {selector}")
# 验证元素存在
element = await page.query_selector(selector)
if not element:
print("[节点3] 选择器未匹配到元素")
return {
"selector": None,
"failed_selectors": failed_selectors + [selector],
"retry_count": retry_count + 1
}
return {"selector": selector}
async def validate_next(state: NextPageState) -> dict:
"""节点4: 验证下一页"""
selector = state["selector"]
page = state["page"]
url = state["url"]
failed_selectors = state.get("failed_selectors", [])
retry_count = state.get("retry_count", 0)
print(f"[节点4] 验证选择器: {selector}")
context = page.context
# 1. 记录状态
before_url = page.url
tabs_before = len(context.pages)
content_before = await page.content()
hash_before = hashlib.md5(content_before.encode()).hexdigest()
# 2. 点击(先 hover 触发可能的显示效果)
try:
element = page.locator(selector).first
await element.scroll_into_view_if_needed()
await asyncio.sleep(0.2)
await element.hover()
await asyncio.sleep(0.3)
await element.click()
except Exception as e:
print(f"[节点4] 点击失败: {e}")
return {
"is_valid": False,
"change_type": "no_change",
"failed_selectors": failed_selectors + [selector],
"retry_count": retry_count + 1
}
await asyncio.sleep(3)
# 3. 检测变化
tabs_after = len(context.pages)
after_url = page.url
content_after = await page.content()
hash_after = hashlib.md5(content_after.encode()).hexdigest()
if tabs_after > tabs_before:
change_type = "new_tab"
# 关闭新标签
await context.pages[-1].close()
elif after_url != before_url:
change_type = "url_change"
elif hash_after != hash_before:
change_type = "content_change"
else:
change_type = "no_change"
print(f"[节点4] 变化类型: {change_type}")
# 4. 恢复状态
if change_type in ("url_change", "content_change"):
await page.goto(url, wait_until="load", timeout=60000)
await asyncio.sleep(2)
# 5. 判断结果
if change_type == "no_change":
print("[节点4] 验证失败: 点击后无变化")
return {
"is_valid": False,
"change_type": change_type,
"failed_selectors": failed_selectors + [selector],
"retry_count": retry_count + 1
}
else:
print("[节点4] 验证成功!")
return {
"is_valid": True,
"change_type": change_type
}
-80
View File
@@ -1,80 +0,0 @@
"""LLM 提示词"""
# 节点2: 找分页区域
FIND_PAGINATION_AREA_PROMPT = """分析以下 HTML,找到分页组件所在的区域。
## HTML
{html}
## 任务
找到包含分页组件的容器的 CSS 选择器。
## 判断建议
1. 包含页码数字(1, 2, 3...
2. 包含"上一页"/"下一页" ">" ">>" "<" "<<""或类似按钮
3. 常见 class: pagination, pager, pages, page-nav
4. 通常在页面底部
5. 根据你的专业判断最可能的元素
## 重要约束
1. 选择器必须唯一匹配一个元素
2. 如果基础选择器匹配多个元素,必须使用伪类精确定位,例如:
- .list:nth-child(2)
- .container > ul:first-of-type
- #main .job-list:nth-of-type(1)
3. 避免使用随机/哈希 class
## 输出
仅输出 JSON:
{{
"selector": "CSS选择器",
"reason": "选择原因" #字数限制30字
}}
找不到则:
{{
"selector": null,
"reason": "原因" #字数限制30字
}}
"""
# 节点3: 找下一页按钮
FIND_NEXT_BUTTON_PROMPT = """分析以下分页区域 HTML,找到可点击的"下一页"按钮。
## 分页区域 HTML
{pagination_html}
## 之前失败的选择器(避免使用)
{failed_selectors}
## 任务
找到可点击的"下一页"按钮的 CSS 选择器(相对于分页区域)。
## 判断依据
1. 文本包含: "下一页""Next""»"">"""""
2. Class 包含: next, pagination-next, next-page
3. 属性: [rel="next"], [aria-label*="next"]
4. 位置: 分页区域中靠右侧的可点击元素
5. 根据你的专业判断最可能的元素
## 必须排除(举例)
- disabled 属性的元素
- class 包含 disabled 的元素
- hidden 或 display:none 的元素
- 灰色/不可点击状态的按钮
如果下一页按钮存在但是 disabled 状态,返回 null。
## 输出
仅输出 JSON:
{{
"selector": "相对于分页区域的CSS选择器",
"reason": "选择原因" #字数限制30字
}}
找不到可点击的下一页按钮:
{{
"selector": null,
"reason": "原因(如:按钮disabled/仅一页/无按钮)" #字数限制30字
}}
"""
-33
View File
@@ -1,33 +0,0 @@
"""状态定义"""
from typing import TypedDict
from playwright.async_api import Page
class NextPageState(TypedDict, total=False):
"""下一页选择器分析状态"""
# 输入
url: str
page: Page
# 节点1: fetch_page
html: str
# 节点2: find_pagination_area
pagination_selector: str
pagination_html: str
has_pagination: int # 0=无分页, 1=有分页
# 节点3: find_next_button
selector: str
# 节点4: validate_next
change_type: str # url_change / content_change / new_tab / no_change
is_valid: bool
# 重试
failed_selectors: list[str]
retry_count: int
# 错误
error: str
-5
View File
@@ -1,5 +0,0 @@
from .main import analyze_job_list
from .graph import create_graph
from .state import AnalysisState
__all__ = ["analyze_job_list", "create_graph", "AnalysisState"]

Some files were not shown because too many files have changed in this diff Show More