diff --git a/common.py b/common.py
index 7a30d87..21fbd7b 100644
--- a/common.py
+++ b/common.py
@@ -7,7 +7,8 @@ def format_dictionary_to_string(data):
for key, value in data.items():
if isinstance(value, list) or isinstance(value, dict):
formatted_string_parts.append(
- f"{quote(key)}={quote(json.dumps(value, separators=(',', ':'), ensure_ascii=False))}")
+ f"{quote(key)}={quote(json.dumps(value, separators=(',', ':'), ensure_ascii=False))}"
+ )
else:
formatted_string_parts.append(f"{quote(key)}={quote(str(value))}")
diff --git a/config.py b/config.py
index 8a649d5..aaa6620 100644
--- a/config.py
+++ b/config.py
@@ -4,7 +4,7 @@
# 获取图标文件的路径
def get_application_path():
- if getattr(sys, 'frozen', False):
+ if getattr(sys, "frozen", False):
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
@@ -12,6 +12,6 @@ def get_application_path():
return application_path
-cookies_config_path = os.path.join(get_application_path(), 'cookies.json')
+cookies_config_path = os.path.join(get_application_path(), "cookies.json")
issue_please_text = " (如果还无法解决, 请提交issue到仓库, 十分感谢)"
sleep_seconds = 1
diff --git a/main.py b/main.py
index 975b973..c2330a9 100644
--- a/main.py
+++ b/main.py
@@ -1,518 +1,34 @@
-import inspect
-import json
-import logging
-import os
-import sys
-import time
-from datetime import datetime
-from urllib.parse import urlencode
+from loguru import logger
import gradio as gr
-import qrcode
-from common import format_dictionary_to_string
-from config import cookies_config_path
-from util.BiliRequest import BiliRequest
-from util.error import errnoDict
-from util.order_qrcode import get_qrcode_url
+from tab.go import go_tab
+from tab.settings import setting_tab
+from tab.train import train_tab
-buyer_value = []
-addr_value = []
-ticket_value = []
-isRunning = False
-gt = ""
-challenge = ""
-geetest_validate = ""
-geetest_seccode = ""
+header = """
+# B 站会员购抢票🌈
-# test_geetest_validate = ""
-# test_geetest_seccode = ""
+⚠️此项目仅用于个人参考学习,切勿进行盈利,所造成的后果与本人无关。
+"""
+short_js = """
+
+
+"""
-def onSubmitTicketId(num):
- global buyer_value
- global addr_value
- global ticket_value
+if __name__ == "__main__":
+ logger.add("app_{time}.log")
- try:
- num = int(num)
- _request = BiliRequest(cookies_config_path=cookies_config_path)
- res = _request.get(
- url=f"https://show.bilibili.com/api/ticket/project/getV2?version=134&id={num}&project_id={num}")
- ret = res.json()
- logging.info(ret)
-
- ticket_str_list = []
- project_id = ret["data"]["id"]
- project_name = ret["data"]["name"]
- project_start_time_unix = ret["data"]["start_time"]
- project_end_time_unix = ret["data"]["end_time"]
- project_start_time = datetime.fromtimestamp(project_start_time_unix).strftime("%Y-%m-%d %H:%M:%S")
- project_end_time = datetime.fromtimestamp(project_end_time_unix).strftime("%Y-%m-%d %H:%M:%S")
- venue_info = ret["data"]["venue_info"]
- venue_name = venue_info["name"]
- venue_address = venue_info["address_detail"]
- for screen in ret["data"]["screen_list"]:
- screen_name = screen["name"]
- screen_id = screen["id"]
- for ticket in screen["ticket_list"]:
- ticket_desc = ticket['desc']
- ticket_price = ticket['price']
-
- ticket["screen"] = screen_name
- ticket["screen_id"] = screen_id
- ticket_can_buy = "可购买" if ticket['clickable'] else "无法购买"
- ticket_str = f"{screen_name} - {ticket_desc} - ¥{ticket_price / 100} - {ticket_can_buy}"
- ticket_str_list.append(ticket_str)
- ticket_value.append({"project_id": project_id, "ticket": ticket})
-
- buyer_json = _request.get(
- url=f"https://show.bilibili.com/api/ticket/buyer/list?is_default&projectId={project_id}").json()
- logging.info(buyer_json)
- addr_json = _request.get(url="https://show.bilibili.com/api/ticket/addr/list").json()
- logging.info(addr_json)
-
- buyer_str_list = [f"{item['name']}-{item['personal_id']}" for item in buyer_json["data"]["list"]]
- buyer_value = [item for item in buyer_json["data"]["list"]]
- addr_str_list = [f"{item['addr']}-{item['name']}-{item['phone']}" for item in addr_json["data"]["addr_list"]]
- addr_value = [item for item in addr_json["data"]["addr_list"]]
-
- return [gr.update(choices=ticket_str_list), gr.update(choices=buyer_str_list),
- gr.update(choices=buyer_str_list), gr.update(choices=addr_str_list), gr.update(visible=True),
- gr.update(
- value=f"获取票信息成功:\n展会名称: {project_name}\n开展时间: {project_start_time} - {project_end_time}\n"
- f"场馆地址: {venue_name} {venue_address}",
- visible=True)]
- except Exception as e:
- return [gr.update(), gr.update(), gr.update(), gr.update(), gr.update(), gr.update(value=e, visible=True)]
-
-
-def onSubmitAll(ticket_number, ticket_info, people, people_buyer, address):
- try:
- if ticket_number != len(people):
- return gr.update(value="生成配置文件失败,保证选票数目和购买人数目一致", visible=True)
- ticket_cur = ticket_value[ticket_info]
- people_cur = [buyer_value[item] for item in people]
- people_buyer_cur = buyer_value[people_buyer]
-
- address_cur = addr_value[address]
- config_dir = {"count": ticket_number, "screen_id": ticket_cur["ticket"]["screen_id"],
- "project_id": ticket_cur["project_id"], "sku_id": ticket_cur["ticket"]["id"], "order_type": 1,
- "buyer_info": people_cur, "buyer": people_buyer_cur["name"], "tel": people_buyer_cur["tel"],
- "deliver_info": {"name": address_cur["name"], "tel": address_cur["phone"],
- "addr_id": address_cur["id"],
- "addr": address_cur["prov"] + address_cur["city"] + address_cur["area"] +
- address_cur["addr"]}}
- return gr.update(value=json.dumps(config_dir), visible=True)
- except Exception as e:
- logging.info(e)
- return gr.update(value="生成错误,仔细看看你可能有哪里漏填的", visible=True)
-
-
-def start_go(tickets_info_str, time_start, interval, mode, total_attempts):
- global isRunning, geetest_validate, geetest_seccode
- global gt
- global challenge
- result = ""
- request_result = {"errno": "未知状态码", "msg": "配置文件有错"}
- isRunning = True
- left_time = total_attempts
-
- while isRunning:
- try:
- if time_start != '':
- time_difference = datetime.strptime(time_start, "%Y-%m-%dT%H:%M").timestamp() - time.time()
- if time_difference > 0:
- logging.info(f'等待中')
- yield [gr.update(value="等待中", visible=True), gr.update(visible=False), gr.update(), gr.update(),
- gr.update(), gr.update()]
- time.sleep(time_difference) # 等待到指定的开始时间
- tickets_info = json.loads(tickets_info_str)
- _request = BiliRequest(cookies_config_path=cookies_config_path)
- token_payload = {"count": tickets_info["count"], "screen_id": tickets_info["screen_id"], "order_type": 1,
- "project_id": tickets_info["project_id"], "sku_id": tickets_info["sku_id"], "token": "",
- "newRisk": True}
- request_result_normal = _request.post(
- url=f"https://show.bilibili.com/api/ticket/order/prepare?project_id={tickets_info['project_id']}",
- data=token_payload)
- request_result = request_result_normal.json()
- logging.info(f"prepare header: {request_result_normal.headers}")
- logging.info(f"prepare: {request_result}")
-
- code = int(request_result["code"])
- ## https://github.com/fsender/Bilibili_show_ticket_auto_order/blob/18b3cf6cb539167153f1d2dd847006c9794ac9af/api.py#L237
- if code == -401:
- _url = "https://api.bilibili.com/x/gaia-vgate/v1/register"
- _payload = urlencode(request_result["data"]["ga_data"]["riskParams"])
- _data = _request.post(_url, _payload).json()
- gt = _data["data"]["geetest"]["gt"]
- challenge = _data["data"]["geetest"]["challenge"]
- token = _data["data"]["token"]
- # https://passport.bilibili.com/x/passport-login/captcha?source=main_web
- # challenge = "7e4a9557299685fb82c41972b63a42fc"
- # gt = "ac597a4506fee079629df5d8b66dd4fe"
- yield [gr.update(value="进行验证码验证", visible=True), gr.update(), gr.update(),
- gr.update(visible=True), gr.update(value=gt), gr.update(value=challenge)]
- while geetest_validate == "" or geetest_seccode == "":
- continue
- logging.info(f"geetest_validate: {geetest_validate},geetest_seccode: {geetest_seccode}")
- _url = "https://api.bilibili.com/x/gaia-vgate/v1/validate"
- csrf = _request.cookieManager.get_cookies_value("bili_jct")
-
- _payload = {
- "challenge": challenge,
- "token": token,
- "seccode": geetest_seccode,
- "csrf": csrf,
- "validate": geetest_validate
- }
- _data = _request.post(_url, urlencode(_payload)).json()
- geetest_validate = ""
- geetest_seccode = ""
- if _data["code"] == 0:
- logging.info("极验GeeTest认证 成功")
- else:
- logging.info(f"极验GeeTest验证失败。 {_data}")
- yield [gr.update(value="极验GeeTest验证失败。重新验证", visible=True), gr.update(), gr.update(),
- gr.update(),
- gr.update(), gr.update()]
- continue
- request_result = _request.post(
- url=f"https://show.bilibili.com/api/ticket/order/prepare?project_id={tickets_info['project_id']}",
- data=token_payload).json()
- tickets_info["token"] = request_result["data"]["token"]
- request_result = _request.get(
- url=f"https://show.bilibili.com/api/ticket/order/confirmInfo?token={tickets_info['token']}&voucher=&project_id={tickets_info['project_id']}").json()
- logging.info(f"confirmInfo: {request_result}")
- tickets_info["pay_money"] = request_result["data"]["pay_money"]
- tickets_info["timestamp"] = int(time.time()) * 100
- payload = format_dictionary_to_string(tickets_info)
- request_result = _request.post(
- url=f"https://show.bilibili.com/api/ticket/order/createV2?project_id={tickets_info['project_id']}",
- data=payload).json()
- errno = int(request_result["errno"])
- left_time_str = '无限' if mode == 0 else left_time
- logging.info(
- f'错误码:{errno} 错误码解析: {errnoDict.get(errno, "未知错误码")}, 请求体: {request_result} 剩余次数: {left_time_str}')
- yield [gr.update(
- value=f"正在抢票,具体情况查看终端控制台。\n 剩余次数: {left_time_str} 当前状态码: {errno}, 当前错误信息:{errnoDict.get(errno, '未知错误码')}",
- visible=True), gr.update(visible=True), gr.update(), gr.update(), gr.update(), gr.update()]
- if errno == 0:
- qrcode_url = get_qrcode_url(_request, request_result["data"]["token"], tickets_info['project_id'],
- request_result["data"]['orderId'])
- qr_gen = qrcode.QRCode()
- qr_gen.add_data(qrcode_url)
- qr_gen.make(fit=True)
- qr_gen_image = qr_gen.make_image()
- yield [gr.update(value="生成付款二维码"), gr.update(),
- gr.update(value=qr_gen_image.get_image(), visible=True), gr.update(), gr.update(),
- gr.update()]
- time.sleep(interval / 1000.0)
- if mode == 1:
- left_time -= 1
- if left_time <= 0:
- break
- except Exception as e:
- errno = request_result["errno"]
- left_time_str = '无限' if mode == 0 else left_time
- frame_info = inspect.stack()[0]
- filename = frame_info.filename
- line_number = frame_info.lineno
- logging.info("An error occurred in file '%s' at line %d: %s", filename, line_number, e)
- logging.info(
- f'错误码:{errno} 错误码解析: {errnoDict.get(errno, "未知错误码")}, 请求体: {request_result},剩余次数: {left_time_str}')
- yield [
- gr.update(value=f"错误, 错误码:{errno} 错误码解析: {errnoDict.get(errno, '未知错误码')}", visible=True),
- gr.update(visible=False), gr.update(), gr.update(), gr.update(), gr.update()]
- time.sleep(interval / 1000.0)
- yield [gr.update(value="抢票结束", visible=True), gr.update(visible=False), gr.update(), gr.update(),
- gr.update(), gr.update()]
-
-
-def configure_global_logging():
- application_path = os.path.dirname(os.path.abspath(__file__))
- if hasattr(sys, "_MEIPASS"):
- application_path = os.path.dirname(os.path.abspath(sys.argv[0]))
- global_logger = logging.getLogger()
- global_logger.setLevel(logging.INFO)
- log_file_path = os.path.join(application_path, 'app.log')
- file_handler = logging.FileHandler(log_file_path)
- formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
- file_handler.setFormatter(formatter)
- global_logger.addHandler(file_handler)
-
-
-if __name__ == '__main__':
- configure_global_logging()
- short_js = """
-
- """
with gr.Blocks(head=short_js) as demo:
- gr.HTML("""
-
-
-
-
- Welcome to My GitHub
-
-
-
-
-
- """)
- with gr.Tab("配置") as setting_tab:
- info_ui = gr.TextArea(info="此窗口为输出信息", label="输出信息", interactive=False, visible=False)
- with gr.Column() as first:
- ticket_id_ui = gr.Textbox(label="票ID", interactive=True,
- info="例如:要抢的网址是https://show.bilibili.com/platform/detail.html?id=84096\n"
- "就要填写 84096 ")
- ticket_id_btn = gr.Button("提交票id")
- with gr.Column(visible=False) as inner:
- with gr.Row():
- ticket_number_ui = gr.Number(label="票数目", value=1)
- ticket_info_ui = gr.Dropdown(label="选票", interactive=True, type="index")
- with gr.Row():
- people_ui = gr.CheckboxGroup(label="实名人", interactive=True, type="index",
- info="用于身份证实名认证,请确保曾经在b站填写过购买人(哔哩哔哩客户端-会员购-个人中心-购票人信息)的实名信息,否则这个表单不会有任何信息")
- people_buyer_ui = gr.Dropdown(label="联系人", interactive=True, type="index",
- info="选一个作为联系人,请确保曾经在b站填写过购买人的实名信息,否则这个表单不会有任何信息")
- address_ui = gr.Dropdown(label="地址", interactive=True, type="index",
- info="请确保曾经在b站填写过地址,否则这个表单不会有任何信息")
-
- config_btn = gr.Button("生成配置")
- config_output_ui = gr.Textbox(label="生成配置文件", show_copy_button=True, info="右上角粘贴",
- visible=False)
- config_btn.click(fn=onSubmitAll,
- inputs=[ticket_number_ui, ticket_info_ui, people_ui, people_buyer_ui, address_ui],
- outputs=config_output_ui, )
-
- ticket_id_btn.click(fn=onSubmitTicketId, inputs=ticket_id_ui,
- outputs=[ticket_info_ui, people_ui, people_buyer_ui, address_ui, inner, info_ui])
-
- with gr.Tab("抢票") as go_tab:
- with gr.Column() as second:
- ticket_ui = gr.TextArea(label="填入配置", info="再次填入配置信息", interactive=True)
- time_html = gr.HTML("""
- """, label="选择抢票的时间", show_label=True)
-
- with gr.Row():
- interval_ui = gr.Number(label="抢票间隔", value=1000, minimum=1,
- info="设置抢票任务之间的时间间隔(单位:毫秒),建议不要设置太小")
- mode_ui = gr.Radio(label="抢票模式", choices=["无限", "有限"], value="无限",
- info="选择抢票的模式",
- type="index", interactive=True)
- total_attempts_ui = gr.Number(label="总过次数", value=100, minimum=1, info="设置抢票的总次数",
- visible=False)
-
- mode_ui.change(fn=lambda x: gr.update(visible=True) if x == 1 else gr.update(visible=False),
- inputs=[mode_ui], outputs=total_attempts_ui)
- with gr.Row():
- go_btn = gr.Button("开始抢票")
- stop_btn = gr.Button("停止", visible=False)
-
- with gr.Row():
- go_ui = gr.TextArea(info="此窗口为临时输出,具体请见控制台", label="输出信息", interactive=False,
- visible=False,
- show_copy_button=True, max_lines=10)
- qr_image = gr.Image(label="使用微信或者支付宝扫码支付", visible=False)
-
- with gr.Row(visible=False) as gt_row:
- gt_html_btn = gr.Button("点击打开抢票验证码(请勿多点!!)")
- gt_html_finish_btn = gr.Button("完成验证码后点此此按钮")
-
- gt_html = gr.HTML(value="""
-
-
-
-
-
""", label="验证码")
- # data
- time_tmp = gr.Textbox(visible=False)
- geetest_validate_ui = gr.Textbox(visible=False)
- geetest_seccode_ui = gr.Textbox(visible=False)
- gt_ui = gr.Textbox(visible=False)
- challenge_ui = gr.Textbox(visible=False)
-
- gt_html_finish_btn.click(None, None, geetest_validate_ui,
- js='() => {return captchaObj.getValidate().geetest_validate}')
- gt_html_finish_btn.click(None, None, geetest_seccode_ui,
- js='() => {return captchaObj.getValidate().geetest_seccode}')
-
-
- def update_geetest_validate(x):
- global geetest_validate
- geetest_validate = x
-
-
- def update_geetest_seccode(x):
- global geetest_seccode
- geetest_seccode = x
-
-
- geetest_validate_ui.change(fn=update_geetest_validate, inputs=geetest_validate_ui, outputs=None)
- geetest_seccode_ui.change(fn=update_geetest_seccode, inputs=geetest_seccode_ui, outputs=None)
-
- gt_html_btn.click(fn=None, inputs=[gt_ui, challenge_ui], outputs=None,
- js=f"""(x,y) => {{ initGeetest({{
- gt: x,
- challenge: y,
- offline: false,
- new_captcha: true,
- product: "popup",
- width: "300px",
- https: true
- }}, function (captchaObj) {{
- window.captchaObj = captchaObj;
- $('#captcha').empty();
- captchaObj.appendTo('#captcha');
- }})}}""")
-
- go_btn.click(fn=None, inputs=None, outputs=time_tmp,
- js='(x) => {return (document.getElementById("datetime")).value;}')
-
-
- def stop():
- global isRunning
- isRunning = False
- return [gr.update(value="抢票结束", visible=True), gr.update(visible=False),
- gr.update(), gr.update()]
-
-
- go_btn.click(fn=start_go, inputs=[ticket_ui, time_tmp, interval_ui, mode_ui, total_attempts_ui],
- outputs=[go_ui, stop_btn, qr_image, gt_row, gt_ui, challenge_ui], )
- stop_btn.click(fn=stop, inputs=None, outputs=[go_ui, stop_btn, qr_image, gt_row], )
- with gr.Tab("训练你的验证码速度") as train_taq:
- _request = BiliRequest(cookies_config_path=cookies_config_path)
- gr.HTML("""
- """)
- test_go_btn = gr.Button("开始测试")
- test_gt = ""
- test_token = ""
- test_csrf = ""
- test_challenge = ""
- test_geetest_validate = ""
- test_geetest_seccode = ""
-
-
- def test_go():
- global test_csrf
- global test_gt
- global test_challenge
- global test_token
- global test_geetest_validate
- global test_geetest_seccode
- test_res = _request.get("https://passport.bilibili.com/x/passport-login/captcha?source=main_web").json()
- test_challenge = test_res["data"]["geetest"]["challenge"]
- test_gt = test_res["data"]["geetest"]["gt"]
- test_token = test_res["data"]["token"]
- test_csrf = _request.cookieManager.get_cookies_value("bili_jct")
- test_geetest_validate = ""
- test_geetest_seccode = ""
- return [gr.update(value=test_gt), gr.update(value=test_challenge), gr.update(visible=True),
- gr.update(value="重新生成")]
-
-
- short_js = """
-
- """
- test_log = gr.TextArea(label="测试结果", info="描述当前的情况,验证码过期是正常现象")
- with gr.Row(visible=False) as test_gt_row:
- test_gt_html_start_btn = gr.Button("点击打开抢票验证码(请勿多点!!)")
- test_gt_html_finish_btn = gr.Button("完成验证码后点此此按钮")
- test_gt_html = gr.HTML(value="""
-
-
-
-
-
""", label="验证码")
- test_gt_ui = gr.Textbox(label="gt", visible=True)
- test_challenge_ui = gr.Textbox(label="challenge", visible=True)
- test_go_btn.click(fn=test_go, inputs=None,
- outputs=[test_gt_ui, test_challenge_ui, test_gt_row, test_go_btn])
- test_gt_html_start_btn.click(fn=None, inputs=[test_gt_ui, test_challenge_ui], outputs=None,
- js=f"""(x,y) => {{ initGeetest({{
- gt: x,
- challenge: y,
- offline: false,
- new_captcha: true,
- product: "popup",
- width: "300px",
- https: true
- }}, function (test_captchaObj) {{
- window.test_captchaObj = test_captchaObj;
- $('#captcha_test').empty();
- test_captchaObj.appendTo('#captcha_test');
- }})}}""")
- test_geetest_validate_ui = gr.Textbox(label="validate", visible=True)
- test_geetest_seccode_ui = gr.Textbox(label="eccode", visible=True)
- test_gt_html_finish_btn.click(None, None, test_geetest_validate_ui,
- js='() => {return test_captchaObj.getValidate().geetest_validate}')
- test_gt_html_finish_btn.click(None, None, test_geetest_seccode_ui,
- js='() => {return test_captchaObj.getValidate().geetest_seccode}')
-
-
- def test_doing():
- while test_geetest_validate == "" or test_geetest_seccode == "":
- continue
- _url = "https://api.bilibili.com/x/gaia-vgate/v1/validate"
- _payload = {
- "challenge": test_challenge,
- "token": test_token,
- "seccode": test_geetest_seccode,
- "csrf": test_csrf,
- "validate": test_geetest_validate
- }
- test_data = _request.post(_url, urlencode(_payload))
- yield gr.update(value=test_data.json())
-
-
- test_gt_html_finish_btn.click(fn=test_doing, outputs=[test_log])
-
-
- def test_update_geetest_validate(x):
- global test_geetest_validate
- test_geetest_validate = x
-
-
- def test_update_geetest_seccode(x):
- global test_geetest_seccode
- test_geetest_seccode = x
-
-
- test_geetest_validate_ui.change(fn=test_update_geetest_validate, inputs=test_geetest_validate_ui,
- outputs=None)
- test_geetest_seccode_ui.change(fn=test_update_geetest_seccode, inputs=test_geetest_seccode_ui, outputs=None)
- # 运行应用
+ gr.Markdown(header)
+ with gr.Tab("配置"):
+ setting_tab()
+ with gr.Tab("抢票"):
+ go_tab()
+ with gr.Tab("训练你的验证码速度"):
+ train_tab()
# 运行应用
print("点击下面的网址运行程序 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓")
diff --git a/requirements.txt b/requirements.txt
index be4099d..6d30530 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,6 @@
-pyttsx3~=2.90
selenium~=4.9.0
requests~=2.31.0
-tkcalendar~=1.6.1
setuptools~=65.5.1
gradio~=4.27.0
-qrcode~=7.4.2
\ No newline at end of file
+qrcode~=7.4.2
+loguru
\ No newline at end of file
diff --git a/tab/go.py b/tab/go.py
new file mode 100644
index 0000000..1862fb3
--- /dev/null
+++ b/tab/go.py
@@ -0,0 +1,330 @@
+from datetime import datetime
+import json
+import time
+from loguru import logger
+import qrcode
+from urllib.parse import urlencode
+import gradio as gr
+
+from common import format_dictionary_to_string
+from config import cookies_config_path
+from util.bili_request import BiliRequest
+from util.error import ERRNO_DICT
+from util.order_qrcode import get_qrcode_url
+
+
+isRunning = False
+gt = ""
+challenge = ""
+geetest_validate = ""
+geetest_seccode = ""
+
+def start_go(tickets_info_str, time_start, interval, mode, total_attempts):
+ global isRunning, geetest_validate, geetest_seccode
+ global gt
+ global challenge
+ request_result = {"errno": "未知状态码", "msg": "配置文件有错"}
+ isRunning = True
+ left_time = total_attempts
+
+ while isRunning:
+ try:
+ if time_start != "":
+ time_difference = (
+ datetime.strptime(time_start, "%Y-%m-%dT%H:%M").timestamp()
+ - time.time()
+ )
+ if time_difference > 0:
+ logger.info("等待中")
+ yield [
+ gr.update(value="等待中", visible=True),
+ gr.update(visible=False),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ ]
+ time.sleep(time_difference) # 等待到指定的开始时间
+ tickets_info = json.loads(tickets_info_str)
+ _request = BiliRequest(cookies_config_path=cookies_config_path)
+ token_payload = {
+ "count": tickets_info["count"],
+ "screen_id": tickets_info["screen_id"],
+ "order_type": 1,
+ "project_id": tickets_info["project_id"],
+ "sku_id": tickets_info["sku_id"],
+ "token": "",
+ "newRisk": True,
+ }
+ request_result_normal = _request.post(
+ url=f"https://show.bilibili.com/api/ticket/order/prepare?project_id={tickets_info['project_id']}",
+ data=token_payload,
+ )
+ request_result = request_result_normal.json()
+ logger.info(f"prepare header: {request_result_normal.headers}")
+ logger.info(f"prepare: {request_result}")
+
+ code = int(request_result["code"])
+ ## https://github.com/fsender/Bilibili_show_ticket_auto_order/blob/18b3cf6cb539167153f1d2dd847006c9794ac9af/api.py#L237
+ if code == -401:
+ _url = "https://api.bilibili.com/x/gaia-vgate/v1/register"
+ _payload = urlencode(request_result["data"]["ga_data"]["riskParams"])
+ _data = _request.post(_url, _payload).json()
+ gt = _data["data"]["geetest"]["gt"]
+ challenge = _data["data"]["geetest"]["challenge"]
+ token = _data["data"]["token"]
+ # https://passport.bilibili.com/x/passport-login/captcha?source=main_web
+ # challenge = "7e4a9557299685fb82c41972b63a42fc"
+ # gt = "ac597a4506fee079629df5d8b66dd4fe"
+ yield [
+ gr.update(value="进行验证码验证", visible=True),
+ gr.update(),
+ gr.update(),
+ gr.update(visible=True),
+ gr.update(value=gt),
+ gr.update(value=challenge),
+ ]
+ while geetest_validate == "" or geetest_seccode == "":
+ continue
+ logger.info(
+ f"geetest_validate: {geetest_validate},geetest_seccode: {geetest_seccode}"
+ )
+ _url = "https://api.bilibili.com/x/gaia-vgate/v1/validate"
+ csrf = _request.cookieManager.get_cookies_value("bili_jct")
+
+ _payload = {
+ "challenge": challenge,
+ "token": token,
+ "seccode": geetest_seccode,
+ "csrf": csrf,
+ "validate": geetest_validate,
+ }
+ _data = _request.post(_url, urlencode(_payload)).json()
+ geetest_validate = ""
+ geetest_seccode = ""
+ if _data["code"] == 0:
+ logger.info("极验 GeeTest 验证成功")
+ else:
+ logger.info("极验 GeeTest 验证失败 {}", _data)
+ yield [
+ gr.update(value="极验 GeeTest 验证失败。重新验证", visible=True),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ ]
+ continue
+ request_result = _request.post(
+ url=f"https://show.bilibili.com/api/ticket/order/prepare?project_id={tickets_info['project_id']}",
+ data=token_payload,
+ ).json()
+ tickets_info["token"] = request_result["data"]["token"]
+ request_result = _request.get(
+ url=f"https://show.bilibili.com/api/ticket/order/confirmInfo?token={tickets_info['token']}&voucher=&project_id={tickets_info['project_id']}"
+ ).json()
+ logger.info(f"confirmInfo: {request_result}")
+ tickets_info["pay_money"] = request_result["data"]["pay_money"]
+ tickets_info["timestamp"] = int(time.time()) * 100
+ payload = format_dictionary_to_string(tickets_info)
+ request_result = _request.post(
+ url=f"https://show.bilibili.com/api/ticket/order/createV2?project_id={tickets_info['project_id']}",
+ data=payload,
+ ).json()
+ errno = int(request_result["errno"])
+ left_time_str = "无限" if mode == 0 else left_time
+ logger.info(
+ f'状态码: {errno}({ERRNO_DICT.get(errno, "未知错误码")}), 请求体: {request_result} 剩余次数: {left_time_str}'
+ )
+ yield [
+ gr.update(
+ value=f"正在抢票,具体情况查看终端控制台。\n剩余次数: {left_time_str} 当前状态码: {errno}({ERRNO_DICT.get(errno, "未知错误码")})",
+ visible=True,
+ ),
+ gr.update(visible=True),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ ]
+ if errno == 0:
+ qrcode_url = get_qrcode_url(
+ _request,
+ request_result["data"]["token"],
+ tickets_info["project_id"],
+ request_result["data"]["orderId"],
+ )
+ qr_gen = qrcode.QRCode()
+ qr_gen.add_data(qrcode_url)
+ qr_gen.make(fit=True)
+ qr_gen_image = qr_gen.make_image()
+ yield [
+ gr.update(value="生成付款二维码"),
+ gr.update(),
+ gr.update(value=qr_gen_image.get_image(), visible=True),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ ]
+ time.sleep(interval / 1000.0)
+ if mode == 1:
+ left_time -= 1
+ if left_time <= 0:
+ break
+ except Exception as e:
+ # errno = request_result["errno"]
+ # left_time_str = '无限' if mode == 0 else left_time
+ # frame_info = inspect.stack()[0]
+ # filename = frame_info.filename
+ # line_number = frame_info.lineno
+ # logger.info("An error occurred in file '%s' at line %d: %s", filename, line_number, e)
+ logger.exception(e)
+ # logger.info(
+ # f'错误码: {errno}({ERRNO_DICT.get(errno, "未知错误码")}), 请求体: {request_result}, 剩余次数: {left_time_str}')
+ # yield [
+ # gr.update(value=f"错误, 错误码:{errno} 错误码解析: {ERRNO_DICT.get(errno, '未知错误码')}", visible=True),
+ # gr.update(visible=False), gr.update(), gr.update(), gr.update(), gr.update()]
+ # time.sleep(interval / 1000.0)
+ yield [
+ gr.update(value="抢票结束", visible=True),
+ gr.update(visible=False),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ ]
+def go_tab():
+ with gr.Column():
+ ticket_ui = gr.TextArea(
+ label="填入配置", info="再次填入配置信息", interactive=True
+ )
+ gr.HTML(
+ """
+ """,
+ label="选择抢票的时间",
+ show_label=True,
+ )
+
+ with gr.Row():
+ interval_ui = gr.Number(
+ label="抢票间隔",
+ value=1000,
+ minimum=1,
+ info="设置抢票任务之间的时间间隔(单位:毫秒),建议不要设置太小",
+ )
+ mode_ui = gr.Radio(
+ label="抢票模式",
+ choices=["无限", "有限"],
+ value="无限",
+ info="选择抢票的模式",
+ type="index",
+ interactive=True,
+ )
+ total_attempts_ui = gr.Number(
+ label="总过次数",
+ value=100,
+ minimum=1,
+ info="设置抢票的总次数",
+ visible=False,
+ )
+
+ mode_ui.change(
+ fn=lambda x: gr.update(visible=True)
+ if x == 1
+ else gr.update(visible=False),
+ inputs=[mode_ui],
+ outputs=total_attempts_ui,
+ )
+ with gr.Row():
+ go_btn = gr.Button("开始抢票")
+ stop_btn = gr.Button("停止", visible=False)
+
+ with gr.Row():
+ go_ui = gr.TextArea(
+ info="此窗口为临时输出,具体请见控制台",
+ label="输出信息",
+ interactive=False,
+ visible=False,
+ show_copy_button=True,
+ max_lines=10,
+ )
+ qr_image = gr.Image(label="使用微信或者支付宝扫码支付", visible=False)
+
+ with gr.Row(visible=False) as gt_row:
+ gt_html_btn = gr.Button("点击打开抢票验证码(请勿多点!!)")
+ gt_html_finish_btn = gr.Button("完成验证码后点此此按钮")
+
+ gr.HTML(
+ value="""
+
+
+
+
+
""",
+ label="验证码",
+ )
+
+ time_tmp = gr.Textbox(visible=False)
+ gt_ui = gr.Textbox(visible=False)
+ challenge_ui = gr.Textbox(visible=False)
+ gt_html_btn.click(
+ fn=None,
+ inputs=[gt_ui, challenge_ui],
+ outputs=None,
+ js="""
+ (gt, challenge) => initGeetest({
+ gt, challenge,
+ offline: false,
+ new_captcha: true,
+ product: "popup",
+ width: "300px",
+ https: true
+ }, function (captchaObj) {
+ window.captchaObj = captchaObj;
+ $('#captcha').empty();
+ captchaObj.appendTo('#captcha');
+ })
+ """,
+ )
+
+ geetest_result = gr.JSON()
+ gt_html_finish_btn.click(
+ fn=None,
+ inputs=None,
+ outputs=geetest_result,
+ js="() => captchaObj.getValidate()",
+ )
+ def receive_geetest_result(res):
+ global geetest_validate, geetest_seccode
+ geetest_validate = res["geetest_validate"]
+ geetest_seccode = res["geetest_seccode"]
+ geetest_result.change(fn=receive_geetest_result, inputs=geetest_result)
+
+
+ go_btn.click(
+ fn=None,
+ inputs=None,
+ outputs=time_tmp,
+ js='(x) => document.getElementById("datetime").value',
+ )
+
+ def stop():
+ global isRunning
+ isRunning = False
+ return [
+ gr.update(value="抢票结束", visible=True),
+ gr.update(visible=False),
+ gr.update(),
+ gr.update(),
+ ]
+
+ go_btn.click(
+ fn=start_go,
+ inputs=[ticket_ui, time_tmp, interval_ui, mode_ui, total_attempts_ui],
+ outputs=[go_ui, stop_btn, qr_image, gt_row, gt_ui, challenge_ui],
+ )
+ stop_btn.click(
+ fn=stop,
+ inputs=None,
+ outputs=[go_ui, stop_btn, qr_image, gt_row],
+ )
\ No newline at end of file
diff --git a/tab/settings.py b/tab/settings.py
new file mode 100644
index 0000000..16efbde
--- /dev/null
+++ b/tab/settings.py
@@ -0,0 +1,208 @@
+from datetime import datetime
+import json
+from loguru import logger
+import gradio as gr
+
+from config import cookies_config_path
+from util.bili_request import BiliRequest
+
+buyer_value = []
+addr_value = []
+ticket_value = []
+
+
+def on_submit_ticket_id(num):
+ global buyer_value
+ global addr_value
+ global ticket_value
+
+ try:
+ num = int(num)
+ bili_request = BiliRequest(cookies_config_path=cookies_config_path)
+ res = bili_request.get(
+ url=f"https://show.bilibili.com/api/ticket/project/getV2?version=134&id={num}&project_id={num}"
+ )
+ ret = res.json()
+ logger.debug(ret)
+
+ data = ret["data"]
+ ticket_str_list = []
+
+ project_id = data["id"]
+ project_name = data["name"]
+
+ project_start_time = datetime.fromtimestamp(data["start_time"]).strftime(
+ "%Y-%m-%d %H:%M:%S"
+ )
+ project_end_time = datetime.fromtimestamp(data["end_time"]).strftime(
+ "%Y-%m-%d %H:%M:%S"
+ )
+
+ venue_info = data["venue_info"]
+ venue_name = venue_info["name"]
+ venue_address = venue_info["address_detail"]
+
+ for screen in data["screen_list"]:
+ screen_name = screen["name"]
+ screen_id = screen["id"]
+ for ticket in screen["ticket_list"]:
+ ticket_desc = ticket["desc"]
+ ticket_price = ticket["price"]
+
+ ticket["screen"] = screen_name
+ ticket["screen_id"] = screen_id
+ ticket_can_buy = "可购买" if ticket["clickable"] else "无法购买"
+ ticket_str = f"{screen_name} - {ticket_desc} - ¥{ticket_price / 100} - {ticket_can_buy}"
+ ticket_str_list.append(ticket_str)
+ ticket_value.append({"project_id": project_id, "ticket": ticket})
+
+ buyer_json = bili_request.get(
+ url=f"https://show.bilibili.com/api/ticket/buyer/list?is_default&projectId={project_id}"
+ ).json()
+ logger.debug(buyer_json)
+ addr_json = bili_request.get(
+ url="https://show.bilibili.com/api/ticket/addr/list"
+ ).json()
+ logger.debug(addr_json)
+
+ buyer_value = buyer_json["data"]["list"]
+ buyer_str_list = [
+ f"{item['name']}-{item['personal_id']}" for item in buyer_value
+ ]
+ addr_value = addr_json["data"]["addr_list"]
+ addr_str_list = [
+ f"{item['addr']}-{item['name']}-{item['phone']}" for item in addr_value
+ ]
+
+ return [
+ gr.update(choices=ticket_str_list),
+ gr.update(choices=buyer_str_list),
+ gr.update(choices=buyer_str_list),
+ gr.update(choices=addr_str_list),
+ gr.update(visible=True),
+ gr.update(
+ value=f"获取票信息成功:\n展会名称:{project_name}\n"
+ f"开展时间:{project_start_time} - {project_end_time}\n场馆地址:{venue_name} {venue_address}",
+ visible=True,
+ ),
+ ]
+ except Exception as e:
+ return [
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(),
+ gr.update(value=e, visible=True),
+ ]
+
+
+def on_submit_all(ticket_info, people_indices, people_buyer_index, address_index):
+ try:
+ # if ticket_number != len(people_indices):
+ # return gr.update(
+ # value="生成配置文件失败,保证选票数目和购买人数目一致", visible=True
+ # )
+ ticket_cur = ticket_value[ticket_info]
+ people_cur = [buyer_value[item] for item in people_indices]
+ people_buyer_cur = buyer_value[people_buyer_index]
+
+ address_cur = addr_value[address_index]
+ config_dir = {
+ "count": len(people_indices),
+ "screen_id": ticket_cur["ticket"]["screen_id"],
+ "project_id": ticket_cur["project_id"],
+ "sku_id": ticket_cur["ticket"]["id"],
+ "order_type": 1,
+ "buyer_info": people_cur,
+ "buyer": people_buyer_cur["name"],
+ "tel": people_buyer_cur["tel"],
+ "deliver_info": {
+ "name": address_cur["name"],
+ "tel": address_cur["phone"],
+ "addr_id": address_cur["id"],
+ "addr": address_cur["prov"]
+ + address_cur["city"]
+ + address_cur["area"]
+ + address_cur["addr"],
+ },
+ }
+ return gr.update(value=json.dumps(config_dir), visible=True)
+ except Exception as e:
+ logger.info(e)
+ return gr.update(value="生成错误,仔细看看你可能有哪里漏填的", visible=True)
+
+
+def setting_tab():
+ info_ui = gr.TextArea(
+ info="此窗口为输出信息", label="输出信息", interactive=False, visible=False
+ )
+ with gr.Column():
+ ticket_id_ui = gr.Textbox(
+ label="票 ID",
+ interactive=True,
+ info="例如:要抢的网址是 https://show.bilibili.com/platform/detail.html?id=84096 就要填写 84096",
+ )
+ ticket_id_btn = gr.Button("获取票信息")
+ with gr.Column(visible=False) as inner:
+ with gr.Row():
+ people_ui = gr.CheckboxGroup(
+ label="身份证实名认证",
+ interactive=True,
+ type="index",
+ info="在哔哩哔哩客户端-会员购-个人中心-购票人信息中添加",
+ )
+ ticket_info_ui = gr.Dropdown(
+ label="选票",
+ interactive=True,
+ type="index",
+ info="此处的「无法购买」仅代表当前状态",
+ )
+ with gr.Row():
+ people_buyer_ui = gr.Dropdown(
+ label="联系人",
+ interactive=True,
+ type="index",
+ info="与实名认证同样在「购票人信息」中添加",
+ )
+ address_ui = gr.Dropdown(
+ label="地址",
+ interactive=True,
+ type="index",
+ info="会员购收货地址",
+ )
+
+ config_btn = gr.Button("生成配置")
+ # config_output_ui = gr.Textbox(
+ # label="生成配置文件",
+ # show_copy_button=True,
+ # info="右上角粘贴",
+ # visible=False,
+ # )
+ config_output_ui = gr.JSON(
+ label="生成配置文件(右上角复制)",
+ visible=False,
+ )
+ config_btn.click(
+ fn=on_submit_all,
+ inputs=[
+ ticket_info_ui,
+ people_ui,
+ people_buyer_ui,
+ address_ui,
+ ],
+ outputs=config_output_ui,
+ )
+
+ ticket_id_btn.click(
+ fn=on_submit_ticket_id,
+ inputs=ticket_id_ui,
+ outputs=[
+ ticket_info_ui,
+ people_ui,
+ people_buyer_ui,
+ address_ui,
+ inner,
+ info_ui,
+ ],
+ )
diff --git a/tab/train.py b/tab/train.py
new file mode 100644
index 0000000..5f921e3
--- /dev/null
+++ b/tab/train.py
@@ -0,0 +1,106 @@
+from urllib.parse import urlencode
+import gradio as gr
+
+from config import cookies_config_path
+from util.bili_request import BiliRequest
+
+
+def train_tab():
+ _request = BiliRequest(cookies_config_path=cookies_config_path)
+
+ gr.Markdown("💪 在这里训练一下手过验证码的速度,提前演练一下")
+ test_get_challenge_btn = gr.Button("开始测试")
+ test_log = gr.JSON(label="测试结果(验证码过期是正常现象)")
+
+ with gr.Row(visible=False) as test_gt_row:
+ test_gt_html_start_btn = gr.Button("点击打开抢票验证码(请勿多点!!)")
+ test_gt_html_finish_btn = gr.Button("完成验证码后点此此按钮")
+ gr.HTML(
+ value="""
+
+
+
+
+ """,
+ label="验证码",
+ )
+ test_gt_ui = gr.Textbox(label="gt", visible=True)
+ test_challenge_ui = gr.Textbox(label="challenge", visible=True)
+ geetest_result = gr.JSON(label="validate")
+
+ def test_get_challenge():
+ global \
+ test_challenge, \
+ test_gt, \
+ test_token, \
+ test_csrf, \
+ test_geetest_validate, \
+ test_geetest_seccode
+ test_res = _request.get(
+ "https://passport.bilibili.com/x/passport-login/captcha?source=main_web"
+ ).json()
+ test_challenge = test_res["data"]["geetest"]["challenge"]
+ test_gt = test_res["data"]["geetest"]["gt"]
+ test_token = test_res["data"]["token"]
+ test_csrf = _request.cookieManager.get_cookies_value("bili_jct")
+ test_geetest_validate = ""
+ test_geetest_seccode = ""
+ return [
+ gr.update(value=test_gt), # test_gt_ui
+ gr.update(value=test_challenge), # test_challenge_ui
+ gr.update(visible=True), # test_gt_row
+ gr.update(value="重新生成"), # test_get_challenge_btn
+ ]
+
+ test_get_challenge_btn.click(
+ fn=test_get_challenge,
+ inputs=None,
+ outputs=[test_gt_ui, test_challenge_ui, test_gt_row, test_get_challenge_btn],
+ )
+ test_gt_html_start_btn.click(
+ fn=None,
+ inputs=[test_gt_ui, test_challenge_ui],
+ outputs=None,
+ js="""
+ (gt, challenge) => initGeetest({
+ gt, challenge,
+ offline: false,
+ new_captcha: true,
+ product: "popup",
+ width: "300px",
+ https: true
+ }, function (test_captchaObj) {
+ window.test_captchaObj = test_captchaObj;
+ $('#captcha_test').empty();
+ test_captchaObj.appendTo('#captcha_test');
+ })
+ """,
+ )
+
+ test_gt_html_finish_btn.click(
+ fn=None,
+ inputs=None,
+ outputs=geetest_result,
+ js="() => test_captchaObj.getValidate()",
+ )
+ def receive_geetest_result(res):
+ global test_geetest_validate, test_geetest_seccode
+ test_geetest_validate = res["geetest_validate"]
+ test_geetest_seccode = res["geetest_seccode"]
+ geetest_result.change(fn=receive_geetest_result, inputs=geetest_result)
+
+ def test_doing():
+ while test_geetest_validate == "" or test_geetest_seccode == "":
+ continue
+ _url = "https://api.bilibili.com/x/gaia-vgate/v1/validate"
+ _payload = {
+ "challenge": test_challenge,
+ "token": test_token,
+ "seccode": test_geetest_seccode,
+ "csrf": test_csrf,
+ "validate": test_geetest_validate,
+ }
+ test_data = _request.post(_url, urlencode(_payload))
+ yield gr.update(value=test_data.json())
+
+ test_gt_html_finish_btn.click(fn=test_doing, outputs=[test_log])
diff --git a/util/JsonUtil.py b/util/JsonUtil.py
deleted file mode 100644
index 161a51f..0000000
--- a/util/JsonUtil.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import json
-
-
-class ProjectInfo:
- def __init__(self, data):
- self.data = data["data"]
-
- def get_name(self):
- return self.data["name"]
-
- def get_screen_list(self):
- return self.data["screen_list"]
-
- def get_ticket_info(self):
- raw_list = self.data["screen_list"]
-
-
-class ProfileInfo:
- def __init__(self, data):
- self.personList = data["data"]["list"]
-
- def get_persons(self):
- return self.personList
-
-class AddrInfo:
- def __init__(self, data):
- self.addrList = data["data"]["addr_list"]
-
- def get_addrs(self):
- return self.addrList
\ No newline at end of file
diff --git a/util/BiliRequest.py b/util/bili_request.py
similarity index 51%
rename from util/BiliRequest.py
rename to util/bili_request.py
index cd598d2..0580881 100644
--- a/util/BiliRequest.py
+++ b/util/bili_request.py
@@ -1,6 +1,6 @@
import requests
-from util.configUtil import CookieManager
+from util.config_util import CookieManager
class BiliRequest:
@@ -9,26 +9,26 @@ def __init__(self, headers=None, cookies=None, cookies_config_path=""):
self.cookieManager = CookieManager(cookies_config_path)
self._cookies = self.cookieManager.get_cookies_str()
self.headers = headers or {
- 'authority': 'show.bilibili.com',
- 'accept': '*/*',
- 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5,ja;q=0.4',
- 'cookie': self._cookies,
- 'referer': "https://show.bilibili.com/",
- 'content-type': 'application/x-www-form-urlencoded',
- 'sec-ch-ua': '"Microsoft Edge";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
- 'sec-ch-ua-mobile': '?0',
- 'sec-ch-ua-platform': '"Windows"',
- 'sec-fetch-dest': 'empty',
- 'sec-fetch-mode': 'cors',
- 'sec-fetch-site': 'same-origin',
- '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 Edg/119.0.0.0'
+ "authority": "show.bilibili.com",
+ "accept": "*/*",
+ "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5,ja;q=0.4",
+ "cookie": self._cookies,
+ "referer": "https://show.bilibili.com/",
+ "content-type": "application/x-www-form-urlencoded",
+ "sec-ch-ua": '"Microsoft Edge";v="119", "Chromium";v="119", "Not?A_Brand";v="24"',
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": '"Windows"',
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "same-origin",
+ "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 Edg/119.0.0.0",
}
def get(self, url, data=None):
response = self.session.get(url, data=data, headers=self.headers)
response.raise_for_status()
if response.json().get("msg", "") == "请先登录":
- self.headers['cookies'] = self.cookieManager.get_cookies_str_force()
+ self.headers["cookies"] = self.cookieManager.get_cookies_str_force()
self.get(url, data)
return response
@@ -36,13 +36,15 @@ def post(self, url, data=None):
response = self.session.post(url, data=data, headers=self.headers)
response.raise_for_status()
if response.json().get("msg", "") == "请先登录":
- self.headers['cookies'] = self.cookieManager.get_cookies_str_force()
+ self.headers["cookies"] = self.cookieManager.get_cookies_str_force()
self.post(url, data)
return response
-if __name__ == '__main__':
+if __name__ == "__main__":
payload = {}
_request = BiliRequest(cookies_config_path="../config/cookies.json")
- res = _request.get(url="https://show.bilibili.com/api/ticket/project/get?version=134&id=77938&project_id=77938")
+ res = _request.get(
+ url="https://show.bilibili.com/api/ticket/project/get?version=134&id=77938&project_id=77938"
+ )
print(res.json()["data"])
diff --git a/util/configUtil.py b/util/config_util.py
similarity index 63%
rename from util/configUtil.py
rename to util/config_util.py
index 2de2065..5c6b992 100644
--- a/util/configUtil.py
+++ b/util/config_util.py
@@ -1,40 +1,43 @@
import json
-import logging
import time
+import requests
-from requests import utils
+from loguru import logger
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
-logging.basicConfig(level=logging.INFO) # 设置日志级别
-
class CookieManager:
def __init__(self, config_file_path):
self.config = {}
self.config_file_path = config_file_path
- self.cookie_jar = utils.cookiejar_from_dict(self.config)
+ self.cookie_jar = requests.utils.cookiejar_from_dict(self.config)
- def _login_and_save_cookies(self, login_url="https://show.bilibili.com/platform/home.html"):
- logging.info("启动浏览器中.....")
+ @logger.catch
+ def _login_and_save_cookies(
+ self, login_url="https://show.bilibili.com/platform/home.html"
+ ):
+ logger.info("启动浏览器中.....")
try:
- self.driver = webdriver.Edge()
- except Exception as e:
+ self.driver = webdriver.Chrome()
+ except Exception:
try:
self.driver = webdriver.Chrome()
- except Exception as e:
- raise Exception("没有找到浏览器驱动,请根据自己的浏览器下载相应的驱动:\n"
- "相关教程:https://blog.csdn.net/zz00008888/article/details/127903475\n"
- "Edge: https://liushilive.github.io/github_selenium_drivers/md/IE.html\n"
- "Chrome:https://liushilive.github.io/github_selenium_drivers/md/Chrome.html\n")
+ except Exception:
+ raise Exception(
+ "没有找到浏览器驱动,请根据自己的浏览器下载相应的驱动:\n"
+ "相关教程:https://blog.csdn.net/zz00008888/article/details/127903475\n"
+ "Edge: https://liushilive.github.io/github_selenium_drivers/md/IE.html\n"
+ "Chrome:https://liushilive.github.io/github_selenium_drivers/md/Chrome.html\n"
+ )
self.wait = WebDriverWait(self.driver, 0.5)
self.driver.get(login_url)
self.driver.maximize_window()
time.sleep(1)
self.driver.find_element(By.CLASS_NAME, "nav-header-register").click()
- logging.info("浏览器启动, 进行登录.")
+ logger.info("浏览器启动, 进行登录.")
while True:
try:
self.driver.find_element(By.CLASS_NAME, "nav-header-register")
@@ -42,17 +45,20 @@ def _login_and_save_cookies(self, login_url="https://show.bilibili.com/platform/
break
time.sleep(1)
self.config["bilibili_cookies"] = self.driver.get_cookies()
- with open(self.config_file_path, 'w') as f:
- json.dump(self.config, f, indent=4)
+ self.dump_config()
self.driver.quit()
- logging.info("登录成功, 浏览器退出.")
+ logger.info("登录成功, 浏览器退出.")
return self.config["bilibili_cookies"]
+ def dump_config(self):
+ with open(self.config_file_path, "w") as f:
+ json.dump(self.config, f, indent=4)
+
def get_cookies(self):
try:
- with open(self.config_file_path, 'r') as f:
+ with open(self.config_file_path, "r") as f:
self.config = json.load(f)
- except Exception as e:
+ except Exception:
return self._login_and_save_cookies()
if self.config == {}:
@@ -85,4 +91,4 @@ def get_cookies_str_force(self):
if __name__ == "__main__":
cookie_manager = CookieManager("../config/cookies.json")
- logging.info(str(cookie_manager.get_cookies_str()))
+ logger.info(str(cookie_manager.get_cookies_str()))
diff --git a/util/error.py b/util/error.py
index 75aa881..670eab7 100644
--- a/util/error.py
+++ b/util/error.py
@@ -1,5 +1,5 @@
# 欢迎补充错误码
-errnoDict = {
+ERRNO_DICT = {
3: "速度过快,请慢一点",
100009: "库存不足,暂无余票",
100001: "无票",
diff --git a/util/order_qrcode.py b/util/order_qrcode.py
index a0f2cf1..d7f5325 100644
--- a/util/order_qrcode.py
+++ b/util/order_qrcode.py
@@ -2,8 +2,9 @@
def get_qrcode_url(_request, token, project_id, order_id):
- url = "https://show.bilibili.com/api/ticket/order/createstatus?token=" + token + "×tamp=" + str(
- int(round(time.time() * 1000))) + "&project_id=" + str(project_id) + "&orderId=" + str(order_id)
+ url = f"https://show.bilibili.com/api/ticket/order/createstatus?token={token}"
+ f"×tamp={int(round(time.time() * 1000))}"
+ f"&project_id={project_id}&orderId={order_id}"
data = _request.get(url).json()
if data["errno"] == 0:
return data["data"]["payParam"]["code_url"]
diff --git a/util/webUtil.py b/util/webUtil.py
deleted file mode 100644
index f7612f5..0000000
--- a/util/webUtil.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import json
-import logging
-import threading
-import time
-
-from selenium import webdriver
-from selenium.webdriver.support.ui import WebDriverWait
-
-
-class WebUtil:
- def __init__(self, cookie_dict):
- self.initialized_event = threading.Event()
-
- initialization_thread = threading.Thread(target=self.initialize, args=(cookie_dict,))
- initialization_thread.start()
-
- def initialize(self, cookie_dict):
- self.driver = webdriver.Edge()
- self.driver.get("https://show.bilibili.com/platform/home.html")
-
- for cookie in cookie_dict["bilibili_cookies"]:
- self.driver.add_cookie(cookie)
- self.driver.refresh()
- self.wait = WebDriverWait(self.driver, 0.5)
- self.initialized_event.set()