const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'; async function handleRequest(tid, num, seedParam, maxFloor) { if (!tid || isNaN(num)) { console.error('请提供有效的帖子 ID 和抽奖人数'); return; } console.log(`Fetching OP for TID: ${tid}`); const op = await getOp(tid); console.log(`OP: ${op}`); console.log(`Fetching all users for TID: ${tid}`); const uniqueUserList = await getAllUser(tid, maxFloor); console.log(`Unique Users: ${uniqueUserList.join(', ')}`); const filteredUserList = uniqueUserList.filter(user => user !== op); console.log(`Filtered Users: ${filteredUserList.join(', ')}`); const userCount = filteredUserList.length; console.log(`User Count: ${userCount}`); const seed = seedParam !== null ? seedParam : userCount.toString(); console.log(`Seed: ${seed}`); console.log(`Max Floor: ${maxFloor}`); const combinedSeed = `${seed}-${maxFloor}`; console.log(`Combined Seed: ${combinedSeed}`); const shuffledList = shuffle(filteredUserList, combinedSeed); console.log(`Shuffled Users: ${shuffledList.join(', ')}`); const result = `符合条件的用户共有 ${filteredUserList.length} 人 抽奖结果: ${shuffledList.slice(0, num).join('\n')}`; console.log(result); } async function getOp(tid) { const url = `amp/t/${tid}`; console.log(`Fetching OP URL: ${url}`); const respOnse= await fetch(url, { headers: { 'User-Agent': UA } }); if (!response.ok) { console.log(`Failed to fetch OP: ${response.status} ${response.statusText}`); return null; } const text = await response.text(); const match = /<div class="topic_author">[\s\S]*?<amp-img[^>]+alt="([^"]+)"[\s\S]*?<\/div>/.exec(text); console.log(`OP Match: ${match ? match[1] : null}`); return match ? match[1].trim() : null; } async function getUserList(url, startIndex, endIndex) { console.log(`Fetching User List URL: ${url}`); const respOnse= await fetch(url, { headers: { 'User-Agent': UA } }); if (!response.ok) { console.log(`Failed to fetch User List: ${response.status} ${response.statusText}`); return []; } const text = await response.text(); const replyItemRegex = /<div class="reply_item">([\s\S]*?)<\/div>/g; let replyItemMatch; const users = []; let currentIndex = startIndex || 0; while ((replyItemMatch = replyItemRegex.exec(text)) !== null) { if (endIndex !== undefined && currentIndex >= endIndex) { break; } const replyItem = replyItemMatch[1]; const altRegex = /<amp-img[^>]+alt="([^"]+)"[^>]*>/g; const altMatch = altRegex.exec(replyItem); if (altMatch) { users.push(altMatch[1]); } currentIndex++; } console.log(`Matches: ${users.join(', ')}`); return users; } async function getAllPages(tid) { const url = `amp/t/${tid}`; console.log(`Fetching All Pages URL: ${url}`); const respOnse= await fetch(url, { headers: { 'User-Agent': UA } }); if (!response.ok) { console.log(`Failed to fetch All Pages: ${response.status} ${response.statusText}`); return []; } const text = await response.text(); const pageCountMatch = /\u5171 (\d+) \u9875/.exec(text); const pageCount = pageCountMatch ? parseInt(pageCountMatch[1], 10) : 1; console.log(`Page Count: ${pageCount}`); const pages = []; for (let i = 1; i <= pageCount; i++) { pages.push(`${url}/${i}`); } return pages; } async function getAllUser(tid, maxFloor) { const pages = await getAllPages(tid); console.log(`Pages: ${pages.join(', ')}`); let allUsers = []; let currentFloor = 0; for (let page of pages) { const startIndex = currentFloor; const endIndex = maxFloor !== undefined ? maxFloor : undefined; const users = await getUserList(page, startIndex, endIndex); allUsers = allUsers.concat(users); currentFloor += users.length; if (endIndex !== undefined && currentFloor >= endIndex) { break; } } const uniqueUsers = []; const seen = new Set(); for (const user of allUsers) { if (!seen.has(user)) { uniqueUsers.push(user); seen.add(user); } } console.log(`Unique Users: ${uniqueUsers.join(', ')}`); return uniqueUsers; } function shuffle(array, seed) { const rng = lcg(seed); console.log(`Shuffling with Seed: ${seed}`); for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(rng() * (i + 1)); console.log(`Shuffling: i=${i}, j=${j}`); if (array[i] !== undefined && array[j] !== undefined) { [array[i], array[j]] = [array[j], array[i]]; } else { console.log(`Error: array[i] or array[j] is undefined. i=${i}, j=${j}, array[i]=${array[i]}, array[j]=${array[j]}`); } } return array; } function lcg(seed) { let state = hashCode(seed); console.log(`LCG State: ${state}`); const a = 1664525; const c = 1013904223; const m = Math.pow(2, 32); return function() { state = (a * state + c) % m; console.log(`LCG Next: ${state / m}`); return state / m; } } function hashCode(str) { l  et hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash |= 0; } return Math.abs(hash); } // Example usage: handleRequest('123456', 3, seed123, 10); 这里的 '123456' 是帖子 ID ,3 是抽奖人数,'seed123' 是种子(可选),10 是最大楼层(可选)。 在 V2EX 网站里用浏览器 consele 运行就可以
为了方便 v 友进行类似抽奖我糊了一个 cloudflare work 来使用直接请求 https://v2ex.240801.xyz/?tid=12345&num=10&seed=12345&maxFloor=11(大佬别打,刚装上访问不了可能 cf 路由没设置好)这里的参数说明为 tid 为帖子 id num 为中奖人数 seed 为随机数种子 maxFloor 为最高楼层
ps 甜度不用担心,今年我们县的都甜。现摘现发没有清洗打腊,只要老家不下雨一般下单第二天就发货。室温 20 度以内还是很耐放的两三个星期没啥问题。有个卖橙子的微信群想加的加我微信 console.log(atob('enF3MjAwOA=='))拉群
为啥这次的代码块没有高亮。。。代码看起来多,是因为ai 写的取回复用户数没用v站的api,下面是去除相关爬虫代码后的代码:https://gist.github.com/zzerding/d80d25149a74c0dd96516d949e9e52b7
好了不摸鱼了领导催进度了
看到515楼我知道这个正则表达式取用户非常不可靠(但是当前代码好像没有注入成功),所以改用v2ex api。 使用方式
![]() | 1 puzzle9 324 天前 尝试中奖 体会 v 友的开心 |
![]() | 2 akafeng 324 天前 做个分母 |
![]() | 3 YiCherish 323 天前 via iPhone 支持 |
![]() | 4 WeaPoon 323 天前 分子试试~ |
5 leo72638 323 天前 via iPhone 试试 |
6 gugulaliqi 323 天前 via Android 碰运气 |
![]() | 7 243205964 323 天前 抽奖代吗越来越复杂了 |
8 Ceylan 323 天前 via Android 试试 |
![]() | 9 AppxLite 323 天前 via Android 参与一下 |
![]() | 10 RobertLyu 323 天前 我来成为分子! |
![]() | 11 zsedc 323 天前 via iPhone 分母 |
![]() | 12 moxxun 323 天前 via iPhone 试试 |
![]() | 13 d1456198 323 天前 1 |
![]() | 14 youbaoer 323 天前 via Android 分母+1 |
![]() | 15 Mrabbit 323 天前 重在参与,爱吃脐橙 |
16 abcgoodwei 323 天前 重在参与,爱吃脐橙 |
17 c9c2ane 323 天前 有优惠吗 |
![]() | 18 monstericeer 323 天前 +1 ! |
19 ch20191 323 天前 我来组成弹幕~~~~~~~~~~~~~~欧皇爱我~~~~~~~~~~~~~ |
![]() | 20 dmdouo12 323 天前 +1 |
![]() | 21 junan 323 天前 没中过奖的来试试 |
![]() | 22 Woodrow 323 天前 争做分子 |
23 lee0508 323 天前 重在参与,爱吃脐橙 |
![]() | 24 7a98kZ6v0WQs5ZO1 323 天前 我是分子 |
![]() | 25 gscsnm 323 天前 我想当分子! |
26 tycyber 323 天前 参与一下。 |
27 zsysmileing 323 天前 重在参与 |
28 likai 323 天前 via Android 分母还是分子 |
![]() | 29 shadowsll 323 天前 重在参与,看着不错 |
30 hill001 323 天前 via Android 参与一下 |
![]() | 31 biumall 323 天前 老乡支持 |
![]() | 32 itiao 323 天前 应当是我 |
![]() | 33 wxw752 323 天前 |
![]() | 34 hucw21750 323 天前 跟了一单,祝好卖~ |
![]() | 35 iLmessi 323 天前 凑个热闹 |
36 superdong 323 天前 预祝大麦 |
37 farah9 323 天前 via iPhone +1 |
![]() | 38 BrookO 323 天前 支持一下 |
39 VampireDemon 323 天前 万一抽到了呢 |
40 liujavamail 323 天前 支持一下 |
![]() | 41 Hidetodong 323 天前 试一下!! |
![]() | 42 roma 323 天前 +1 |
![]() | 43 yanyue526 323 天前 你就说甜不甜吧 |
44 wlongs 323 天前 try |
45 dongyulin353 323 天前 支持一下 |
46 ming7435 323 天前 你就说甜不甜吧 |
![]() | 47 thank001 323 天前 重在参与 |
48 godFree 323 天前 分子 +1 +1 |
![]() | 49 zoyao 323 天前 参与下,还没在 v2 中过奖 |
50 yaoliyc 323 天前 加一 |
![]() | 51 Emi1 323 天前 分母++ |
![]() | 52 hataki77 323 天前 重在参与,分子分母+1 |
![]() | 53 Vipcw95 323 天前 +1 |
![]() | 54 ppllss 323 天前 分子试试~ |
![]() | 55 fuchish112 323 天前 分母 |
56 xR13zp0h67njQr2S 323 天前 做个分子 |
![]() | 57 lianleisuper66 323 天前 试试 |
![]() | 58 hkiJava 323 天前 试试就试试吧 |
![]() | 59 usboy 323 天前 分子 |
60 stormwindcity 323 天前 分母+1 |
![]() | 61 yryc 323 天前 分子+1 |
![]() | 62 luckyboy6 323 天前 1 |
![]() | 63 d873139022 323 天前 参与一下 |
64 smy14520 323 天前 分子分子++ |
![]() | 65 CooperZhuang 323 天前 哈哈哈咱也参与一下,顺祝商祺 |
66 Davy 323 天前 分母 |
![]() | 67 hh7418695 323 天前 做个分母 |
![]() | 68 imherer 323 天前 支持 |
69 amanisheir 323 天前 华农的竹鼠中暑了,快去帮帮他 |
![]() | 70 oouz 323 天前 参与 |
71 banli 323 天前 +1 |
![]() | 72 ik 323 天前 via iPhone 分子分子 |
![]() | 73 kalthus 323 天前 分子 |
74 BugFree 323 天前 试试 |
![]() | 75 Zxien 323 天前 分子! |
76 jjl19960910 323 天前 via Android 我来组成臀部 |
77 tyhsun 323 天前 支持支持 |
![]() | 78 dys0327 323 天前 分子 |
79 happyxhw101 323 天前 我是大学生 |
80 linchen514 323 天前 试试 |
![]() | 81 karlguo7 323 天前 via iPhone +1 |
![]() | 82 wukaige 323 天前 观世音菩萨保佑 |
![]() | 83 yrk20212021 323 天前 分子 |
![]() | 84 wupher 323 天前 分子 |
85 flashmamba 323 天前 111 |
![]() | 86 particlec 323 天前 我要吃橘子 |
87 dany663399 323 天前 分子 |
88 qw3rty 323 天前 我来成为分子 |
89 mkstring 323 天前 分母 |
90 williamcheen 323 天前 +1 |
![]() | 91 dai201617 323 天前 分子 |
92 cxilife 323 天前 做个分母 |
![]() | 93 zii4914 323 天前 |
94 zacheryWu 323 天前 分子 |
95 ssssssssssssssss 323 天前 分母+1 |
![]() | 96 ruiy 323 天前 试试,,, |
97 zimonianhua 323 天前 via Android 分母+1 |
![]() | 98 scal 323 天前 我们这种爱媛、耙耙柑、沃柑。 |
99 WalterHs 323 天前 为啥用邮政快递啊,太慢了啊。 |
![]() | 100 intoext 323 天前 重在参与! |