IJCAI 爆破教程!

IJCAI 2025 投稿监控与经验总结

投稿 IJCAI 2025 是一次难忘的经历,本文记录了我的投稿过程、实时评分监控、Meta-review 获取方式等一些实用的经验,希望对未来准备 IJCAI 的朋友有所帮助。


📊 接受率与背景

本年度 IJCAI 2025 的接受量 / 投稿量为:

  • 接受量:1042
  • 投稿量:5404
  • 接受率19.3%

相比往年低于 15% 的接受率,这一数字确实提升不少。不过,今年 CMT 和 IJCAI 的各种系统 bug 也让人哭笑不得……


📈 实时监控审稿人是否改分

为了能及时掌握评分变化,能够通过python脚本来实时监控 CMT 上的评分变动,并支持邮件提醒。

🧠 原理

利用 CMT 的 OData 接口,定时访问 ReviewViews 接口,记录当前的评分,并与之前抓取的结果做对比,一旦发生变动,通过邮箱提醒。

⚠️ 注意事项

  • 你需要在浏览器中登录 CMT,按 F12 打开开发者工具,在 Application 面板中获取你的 Cookie 信息。
  • 脚本支持记录日志,并将评分变化写入 ijcai_monitor_log.json 文件。
  • 支持邮件通知(使用 Outlook SMTP)。

💻 脚本源码

点击查看评分监控脚本源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import requests
import time
import smtplib
import copy
import json
import os
from datetime import datetime
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import platform

# xxxx is the reviewer id (replace it with your own reviewer ID)
urls = {
641: "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/ReviewViews(641)", #4
5149: "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/ReviewViews(5149)", #6
15758: "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/ReviewViews(15758)", #6
19890: "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/ReviewViews(19890)", #7
}

# 初始评分状态(第一次抓到后自动初始化)
last_scores = {}

# 日志记录
log_data = {
"start_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"papers": {},
"errors": []
}

# JSON日志文件路径
log_file = "ijcai_monitor_log.json"

# 如果日志文件已存在,加载之前的日志
if os.path.exists(log_file):
try:
with open(log_file, "r", encoding="utf-8") as f:
log_data = json.load(f)
except Exception as e:
print(f"无法加载现有日志文件: {e}")

# 更新日志文件
def update_log():
try:
with open(log_file, "w", encoding="utf-8") as f:
json.dump(log_data, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"无法更新日志文件: {e}")

# Cookie 与 Headers, 按F12获取(开发者模式下,应用栏)
cookies = {
"MC1": "GUID=44928b063b3947518a67995891bf0044&HASH=4492&LV=202504&V=4&LU=1744614339104",
".TRACK": "1",
".ROLE": "Author",
".AspNetCore.Cookies": "CfDJ8JC1yWmjADxLvSP8DVdQ7PM9h9aXhei2M9X2n1gyKZDAzln5XwsqmKIfwA7qkbms31Y_5wMn76scpSspYkqF3VYwSt7u5lNTN21OIC97gNoumKnQMF1fI1-xerQAvNLX29vtm69sC-a0JdmHODOWNkq6L7FvjwH3ABskXLX09Y9VBLsVGuliIZhKXo0nuTkQUHDF4wqhxbuS6X3YlVnGv5DEcDDzes5lQzjWnfPXilfObgRwz1fCXZIstCbtNdZNutC7m2OfJtYP0GdssaJXQLxONo5IZjFoiVae-90jdRR-"
}

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://cmt3.research.microsoft.com/IJCAI2025/Submission/Index",
"Origin": "https://cmt3.research.microsoft.com"
}

# 根据环境决定是否使用代理
if platform.system() == "Windows":
# 仅在Windows下使用代理
# proxies = {
# "http": "http://127.0.0.1:9090",
# "https": "http://127.0.0.1:7890"
# }
proxies = None
else:
# Linux或其他系统不使用代理
proxies = None

# 邮件配置
def send_email(subject, body):
sender = "" #email
receiver = "" #Email
password = "" # 您的密码

msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = receiver
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))

try:
# 注意: 对于Outlook邮箱,需要修改SMTP服务器和端口
server = smtplib.SMTP("smtp.office365.com", 587)
server.starttls()
server.login(sender, password)
server.sendmail(sender, receiver, msg.as_string())
server.quit()
print("📧 Email sent successfully!")
except Exception as e:
print(f"❌ Email send failed: {e}")

# 主循环
while True:
for rid, url in urls.items():
try:
response = requests.get(url, headers=headers, cookies=cookies, proxies=proxies, timeout=10)
if response.status_code == 200:
data = response.json()

# 初始化该论文的日志记录(如果不存在)
if str(rid) not in log_data["papers"]:
log_data["papers"][str(rid)] = {
"title": data.get("SubmissionTitle", "Unknown Title"),
"score_history": [],
"last_check": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}

for question in data.get("Questions", []):
if question.get("Order") == 7:
new_value = question.get("Answers", [{}])[0].get("Value")
print(f"[{rid}] {new_value}", end="")

# 更新日志的最后检查时间
log_data["papers"][str(rid)]["last_check"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

if rid not in last_scores:
last_scores[rid] = new_value

# 记录初始分数
log_data["papers"][str(rid)]["score_history"].append({
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"score": new_value,
"type": "initial"
})

elif new_value != last_scores[rid]:
# 发生了变化
old = last_scores[rid]
last_scores[rid] = new_value # 更新缓存值
title = data.get("SubmissionTitle", "Unknown Title")

# 记录分数变化
log_data["papers"][str(rid)]["score_history"].append({
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"score": new_value,
"previous_score": old,
"type": "change"
})

msg = (
f"🔔 Score Changed!\n\n"
f"Paper ID: {rid}\n"
f"Title: {title}\n"
f"Old Score: {old}\n"
f"New Score: {new_value}\n"
f"Link: {url}"
)
print(msg)
send_email("IJCAI2025 - Review Score Changed", msg)
else:
print(f" - No change")
break
print("")
else:
error_msg = f"Failed to fetch {rid}, Status code: {response.status_code}"
print(error_msg)

# 记录错误
log_data["errors"].append({
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"paper_id": rid,
"error": error_msg
})

except Exception as e:
error_msg = f"[Error] {rid} -> {e}"
print(error_msg)

# 记录错误
log_data["errors"].append({
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"paper_id": rid,
"error": str(e)
})

# 每次检查后更新日志文件
update_log()

print(f"\n[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 等待下一次检查...\n")
# 每 100 秒检查一次
time.sleep(100)

🔍 如何查看 Meta-review

CMT 在 UI 上并不会第一时间公开 Meta-review, 但通过接口我们是可以提前看到的。

🚀 爆破方法

  1. 登录 CMT 后复制 Cookie。

  2. 使用以下脚本暴力访问 MetaReviewViews 接口:

    • 成功响应的 ID 即为你投稿的 Meta-review ID。
  3. 用浏览器打开:

1
https://cmt3.research.microsoft.com/api/odata/IJCAI2025/MetaReviewViews/xxx

即可获取内容。

🔐 爆破脚本

点击查看爆破脚本源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import requests
from concurrent.futures import ThreadPoolExecutor

cookies = {
# "MC1": "GUID=44928b063b3947518a67995891bf0044&HASH=4492&LV=202504&V=4&LU=1744614339104",
".TRACK": "1",
".ROLE": "Author",
".AspNetCore.Cookies": "CfDJ8JC1yWmjADxLvSP8DVdQ7PPSPO1yb6CuSpzMHAMB4uGge4NbgHYHw6lXfTJqiOH-6W4DmeRjtQRwQisMbTQiO7Zby5UW9Bd8xkV8zCOP1xSPjNu3Up2F7RbYaBfx2LmuQ4lPttZJ8wGNTZ7Ei4WjEwTC6G7my3y16Pl93196VhECARZXr2AvW5ptDj1fI7bDkSLHAXzLfX1fj8tNxJ-IMuQk4jqJRcbLGhCVBFKpD3pxhrI-h2edsJJusMcuDBSnI5R6EttkeRGI6X_7-DmZEm63uvQ2eT1OfxbmzKSyaHaS"
}

def check_id(session, base_url, id):
url = f"{base_url}/{id}"
try:
response = session.get(url)
if 'error' not in response.text:
print(f"✅ ID {id} is valid: {response.text[:200]}...")
return id
else:
print(f"❌ ID {id} failed: {response.status_code} - {response.text[:500]}")
return None
except Exception as e:
print(f"⚠️ Error checking ID {id}: {e}")
return None

def check_valid_ids(base_url, start_id, end_id):
valid_ids = []
session = requests.Session()
session.cookies.update(cookies)

left = start_id
right = end_id

with ThreadPoolExecutor(max_workers=2) as executor:
while left <= right:
# 同时检查左右两端
future_left = executor.submit(check_id, session, base_url, left)
future_right = executor.submit(check_id, session, base_url, right) if left != right else None

# 获取结果
result_left = future_left.result()
if result_left is not None:
valid_ids.append(result_left)

if future_right:
result_right = future_right.result()
if result_right is not None:
valid_ids.append(result_right)

left += 1
right -= 1

# 如果找到有效ID,可以提前结束
if valid_ids:
# break
print(f"Found valid IDs: {valid_ids}")
# 继续检查剩余的ID

return valid_ids

base_url = "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/MetaReviewViews"
# base_url = "https://cmt3.research.microsoft.com/api/odata/IJCAI2025/SeniorMetaReviewerNoteViews"
start_id, end_id = 0, 10000
valid_ids = check_valid_ids(base_url, start_id, end_id)
print("\nValid IDs:", valid_ids)

🕵️‍♂️ 提前获取结果

除了评分和 Meta-review,有时我们还想尽早知道论文的最终状态。虽然 CMT 没有在 UI 上直接显示,但我们依然可以通过接口拿到 SubmissionStatus。

📌 操作步骤

  1. 访问以下链接,获取你论文的 Submission ID 对应的 StatusId
1
2
3

[https://cmt3.research.microsoft.com/api/odata/IJCAI2025/Submissions/你的论文编号](https://cmt3.research.microsoft.com/api/odata/IJCAI2025/Submissions/你的论文编号)

  1. 然后用该 StatusId 去下面这个接口对应结果:
1
2
3

[https://cmt3.research.microsoft.com/api/odata/IJCAI2025/SubmissionStatuses](https://cmt3.research.microsoft.com/api/odata/IJCAI2025/SubmissionStatuses)

🎯 总结

这一年的 IJCAI 投稿过程中,我学到了很多,也踩了不少坑。总结几点经验分享如下:

  • 接口随时可能改动:今年的接口结构相比去年有改动,建议务必注意抓包调试。
  • 邮箱提醒是刚需:有些评分变化是在凌晨发生的,邮箱提醒能第一时间知道。
  • Meta-review 不一定有用:提前看到 Meta-review 虽然能提前准备 rebuttal 或预期结果,但最终结果未必一致。

如果你也准备投稿 IJCAI,希望这些工具和经验能帮到你。欢迎交流分享!

提前获取结果

通过如下链接获取对应的status id
https://cmt3.research.microsoft.com/api/odata/IJCAI2025/Submissions/论文编号

对照如下链接中的状态,即可获取结果:
https://cmt3.research.microsoft.com/api/odata/IJCAI2025/SubmissionStatuses


IJCAI 爆破教程!
https://chengz23.github.io/2025/05/03/IJCAI爆破教程/
作者
chengz23
发布于
2025年5月3日
许可协议