python 使用request模块访问微信(gettoken)报错及解决办法

本文介绍了解决Python在使用request模块访问微信接口时遇到的SSL相关问题的方法。包括安装OpenSSL和openssl-devel,重新编译Python,以及在requests的post和get方法中设置verify参数为FALSE。

1、python 使用request模块访问微信(gettoken)报错:

can`t connect https url ssl module not available

如下图:

原因:编译python的时候可能没有安装OpenSSL和openssl-devel

解决办法,yum -y install openssl openssh-devel 然后重新编译python


2、编译后报错:

Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)')


解决办法,requests的post和get方法加参数verify =FALSE


执行成功。

<think>我们正在讨论企业微信机器人的消息监听。企业微信本身不提供直接的消息推送服务,但可以通过设置回调URL或使用企业微信提供的API进行消息的接收。常见的方式是使用企业微信的“接收消息服务器配置”功能,设置一个可公网访问的URL作为接收消息的入口。 然而,根据企业微信的文档,接收消息需要以下步骤: 1. 在企业微信管理后台设置接收消息的服务器配置(包括URL、Token、EncodingAESKey)。 2. 开发一个服务,部署在公网可访问的服务器上,用于接收企业微信推送的消息(包括事件和普通消息)。 3. 服务需要验证URL(企业微信会发送一个GET请求进行验证)以及处理后续的消息(POST请求)。 但是,请注意,企业微信的消息接收是推送模式,而不是主动轮询。因此,我们需要一个Web服务来接收企业微信的推送。 由于用户要求使用Python,我们可以使用Flask或类似的Web框架来搭建一个简单的服务器。 步骤: 1. 在管理后台设置接收消息的服务器配置(需要公网URL)。 2. 编写一个Flask应用,提供两个路由:一个用于验证URL(GET请求),另一个用于接收消息(POST请求)。 3. 在验证URL时,企业微信会发送echostr参数,我们需要对这个参数进行解密(如果选择了加密模式)并返回解密后的字符串以验证成功。 4. 接收消息时,需要解析XML格式的消息(企业微信默认使用XML格式),并回复。 注意:企业微信支持明文模式、兼容模式和安全模式(加密)。我们这里以兼容模式为例,因为兼容模式可以同时处理明文和加密消息。 由于企业微信的API文档中提供了具体的加解密方法,我们可以使用企业微信提供的加解密库(WXBizMsgCrypt)或者自己实现(但推荐使用官方提供的)。 但是,由于官方提供的加解密库只有Python2版本,对于Python3,我们可以使用第三方库或者自己移植。这里为了简化,我们使用一个已有的Python3移植版本,或者使用一个纯Python实现的加解密方法。 不过,请注意,企业微信的消息接收和回复需要遵循一定的协议,包括消息加密、签名验证等。 由于实现整个加解密过程较为复杂,我们可以先使用明文模式(不加密)来简化开发。在设置接收消息服务器时,选择明文模式,这样就不需要解密,只需要验证签名(签名由token、时间戳、随机数和消息体计算得出)。 具体步骤: 1. 设置服务器配置: - URL:填写你的公网URL,例如:http://yourdomain.com/wechat - Token:自定义的token字符串 - EncodingAESKey:随机生成(如果选择加密模式则需要,明文模式可以忽略) - 选择明文模式 2. 编写Flask应用: 安装Flask: `pip install flask` 示例代码: ```python from flask import Flask, request, make_response import time import hashlib import xml.etree.ElementTree as ET app = Flask(__name__) # 企业微信后台设置的Token TOKEN = "YourTokenHere" # 验证URL @app.route('/wechat', methods=['GET']) def verify_url(): # 获取参数 signature = request.args.get('msg_signature', '') timestamp = request.args.get('timestamp', '') nonce = request.args.get('nonce', '') echostr = request.args.get('echostr', '') # 验证签名(在明文模式下,签名计算方式为:用token、timestamp、nonce和echostr(如果有)进行字典序排序后拼接,然后做sha1加密) # 注意:明文模式下,企业微信发送的GET请求中只有signature(即msg_signature)、timestamp、nonce和echostr参数,但这里的signature实际上就是msg_signature # 但是根据文档,在URL验证时,即使明文模式,企业微信也是用加密模式的方式发送的(即msg_signature),但此时echostr是加密的?实际上在明文模式时,echostr是明文的,而msg_signature的计算方法不同。 # 这里我们按照文档说明:在明文模式下,验证URL时,企业微信发送的是明文echostr,并且msg_signature的计算方法为:对token、timestamp、nonce和echostr进行字典序排序后拼接,然后sha1加密,然后与signature比较。 # 计算签名 list = [TOKEN, timestamp, nonce, echostr] list.sort() s = ''.join(list) sha1 = hashlib.sha1() sha1.update(s.encode('utf-8')) hashcode = sha1.hexdigest() # 如果计算出的签名与请求中的signature一致,则返回echostr if hashcode == signature: return make_response(echostr) else: return make_response('验证失败', 403) # 接收消息 @app.route('/wechat', methods=['POST']) def receive_msg(): # 获取参数 signature = request.args.get('msg_signature', '') timestamp = request.args.get('timestamp', '') nonce = request.args.get('nonce', '') # 读取请求体 body = request.data # 解析XML xml_data = ET.fromstring(body) # 消息类型,有事件(event)和普通消息(text等) msg_type = xml_data.find('MsgType').text # 如果是文本消息 if msg_type == 'text': content = xml_data.find('Content').text from_user = xml_data.find('FromUserName').text to_user = xml_data.find('ToUserName').text # 这里可以处理消息,例如自动回复 # 构造回复的XML(明文模式) reply_content = f"你发送的消息是:{content}" # 注意:回复也需要按照企业微信的格式,并且需要计算签名?但是明文模式下回复不需要签名,直接明文XML # 但是根据企业微信文档,回复的消息需要加密吗?在明文模式下,回复也是明文。 # 构造XML reply_xml = f""" <xml> <ToUserName><![CDATA[{from_user}]]></ToUserName> <FromUserName><![CDATA[{to_user}]]></FromUserName> <CreateTime>{int(time.time())}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[{reply_content}]]></Content> </xml> """ return make_response(reply_xml) else: # 其他类型消息,可以忽略或处理 return 'success' # 返回success表示接收成功,企业微信不会重试 if __name__ == '__main__': app.run(host='0.0.0.0', port=80) ``` 注意:以上代码仅用于演示,实际生产环境需要考虑更多情况,如消息加密、各种消息类型的处理、异常处理等。 3. 部署:需要将应用部署在公网服务器上,并确保80端口可访问(或使用其他端口,但企业微信要求URL必须是80或443端口,或者使用反向代理将80端口的请求转发到其他端口)。 4. 在企业微信管理后台设置好URL(如:http://yourdomain.com/wechat)和Token,选择明文模式,然后保存。企业微信会发送一个GET请求进行验证,验证通过后即可接收消息。 重要提示:企业微信的消息接收服务器要求必须在5秒内返回响应,否则会认为失败并重试(最多重试三次)。因此,处理消息的逻辑需要快速完成,或者将耗时操作放入异步队列。 以上是一个简单的实现,实际开发中还需要考虑安全性、消息重试、消息去重等问题。 另外,企业微信也提供了第三方库(如WeWorkFinanceSDK)用于获取会话记录,但那是另一种方式(主动拉取),需要企业具有会话存档权限。这里我们讨论的是接收实时消息,所以使用回调模式。 参考引用: [企业微信接收消息与事件](https://work.weixin.qq.com/api/doc/90000/90135/90240)[^1] 注意:由于企业微信的API可能会更新,请以最新官方文档为准。 相关问题: 1. 如何设置企业微信接收消息的服务器配置? 2. 企业微信消息接收中,如何实现消息解密(加密模式)? 3. 企业微信支持哪些类型的消息和事件? 4. 如何用Python实现企业微信的消息加密和解密? 5. 企业微信接收消息服务器如何保证安全性?</think>### Python监听企业微信消息接收方法 要使用Python监听企业微信消息,需要通过企业微信的**回调模式**实现。以下是完整实现步骤: --- ### 1. 准备工作 - 获取企业ID(`corpid`)和应用凭证(`corpsecret`) - 在[企业微信管理后台](https://work.weixin.qq.com/)创建应用 - 准备公网可访问的服务器(或使用内网穿透工具如ngrok) --- ### 2. 核心代码实现 #### (1) 获取Access Token ```python import requests def get_access_token(corpid, corpsecret): url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}" response = requests.get(url) if response.status_code == 200: return response.json()['access_token'] else: raise Exception("获取Token失败") ``` #### (2) 设置接收消息服务器 ```python def set_callback_url(access_token, url, token, aes_key): api_url = f"https://qyapi.weixin.qq.com/cgi-bin/chatgroup/set_callback_url?access_token={access_token}" payload = { "url": url, # 你的公网URL "token": token, # 自定义Token "encodingaeskey": aes_key # 企业微信生成的AESKey } response = requests.post(api_url, json=payload) return response.json() ``` #### (3) Flask消息接收服务 ```python from flask import Flask, request, make_response import xml.etree.ElementTree as ET import hashlib app = Flask(__name__) # 验证URL有效性(企业微信首次配置时调用) @app.route('/callback', methods=['GET']) def verify_url(): signature = request.args.get('msg_signature', '') timestamp = request.args.get('timestamp', '') nonce = request.args.get('nonce', '') echostr = request.args.get('echostr', '') # 计算签名验证(需实现) if verify_signature(signature, timestamp, nonce, echostr): return make_response(echostr, 200) else: return "验证失败", 403 # 接收消息入口 @app.route('/callback', methods=['POST']) def handle_message(): xml_data = request.data # 解析XML消息(需实现解密逻辑) msg = parse_message(xml_data) print(f"收到消息: {msg}") # 此处添加消息处理逻辑 return "success" def verify_signature(signature, timestamp, nonce, echostr): # 实际实现需结合Token和AESKey计算 # 参考公式: sha1(sort(Token, timestamp, nonce, echostr)) return True # 简化示例 if __name__ == '__main__': app.run(host='0.0.0.0', port=80) ``` --- ### 3. 配置步骤 1. **生成AESKey**:在企业微信后台"接收消息"页面生成 2. **设置回调URL**: ```python set_callback_url( access_token="YOUR_ACCESS_TOKEN", url="https://yourdomain.com/callback", token="YOUR_TOKEN", aes_key="YOUR_AES_KEY" ) ``` 3. **启动服务**:运行Flask应用 4. **验证服务器**:在企业微信后台启用配置 --- ### 4. 消息处理要点 - **消息格式**:XML格式,需解析`<Content>`标签 - **消息类型**:支持文本/图片/语音/视频等类型 - **安全验证**:必须实现签名验证和消息解密 - **响应要求**:必须在5秒内返回`success`,否则企业微信会重试 > 完整实现需参考[企业微信官方文档](https://work.weixin.qq.com/api/doc/90000/90135/90240)[^1],包含消息加解密等安全机制。 --- ### 注意事项 1. 使用**固定公网IP**或域名(避免动态IP变化) 2. 处理**消息重试机制**(企业微信会重发未响应的消息) 3. 敏感操作需验证`AgentID`防止伪造请求 4. 推荐使用官方加解密库[WeChatEnterpriseCrypto](https://github.com/sbzhu/weworkapi_python) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值