..

起因

  • 某HD家九周年抽奖

  • 30秒能抽一次。每次抽完要返回刷新才能继续抽

  • 我能抽好几十次,算下来可能要半个小时了,想写个脚本代劳

  • 他这个抽奖,要先访问一次主抽奖页面,点击抽奖,然后刷新当前抽奖页面获取新的key,再抽。如果直接复制抽奖链接重复访问会显示错误。所以简单的循环访问直接pass,涉及到抓页面内容,我想到了python

  • 但是我不会啊!!我不会python,只是稍微看过一点点。没关系,趁这机会学习一波

安装python环境

1.下载 Python 安装程序: 访问 Python 官方网站 ,在主页中选择最新版本的 Python,并下载 Windows 安装程序 (.exe 文件)。

2.运行安装程序: 双击下载的 .exe 文件运行安装程序。确保在安装过程中选择添加 Python 到系统 PATH。

  • 在安装程序的初始界面,确保勾选 “Add Python to PATH” 选项。
  • 单击 “Customize installation” 按钮,可以选择安装的组件。默认情况下,应该选择 “Install for all users” 和 “Add Python to PATH”。
  • 在 “Advanced Options” 界面,可以选择 “Precompile standard library” 以提高性能。

3.完成安装: 单击 “Install Now” 开始安装 Python。安装完成后,会出现一个 “Setup was successful” 的界面。

4.验证安装: 打开命令提示符(CMD)或 PowerShell,运行以下命令验证 Python 是否安装成功:

1
python --version

或者使用以下命令:

1
python -m ensurepip --default-pip

如果成功,将显示 Python 版本信息。

现在,你已经成功在 Windows 上安装了 Python。你可以使用命令行运行 Python 解释器,或者创建和运行 Python 脚本。

写脚本

点击展开
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
import os
import sys
import configparser
import requests
import http.cookies
from bs4 import BeautifulSoup
import time

# 获取打包后的临时目录
temp_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
print(temp_dir)
# 构建配置文件的完整路径
config_path = os.path.join(temp_dir, 'config.ini')

config = configparser.RawConfigParser()

# 检查配置文件是否存在
if not os.path.exists(config_path):
# 如果不存在,创建并初始化配置文件
config['Credentials'] = {
'cookie': 'your_default_cookie_value',
'Lottery_numbe': 'your_default_lottery_number',
'circulate': 'your_default_circulate_value'
}
with open(config_path, 'w') as config_file:
config.write(config_file)
else:
# 如果存在,读取配置文件
config.read(config_path)
# 赋值
Cookie = config.get('Credentials', 'cookie')
Lottery_numbe = config.get('Credentials', 'Lottery_numbe')
circulate = int(config.get('Credentials', 'circulate'))


# 判断是否有一个变量不存在或为空
if not Cookie or not Lottery_numbe or not circulate:
print("At least one variable is missing or empty. Exiting...")
exit()



# 初始的 URL
initial_url = 'https://hdhome.org/lottery.php'


def get_last_column_link(html_content,Lottery_numbe):
soup = BeautifulSoup(html_content, 'html.parser')
outer_div = soup.find(id="outer")
target_td = outer_div.find_all("td", string=lambda text: text and Lottery_numbe in text)
last_td = target_td[0].find_parent("tr").find_all("td")[-1]
last_a = last_td.find("a")
if last_a:
return last_a.get("href")
else:
return ''

# 设置请求头和 Cookie
headers = {
'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': 'zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}

cookie_dict = http.cookies.SimpleCookie(Cookie)
cookies = {key: morsel.value for key, morsel in cookie_dict.items()}

# 循环访问和获取链接
for _ in range(circulate):
# 发送 GET 请求,设置 Referer
headers['Referer'] = initial_url
response = requests.get(initial_url, headers,cookies=cookies)

# 检查是否成功
if response.status_code == 200:
# 获取href
link_href = get_last_column_link(response.text,Lottery_numbe)
if len(link_href) < 1:
print('当前奖品已经抽完,无法继续抽奖')
exit()
# 拼接完整url
full_url = f'{initial_url}{link_href}'
print(f'Full URL: {full_url}')
# 发送 GET 请求,设置 Referer
headers['Referer'] = full_url
response = requests.get(full_url, headers,cookies=cookies)
rst_text = response.text
soup = BeautifulSoup(rst_text, 'html.parser')
main = soup.find_all(class_="main")[1]
rst_text = main.find_all(class_="text")[0].text
print(rst_text)
# exit()
# 设置访问间隔为32秒
time.sleep(32)

把cookie和抽奖设置和次数放config.ini的。当然本地执行没什么问题,问题是如何给别人使用,我想让没有python环境的人也能一键执行脚本,所以在一番GPT的搜索之后,选择了pyinstaller进行打包

打包脚本

  • 首先要安装pyinstaller
1
pip install pyinstaller
  • 打包命令
1
pyinstaller --onefile hdhdraw.py
  • 打包很顺利。但是执行之后,不出意外。报错了,看报错信息,应该是config没读取到,使用了默认的数据导致字符串转数字报错了!
  • 并且.exe目录如果没有config.ini的话,我设置了没有就会新建默认的config.ini,但是并没有生成config.ini

  • 打印了一下加载的config.ini的路径。发现在C:\Users\93481\AppData\Local\Temp_MEI179042 ,这应该是在打包过程中的临时目录。

  • 说明我这行代码一点R用没有
    1
    temp_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
  • 换一个写法,其实中间我折腾了很久,都是这个路径无法加载真实执行脚本所在路径导致config加载不出来,下面这个写法能访问到打包后脚本真实的执行路径。
    1
    2
    3
    4
    5
    6
    7
    8
    def get_script_directory():
    if getattr(sys, 'frozen', False):
    # The application is frozen (i.e., a standalone executable)
    return os.path.dirname(sys.executable)
    elif __file__:
    # The script is running in a normal Python environment
    return os.path.dirname(os.path.realpath(__file__))
    return None
    最后,完整的最终脚本。经过我放在另一台虚拟机的测试,可以完美执行。不依赖环境
    点击展开
    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
    import os
    import sys
    import configparser
    import requests
    import http.cookies
    from bs4 import BeautifulSoup
    import time

    # 获取脚本所在目录的路径
    def get_script_directory():
    if getattr(sys, 'frozen', False):
    # The application is frozen (i.e., a standalone executable)
    return os.path.dirname(sys.executable)
    elif __file__:
    # The script is running in a normal Python environment
    return os.path.dirname(os.path.realpath(__file__))
    return None

    # 获取脚本所在目录
    script_dir = get_script_directory()
    # 构建配置文件的完整路径
    config_path = os.path.join(script_dir, 'config.ini')
    config = configparser.RawConfigParser()

    # 检查配置文件是否存在
    if not os.path.exists(config_path):
    # 如果不存在,创建并初始化配置文件
    config['Credentials'] = {
    'cookie': '',
    'Lottery_numbe': 38,
    'circulate': 20
    }
    with open(config_path, 'w') as config_file:
    config.write(config_file)
    else:
    # 如果存在,读取配置文件
    config.read(config_path, encoding='utf-8')

    # 赋值
    Cookie = config.get('Credentials', 'cookie')
    Lottery_numbe = config.get('Credentials', 'Lottery_numbe')
    # 读取配置文件
    circulate_str = config.get('Credentials', 'circulate', fallback=20)

    # 尝试将字符串转换为整数,如果失败则使用默认值
    try:
    circulate = int(circulate_str)
    except ValueError:
    circulate = 20


    # 判断是否有一个变量不存在或为空
    if not Cookie or not Lottery_numbe or not circulate:
    print("At least one variable is missing or empty. sys.exit()g...")
    time.sleep(3)
    sys.exit()



    # 初始的 URL
    initial_url = 'https://hdhome.org/lottery.php'


    def get_last_column_link(html_content,Lottery_numbe):
    print(Lottery_numbe)
    soup = BeautifulSoup(html_content, 'html.parser')
    outer_div = soup.find(id="outer")
    target_td = outer_div.find_all("td", string=lambda text: text and Lottery_numbe in text)
    last_td = target_td[0].find_parent("tr").find_all("td")[-1]
    last_a = last_td.find("a")
    if last_a:
    return last_a.get("href")
    else:
    return ''

    # 设置请求头和 Cookie
    headers = {
    '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': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
    'sec-ch-ua': '"Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    }

    cookie_dict = http.cookies.SimpleCookie(Cookie)
    cookies = {key: morsel.value for key, morsel in cookie_dict.items()}

    # 循环访问和获取链接
    for _ in range(circulate):
    # 发送 GET 请求,设置 Referer
    headers['Referer'] = initial_url
    response = requests.get(initial_url, headers,cookies=cookies)

    # 检查是否成功
    if response.status_code == 200:
    # 获取href
    link_href = get_last_column_link(response.text,Lottery_numbe)
    if len(link_href) < 1:
    print('当前奖品已经抽完,无法继续抽奖')
    time.sleep(3)
    sys.exit()
    # 拼接完整url
    full_url = f'{initial_url}{link_href}'
    print(f'Full URL: {full_url}')
    # 发送 GET 请求,设置 Referer
    headers['Referer'] = full_url
    response = requests.get(full_url, headers,cookies=cookies)
    rst_text = response.text
    soup = BeautifulSoup(rst_text, 'html.parser')
    main = soup.find_all(class_="main")[1]
    rst_text = main.find_all(class_="text")[0].text
    print(rst_text)
    # sys.exit()
    # 设置访问间隔为32秒
    time.sleep(32)

完结撒花

虽然脚本完成了,我自己跑了一下,10分钟就把魔力跑完了(写脚本1小时,跑了10分钟,好家伙,不如手动抽奖2333),然后也找不到其他需要用他的人(认识的好像手动已经吧魔力抽完了- -),就当学习了一下啦!

打包完成的最终脚本文件提取码:8lsn