麦当劳获取code脚本

麦当劳免费吃喝活动: 麦当劳联动大富翁免费吃喝 使用这个脚本就可以只需要填一次信息 不需要靠浏览器的降速来卡BUG (我失败了所以才写这个 :cry:)

先说原理

不想用脚本的也可以手动 我手动是全失败

Python脚本
#!/usr/bin/env python3
import argparse
import concurrent.futures as cf
import random
import string
import time
from typing import Dict, Any, Tuple

import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter


URL = "https://amoe.playatmcd.com/complete_your_game_code_request"


def build_session(sid: str, user_agent: str, referer: str) -> requests.Session:
    """Create a requests session with retries, headers, and cookie."""
    s = requests.Session()

    # Robust retry policy for transient errors
    retry = Retry(
        total=5,
        connect=5,
        read=5,
        backoff_factor=0.5,              # exponential backoff: 0.5, 1.0, 2.0, ...
        status_forcelist=(429, 500, 502, 503, 504),
        allowed_methods=frozenset(["GET", "POST", "HEAD", "OPTIONS"]),
        raise_on_status=False,
    )
    adapter = HTTPAdapter(max_retries=retry, pool_connections=100, pool_maxsize=100)
    s.mount("https://", adapter)
    s.mount("http://", adapter)

    # Browser-ish headers that actually matter for this POST
    s.headers.update({
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6",
        "Cache-Control": "no-cache",
        "Pragma": "no-cache",
        "Origin": "https://amoe.playatmcd.com",
        "Referer": referer,
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": user_agent,
        # requests will set the correct Content-Type for form-encoded bodies,
        # but we pin it here to match curl:
        "Content-Type": "application/x-www-form-urlencoded",
    })

    # Cookie (sid)
    s.cookies.set("sid", sid, domain="amoe.playatmcd.com", secure=True)

    return s


def make_form(
        csrf_token: str,
        token: str,
        first_name: str,
        last_name: str,
        suffix: str,
        email: str,
        address: str,
        address2: str,
        city: str,
        state: str,
        zip_code: str,
        placeid: str,
        suggested_placeid: str,
) -> Dict[str, Any]:
    """Payload matching your curl --data-raw."""
    return {
        "csrf_token": csrf_token,
        "token": token,
        "first_name": first_name,
        "last_name": last_name,
        "suffix": suffix,
        "email": email,
        "address": address,
        "address2": address2,
        "city": city,
        "state": state,
        "zip": zip_code,
        "placeid": placeid,
        "suggested_placeid": suggested_placeid,
    }


def post_once(session: requests.Session, form: Dict[str, Any], timeout: float) -> Tuple[int, str]:
    """Fire one POST; return (status_code, short_text_snippet)."""
    r = session.post(URL, data=form, timeout=timeout)
    text = r.text
    # Keep output compact
    snippet = text.replace("\n", " ")[:200]
    return r.status_code, snippet


def maybe_jitter(base_delay: float, jitter: float) -> None:
    """Sleep for base_delay ± jitter for gentler traffic profile."""
    if base_delay <= 0 and jitter <= 0:
        return
    low = max(0.0, base_delay - jitter)
    high = base_delay + jitter
    time.sleep(random.uniform(low, high))


def main():
    parser = argparse.ArgumentParser(description="Concurrent AMOE form submitter (requests + ThreadPoolExecutor)")
    # Required tokens/cookie
    parser.add_argument("--sid", required=True, help="Cookie sid=... from your browser session")
    parser.add_argument("--csrf", required=True, help="csrf_token value")
    parser.add_argument("--token", required=True, help="token query/value")

    # Form fields (defaults filled from your curl)
    parser.add_argument("--first-name", required=True, help="First name")
    parser.add_argument("--last-name", required=True, help="Last name")
    parser.add_argument("--suffix", default="None")
    parser.add_argument("--email", required=True, help="Email address")
    parser.add_argument("--address", required=True, help="Street address")
    parser.add_argument("--address2", default="")
    parser.add_argument("--city", required=True, help="City")
    parser.add_argument("--state", required=True, help="State")
    parser.add_argument("--zip", dest="zip_code", required=True, help="ZIP code")
    parser.add_argument("--placeid", default="")
    parser.add_argument("--suggested-placeid", required=True, help="suggested_placeid value")

    # Client behavior
    parser.add_argument("--user-agent", default="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36")
    parser.add_argument("--threads", type=int, default=100, help="Max concurrent workers")
    parser.add_argument("--count", type=int, default=100, help="Total submissions to send")
    parser.add_argument("--timeout", type=float, default=20.0, help="Per-request timeout (seconds)")
    parser.add_argument("--delay", type=float, default=0.0, help="Base delay between scheduling requests (seconds)")
    parser.add_argument("--jitter", type=float, default=0.0, help="± jitter added to the base delay (seconds)")

    args = parser.parse_args()

    referer = "https://amoe.playatmcd.com/complete_your_game_code_request?token=" + args.token

    session = build_session(sid=args.sid, user_agent=args.user_agent, referer=referer)

    base_form = make_form(
        csrf_token=args.csrf,
        token=args.token,
        first_name=args.first_name,
        last_name=args.last_name,
        suffix=args.suffix,
        email=args.email,
        address=args.address,
        address2=args.address2,
        city=args.city,
        state=args.state,
        zip_code=args.zip_code,
        placeid=args.placeid,
        suggested_placeid=args.suggested_placeid,
    )

    print(f"[i] Submitting {args.count} requests with up to {args.threads} concurrent workers...")
    successes = 0
    failures = 0

    with cf.ThreadPoolExecutor(max_workers=args.threads) as executor:
        futures = []
        for i in range(args.count):
            # Clone and optionally tweak email per request
            form_i = dict(base_form)
            form_i["email"] = args.email

            futures.append(executor.submit(post_once, session, form_i, args.timeout))

            # Stagger submissions slightly
            maybe_jitter(args.delay, args.jitter)

        for idx, fut in enumerate(cf.as_completed(futures), 1):
            try:
                status, snippet = fut.result()
                ok = 200 <= status < 300
                if ok and "Success" in snippet:
                    successes += 1
                    print(f"[{idx:03d}] ✓ {status}  {snippet}")
                else:
                    failures += 1
                    print(f"[{idx:03d}] ✗ {status}  {snippet}")
            except Exception as e:
                failures += 1
                print(f"[{idx:03d}] ✗ Exception: {e}")

    print(f"\nDone. Success: {successes}  Failures: {failures}")


if __name__ == "__main__":
    main()

前置条件: 点开麦当劳网站 收OTP 手动打开网页 填写个人信息 完成地址验证


按钮应该只显示提交

按键盘F12 打开控制台(Console), 复制黏贴以下代码

var firstName = document.querySelector("#first_name").value
var lastName = document.querySelector("#last_name").value
var suffix = document.querySelector("#suffix").value
var email = document.querySelector("#email").value
var addressStreet = document.querySelector("#address").value
var addressStreet2 = document.querySelector("#address2").value
var city = document.querySelector("#city").value
var state = document.querySelector("#state").value
var zip = document.querySelector("#zip").value
var placeid = document.querySelector("#placeid").value
var suggestedPlaceid = document.querySelector("#suggested_placeid").value
var csrfToken = document.querySelector("input[name='csrf_token']").value
var token = document.querySelector("input[name='token']").value
// Generate python command based on above info
var pythonCommand = `python3 app.py --csrf "${csrfToken}" --token "${token}" --first-name "${firstName}" --last-name "${lastName}" --suffix "${suffix}" --email "${email}" --address "${addressStreet}" --address2 "${addressStreet2}" --city "${city}" --state "${state}" --zip "${zip}" --placeid "${placeid}" --suggested-placeid "${suggestedPlaceid}"`
console.log(pythonCommand)

输入代码的时候浏览器可能提示复制黏贴js代码的风险 按照要求输入确认后就能黏贴
执行完毕后会获得一串让你执行python脚本的代码


这串代码还缺少一个sid, 这个要自己从浏览器获取 (被加了http only)
同样在F12窗口 点Application → Cookies → 能看到一个sid 复制值 并且在前面的代码最后添加–sid 即可

执行完成效果:


带有success字样的就是成功 没有的就是失败
默认100线程100个请求 可以自己看脚本调整参数

114 个赞

先赞再看,养成习惯 :+1:

码农yyds

跟着喝汤

太狠了zs

后排Disclaimer: 被麦当劳杀全家别找我 :yaoming:

真中大奖我都不敢去兑换 :yaoming:

1 个赞

前排提示:bell:

需要的时候身为潭友会去看你的 :xieyan:

我等了这么久,终于有人写个脚本了

1 个赞

楼主还能更近一步,这个code看起来大概率直接绑定奖品了,因为店里拿到的code直接说明了是什么东西,扫码领取。你可以试试看看API,有没有办法不 claim 的方式检测奖品 :yaoming:

但凡麦当劳不是用recaptcha 我就连邮箱都写了 recaptcha过不去

原来Monopoly是垄断所有奖卷的意思 :yaoming:

可以用playwright写,模拟点击的同时还可以有人类输入

被麦当劳全球封锁(杀全家)怎么办?
以后改吃 Berger King 吗

我自己不用怎么办 :yaoming: 而且手动的话楼里面就有教程了 限制chrome的速度能做到一样效果

码农怎么那么强

不是,你可以 claim 1 万个 code,但是你不可能 redeem 这么多 code。如果能有 API 检测奖品,10M AA、汽车啊、手铐、房车之类的奖品都是你的了!

好像混进去奇怪的东西

3 个赞

对于我们这种一天吃10个麦当劳生日礼物的人,可以

很多网站直接禁了 playwright了,比如REI 这种。。。不知道麦当劳的有没有禁止

1 个赞