Spaces:
Runtime error
Runtime error
| #!/usr/bin/python3 | |
| # -*- coding: utf-8 -*- | |
| import json | |
| import re | |
| from PIL import Image | |
| import requests | |
| from project_settings import project_path | |
| def get_operator_by_track_id_baidu(track_id: str): | |
| url = "https://alayn.baidu.com/express/appdetail/get_com" | |
| params = { | |
| "num": track_id | |
| } | |
| resp = requests.request( | |
| "GET", | |
| url=url, | |
| params=params | |
| ) | |
| if resp.status_code == 200: | |
| match = re.search(r"\{.*\}", resp.text, flags=re.IGNORECASE) | |
| if match is not None: | |
| json_str = match.group(0) | |
| js = json.loads(json_str) | |
| message = js["message"] | |
| if message == "fail": | |
| return None | |
| else: | |
| company = js["data"]["company"] | |
| return company | |
| return None | |
| cookie = None | |
| def get_operator_by_track_id(track_id: str): | |
| global cookie | |
| url = "https://trace.fkdex.com/auto/{}".format(track_id) | |
| headers = { | |
| # 不给出 Referer 时,它会生成随机的物流信息。 | |
| "Referer": "https://www.ickd.cn/", | |
| } | |
| if cookie is not None: | |
| headers["Cookie"] = cookie | |
| params = { | |
| "mailNo": track_id, | |
| } | |
| resp = requests.request( | |
| "GET", | |
| url=url, | |
| headers=headers, | |
| params=params | |
| ) | |
| if resp.status_code == 200: | |
| js = resp.json() | |
| exp_text_name = js["expTextName"] | |
| exp_spell_name = js["expSpellName"] | |
| message = js["message"] | |
| return exp_spell_name, message | |
| return resp.text, None | |
| def get_captcha(): | |
| global cookie | |
| url = "https://trace.fkdex.com/captcha" | |
| headers = { | |
| "Referer": "https://www.ickd.cn/", | |
| } | |
| if cookie is not None: | |
| headers["Cookie"] = cookie | |
| resp = requests.request( | |
| "GET", | |
| url=url, | |
| headers=headers, | |
| ) | |
| if "Set-Cookie" in resp.headers: | |
| _cookie = resp.headers["Set-Cookie"] | |
| _cookie = _cookie.split(";")[0].strip() | |
| else: | |
| _cookie = cookie | |
| filename = project_path / "data/captcha.png" | |
| filename = filename.as_posix() | |
| with open(filename, "wb") as f: | |
| f.write(resp.content) | |
| return {"filename": filename, "cookie": _cookie} | |
| def get_express_delivery_information(track_id: str, four_digits: str = None, captcha: str = None) -> dict: | |
| """ | |
| 如果函数的名字叫作 “get_express_delivery_information” , | |
| 那么就需要一个同名 python 脚本 “get_express_delivery_information.py” , | |
| 同时其中应包含一个名为 “get_express_delivery_information” 的函数。 | |
| https://www.ickd.cn/ | |
| :param track_id: str, egs: 433542074086264. | |
| :param four_digits: str, 收件人或寄件人手机号码后四位. egs: 4154. | |
| :param captcha: str, egs: b2Nbm. | |
| :return: info: str. | |
| """ | |
| global cookie | |
| operator, message = get_operator_by_track_id(track_id) | |
| if (message == "需要验证码" and captcha is None) or cookie is None: | |
| outputs = get_captcha() | |
| captcha_filename = outputs["filename"] | |
| cookie = outputs["cookie"] | |
| message_ = """请让用户提供在 chatting image 中展示的验证码。""" | |
| return {"text": message_, "image": captcha_filename} | |
| if four_digits is None: | |
| url = "https://trace.fkdex.com/{}/{}".format(operator, track_id) | |
| else: | |
| url = "https://trace.fkdex.com/{}/{}:{}".format(operator, track_id, four_digits) | |
| headers = { | |
| # 不给出 Referer 时,它会生成随机的物流信息。 | |
| "Referer": "https://www.ickd.cn/", | |
| "Cookie": cookie | |
| } | |
| params = { | |
| "mailNo": "{}:{}".format(track_id, four_digits), | |
| "verifyCode": captcha | |
| } | |
| resp = requests.request( | |
| "GET", | |
| url=url, | |
| headers=headers, | |
| params=params | |
| ) | |
| # print(resp.status_code) | |
| # print(resp.text) | |
| if resp.status_code == 200: | |
| js = resp.json() | |
| error_code = js["errCode"] | |
| message = js["message"] | |
| exp_text_name = js["expTextName"] | |
| exp_spell_name = js["expSpellName"] | |
| data = js["data"] | |
| if error_code == 1: | |
| # 请输入正确的单号 | |
| return {"text": message} | |
| elif error_code == 2: | |
| # 请输入【收件人】或【寄件人】\n电话号码后4位 | |
| return {"text": message} | |
| elif error_code == 3: | |
| # 快递公司服务器繁忙,稍后再试(连接服务器超时) | |
| return {"text": message} | |
| elif error_code == 14: | |
| # 需要验证码 | |
| outputs = get_captcha() | |
| captcha_filename = outputs["filename"] | |
| cookie = outputs["cookie"] | |
| message_ = """请让用户提供在 chatting image 中展示的验证码。""" | |
| return {"text": message_, "image": captcha_filename} | |
| if error_code != 0: | |
| print(message) | |
| return {"text": message} | |
| track_info = "" | |
| for row in data: | |
| date = row["time"] | |
| context = row["context"] | |
| row_ = "{}: {}".format(date, context) | |
| track_info += row_ | |
| track_info += "\n" | |
| result = "快递公司名称: {}\n快递单号: {}\n手机号码后四位: {}\n物流信息如下: \n\n{}".format( | |
| exp_text_name, track_id, four_digits, track_info | |
| ) | |
| return {"text": result} | |
| return {"text": "物流信息查询失败。"} | |
| def kwargs(): | |
| return ["track_id", "four_digits", "captcha"] | |
| def main(): | |
| tools = [ | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "get_express_delivery_information", | |
| "description": "在此根据跟踪号查询物流信息。", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "track_id": { | |
| "type": "string", | |
| "description": "物流跟踪号码。", | |
| }, | |
| "four_digits": { | |
| "type": "string", | |
| "description": "出于对用户隐私的考虑,有些物流商可能会要求你提供收件人或寄件人手机号码后四位。", | |
| }, | |
| "captcha": { | |
| "type": "string", | |
| "description": "有些物流商的查询可能要求你提供图像验证码。", | |
| } | |
| }, | |
| "required": ["track_id"], | |
| }, | |
| }, | |
| } | |
| ] | |
| tools_ = json.dumps(tools, ensure_ascii=False) | |
| print(tools_) | |
| print(tools_.replace("\"", "\\\"")) | |
| # track_id = "33212432323" | |
| # four_digits = None | |
| # track_id = "433542074086264" | |
| # four_digits = "4154" | |
| # four_digits = None | |
| track_id = "4577035024" | |
| four_digits = None | |
| captcha = "VWDYW" | |
| # result = get_operator_by_track_id(track_id) | |
| # print(result) | |
| result = get_express_delivery_information(track_id, four_digits, captcha) | |
| print(result) | |
| return | |
| if __name__ == '__main__': | |
| main() | |