文档章节

使用python导出公众号关注用户

海鲜新零售
 海鲜新零售
发布于 2018/08/21 10:48
字数 1448
阅读 196
收藏 0

要从公众号导出关注用户,共需要三步:

  1. 获取access_token
  2. 获取关注用户的Open_id
  3. 根据open_id获取用户的信息

获取access_token

公众号文档对access_token的简介:

URL: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回结果:{"access_token":"ACCESS_TOKEN","expires_in":7200}

字段解析:
grant_type	是	获取access_token填写client_credential
appid	是	第三方用户唯一凭证
secret	是	第三方用户唯一凭证密钥,即appsecret

获取access_token的代码:

access_token = None
def get_access_token():
	url = 'https://api.weixin.qq.com/cgi-bin/token'
	global access_token
	params = {
		'grant_type':'client_credential',
		'appid':'xxxxx', #从公众号上找到自己的appid
		'secret':'xxxx', #从公众号上找到自己的secret
	}

	response = get(url, params)

	# print(response.text)

	json_data = json.loads(response.text)
	access_token = json_data['access_token']

access_token的有效期是7200秒,过期需要重新获取。

获取关注用户的Open_id

公众号文档对获取关注用户的open_id列表的文档:

URL: https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

返回结果:{
"total":2,
"count":2,
"data":{
"openid":["OPENID1","OPENID2"]},
"next_openid":"NEXT_OPENID"
}

字段解析:
total	关注该公众账号的总用户数
count	拉取的OPENID个数,最大值为10000
data	列表数据,OPENID的列表
next_openid	拉取列表的最后一个用户的OPENID

获取open_id列表的python代码:

openids = []
def get_openids(next_openid=''):
	global openids
	url = 'https://api.weixin.qq.com/cgi-bin/user/get'
	params = {
		'access_token':access_token,
		'next_openid':next_openid,
	}

	response = get(url, params)

	# print(response.text)

	json_data = json.loads(response.text)
	count = json_data['count']
	openid_list = json_data['data']['openid']
	openids.extend(openid_list)
	next_openid = json_data['next_openid']

	logger.info('>>> count=%s, next_openid=%s'%(count,next_openid))

	if count == 10000:
		get_openids(next_openid)

每个请求最多返回10000个open_id。 第一次请求,next_open_id是空的。 我这里直接判断上次返回的open_id的数量。如果返回数量是10000个,就尝试再请求下一批Open_id。

根据open_id获取用户的信息

公众号文档对获取用户信息的文档描述:

URL: https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN
请求参数:
{
    "user_list": [
        {
            "openid": "otvxTs4dckWG7imySrJd6jSi0CWE", 
            "lang": "zh_CN"
        }, 
        {
            "openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg", 
            "lang": "zh_CN"
        }
    ]
}

返回结果:
{
    "subscribe": 1, 
    "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", 
    "nickname": "Band", 
    "sex": 1, 
    "language": "zh_CN", 
    "city": "广州", 
    "province": "广东", 
    "country": "中国", 
    "headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
    "subscribe_time": 1382694957,
    "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
    "remark": "",
    "groupid": 0,
    "tagid_list":[128,2],
    "subscribe_scene": "ADD_SCENE_QR_CODE",
    "qr_scene": 98765,
    "qr_scene_str": ""
}

字段解析:
subscribe	用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
openid	用户的标识,对当前公众号唯一
nickname	用户的昵称
sex	用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
city	用户所在城市
country	用户所在国家
province	用户所在省份
language	用户的语言,简体中文为zh_CN
headimgurl	用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
subscribe_time	用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
unionid	只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
remark	公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
groupid	用户所在的分组ID(兼容旧的用户分组接口)
tagid_list	用户被打上的标签ID列表
subscribe_scene	返回用户关注的渠道来源,ADD_SCENE_SEARCH 公众号搜索,ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移,ADD_SCENE_PROFILE_CARD 名片分享,ADD_SCENE_QR_CODE 扫描二维码,ADD_SCENEPROFILE LINK 图文页内名称点击,ADD_SCENE_PROFILE_ITEM 图文页右上角菜单,ADD_SCENE_PAID 支付后关注,ADD_SCENE_OTHERS 其他
qr_scene	二维码扫码场景(开发者自定义)
qr_scene_str	二维码扫码场景描述(开发者自定义)

获取用户信息的代码:

user_info_list=[]
def get_unionids():
	url = 'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=%s'%access_token
	
	total=len(openids)
	step=100
	repeat=int(total/step+(1 if total%step>0 else 0))

	global user_info_list

	for i in range(repeat):

		low_idx=step*i
		high_idx=len(openids) if len(openids) <= step*(i+1) else step*(i+1)

		if len(openids) <= low_idx:
			break

		openid_params = []
		for openid in openids[low_idx:high_idx]:
			openid_params.append({'openid':openid,'lang':'zh_CN'})

		payload = {'user_list':openid_params}

		logger.info('step=%s,low index=%s,high index=%s' % (i,low_idx,high_idx))
		#json_data = json.dumps(payload)
		#logger.info(json_data)
		
		response = post_json(url, payload)

		json_data = json.loads(response.text)

		try:
			user_infos = json_data['user_info_list']
			user_info_list.extend(user_infos)
			#store_user_infos()
			#exit()
		except KeyError:
			logger.error(response.status_code)
			logger.error(response.text)

这个请求需要用post发送。 每次只能发送100个open_id。

这里遇到两个问题:

  1. 在windows系统,打印请求回来的内容时,遇到gbk编码问题,
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='gb18030')

用上面的代码片段,将打印输出流的编码指定为gb18030,可以支持中文输出

  1. 昵称里有表情符号,无法入库 首先需要让请求返回的数据编码是utf-8 mysql数据库,数据表,文本字段的编码是utf8mb4, 修改完数据配置后,一定要重启数据库,这些编码才能生效。

修改数据库编码的脚本如下:

ALTER DATABASE hello_moto CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

ALTER TABLE t_yown_user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

ALTER TABLE tb_user CHANGE name name VARCHAR(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

数据库的配置(/etc/my.cnf):

[mysql]
default-character-set=utf8mb4

[mysqld]
character_set_server=utf8mb4
init_connect='SET NAMES utf8mb4'

为了简化和重用发送http请求的代码,做了一个小工具类 http.py:

import requests


requests.packages.urllib3.disable_warnings()

s=requests.session()  #获取会话对象

def get(url, data=None):
    response = s.get(url, params=data) if data else s.get(url)

    return response

def post_json(url, payload):
    myheader = {
        "Content-Encoding":"application/json; encoding=utf-8",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
        "Accept-Encoding": "gzip, deflate, br",
        "Content-Type": "application/json; charset=utf-8",
        "Connection": "keep-alive"
    }

    response = s.post(url, headers=myheader, json=payload, verify=False)

    response.encoding = 'utf-8'

    return response

这里面的get, post_json函数的使用,在上面的代码里有。

© 著作权归作者所有

海鲜新零售
粉丝 2
博文 28
码字总数 45206
作品 0
大连
技术主管
私信 提问
时隔 8 年,Flask 1.0 终于发布,放弃支持 Py 2.6 和 3.3

(点击上方公众号,可快速关注) 【导读】:在浏览器拼版本号的时代,有些软件的更新,则显得龟速了。比如:2017 年,Python 科学计算库 SciPy 时隔 16 年后才升到 1.0 版。还有,今天本文的...

p5deyt322jacs
2018/05/02
0
0
如何快速成为优秀架构师(速成版)?

对架构师来说,其劳动成果是很难被评价的。但是,有一类脑力劳动的成果,是比较容易被评价或者能够判断其对错的。比如考试的分数,比赛的输赢等;无论是根据结果或者市场来判断,这些劳动力都...

架构师技术联盟
2018/09/28
0
0
2019年推荐几个你看了就会关注的公众号

大V推荐 作为一个可怜弱小又无助的小萌新,求知若渴却找不到良好的渠道去学习,只能看着教科书苦哈哈的抓瞎学习? 不用担心,这里为大家带来如下几个Python和知乎的大佬们!迷茫的萌新们快扫...

JAVA高级架构v
02/28
0
0
高级爬虫(一):Scrapy爬虫框架的安装

Hi 小伙伴们差不多有半个月没有更新干货了,一直有点忙,而且这中间还有曲折过程,也就没有更新文章. 但今天无论如何也要更新一篇文章,接下来是爬虫高级篇重点讲解的地方! 最近会连载Scrap...

Python绿色通道
2018/04/22
0
0
Python3分析sitemap.xml抓取导出全站链接

最近网站从HTTPS转为HTTP,更换了网址,旧网址做了301重定向,折腾有点大,于是在百度站长平台提交网址,不管是主动推送还是手动提交,前提都是要整理网站的链接,手动添加太麻烦,效率低,于...

it1000001001
2017/06/28
109
1

没有更多内容

加载失败,请刷新页面

加载更多

Protocol Buffers 简介

文档编辑和持续集成状态: 本文档的 Protocol Buffer 的中文文档使用的是 Asciidoctor 进行编排的 http://docs.ossez.com/protocol-buffers-docs/index.html(本 WIKI 中的内容将会与在线发布...

honeymoose
今天
4
0
uniapp + bootstrapvue 移动/PC 一套搞定 (一)配置bootstrapvue

1.准备文件 自己到DCloud官网: http://dcloud.io/ 去下载官方的IDE Hbuilder,新建一个空的uniapp项目即可。 uniapp框架自带优化的vue,我们仅仅需要准备以下三个文件: bootstrap.min.css ...

panyunxing
今天
12
0
Android Camera原理之camera service类与接口关系

camera service主要是指 frameworks/av/services/camera/下面的代码,最近在看这一块的代码,为了更好地理清这一块的代码,也为了后续学习camera方便一些,我觉得很有必要理一下这一块的整体...

天王盖地虎626
今天
6
0
Golang学习笔记

[TOC] Golang学习笔记 这个学习笔记是最早在1.初,版本左右的时候写的,和当前最新的版本可能会有较大的差异. 因为成文比较早,文章里面又有很多自己的见解,有些东西当时理解的不太透彻可能写错...

我爱吃炒鸡
今天
21
0
科技赋能成效显著!金融壹账通两大赋能项目荣获IDC大奖

7月19日,2019IDC中国未来金融论坛曁颁奖典礼于北京举办。由金融壹账通赋能的长春农商银行多人视频面审智能风控系统、包头农商银行互联网银行SaaS服务两大项目因在项目的创新性、技术领先性、...

IFTNews
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部