微信公众号刷票思路 Python

记一次微信公众号批量投票,主要记录思路,具体的公众号已打码。

主线思路:

1.分析投票所需数据(判断  是通过ip  还是 需要注册账号后才可以进行投票)

2.批量注册第三方平台的账号(若拥有大量可用微信号,则可用微信号直接替代此步)

3.利用已注册的账号进行遍历,随机投票,每日循环。

 

实施步骤:

1.使用  mitmproxy 监测 投票过程(亦可用fiddler进行抓包),分析并记录 必要请求及所需数据。

微信公众号刷票思路 Python_第1张图片

上图中  红色字体所标记数据为 用户数据,

Referer 中涉及到  被投票用户的 work_id 和 library_id  ,可以通过分享页面的url获取

data 中涉及到 被投票用户的work_id 和 投票者的token ,投票者的token 是每个用户特有的识别码,故需要进行注册账号

  注:请求所需的 代理ip 下方有介绍,主要是通过实时爬取 站大爷的可用ip 来实现。

 

2. 注册该公众号平台的账号,并使用 selenium 模拟chrome访问,获取控件并填写信息。

微信公众号刷票思路 Python_第2张图片

图中信息均为必填信息,

昵称, 现在各种平台比较多,可以比较快捷的获取大量用户名,或者自己编辑

密码、确认密码  更不用说,是比较容易填写的,初看比较困难的是如何获取到大量的手机号,以及能得到其验证码

因为国家针对sim卡实行实名制,所以正规渠道比较少。在网上搜索后发现,

①. 有很多的接码平台可以实现此类功能,但是大多要付费、还有很多api要了解,乍一看比较麻烦,就没有使用这种办法。

②.  还发现有一些机构个人会在网上免费公开少量的手机号,可以在线接收短信注册码验证码(例 点击查看),类似的网站如果需要可以自行在网上搜索。此方法的确可以使用,但是实操时发现很多手机号发送验证码后不能及时接收到,即同一时间有很多用户使用,导致运营商延迟较大。所以也没使用这种办法。

③. 最后因为找不到手机号,就 按了F12 ,这下才发现,原来每次点击 验证码后,都会响应到一个json串,即验证码,于是得来全不费工夫。最后自己随机生成手机号,并获取响应到的json串,以此达到 获取验证码的效果。至此,批量注册账号的问题得以解决了。

注册完账号后,发现 用户的token值 并不会显示出来,

于是在网页的js中开始检索, 发现 通过  get_user_token()  方法可以直接获取当前用户的token,在F12 的 console 中调试后发现可行。就通过此方法获取的 token 值。

 

3. 获取大量 实时免费的高匿代理ip。

通过前两步,已经可以实现注册账号、进行投票了,但没有高匿代理ip,极易被人察觉,所以这一步就是想办法获取代理ip了。

初步调研了目前主流的免费的代理ip网站,最终选择了站大爷,因为每个小时都更新,而且使用公众号的主站测试了一下,发现大部分是可以成功访问的。

 

项目中使用的:

数据库:SSDB,详细信息可参见git

代理ip池:  proxy_pool,详细信息可参见git

为了尽量少的影响他人服务器,我的请求速度写的极慢,按需修改。

 

代码部分:

1,​投票

import json
import random
import time
import pyssdb
import requests
from selenium import webdriver

class vote_wechat(object):
    """
    投票部分

            先 请求 upload_visit 上传服务器数据,返回值为result: 1 说明被服务器认可
            然后 请求add_praise 上传token ,服务器返回成功

    requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')
        此行的意思是  请求局域网内的代理ip库,从中随机取一个可用ip
        可以根据自己的配置情况自行修改

    """

    def __init__(self,
                 token="******",
                 proxy={'http': requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')}):

        # 默认微信用户 - 小号
        self.token = token
        # 默认代理ip - 随机选取
        self.proxy = proxy

        # 被投票人信息
        work_id = "******"
        library_id = "******"


        self.url = 'http://www.y***k.net/wh/api/activity/fruit/add_praise'
        Agent = [
            'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 MicroMessenger/6.7.3(0x16070321) NetType/WIFI Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 7.0; Redmi Note 4X Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044304 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/WIFI Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 7.1.1; vivo X20A Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044304 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/4G Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 7.1.1; OD105 Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044208 Mobile Safari/537.36 wxwork/2.4.9 MicroMessenger/6.3.22 NetType/4G Language/zh',
            'Mozilla/5.0 (Linux; Android 7.1.1; OPPO R11st Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044304 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/WIFI Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 8.0; SM-G9500 Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044208 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/WIFI Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 8.0; DUK-AL20 Build/HUAWEIDUK-AL20; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044353 Mobile Safari/537.36 MicroMessenger/6.7.3.1360(0x26070333) NetType/WIFI Language/zh_CN Process/tools',
            'Mozilla/5.0 (Linux; Android 8.0; MHA-AL00 Build/HUAWEIMHA-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044304 Mobile Safari/537.36 MicroMessenger/6.7.3.1360(0x26070333) NetType/NON_NETWORK Language/zh_CN Process/tools',
            'Mozilla/5.0 (Linux; Android 8.1; EML-AL00 Build/HUAWEIEML-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.143 Crosswalk/24.53.595.0 XWEB/358 MMWEBSDK/23 Mobile Safari/537.36 MicroMessenger/6.7.2.1340(0x2607023A) NetType/4G Language/zh_CN',
            'Mozilla/5.0 (Linux; Android 8.1; PAR-AL00 Build/HUAWEIPAR-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/044304 Mobile Safari/537.36 MicroMessenger/6.7.3.1360(0x26070333) NetType/WIFI Language/zh_CN Process/tools',
        ]
        self.Agent = Agent[random.randint(0, len(Agent) - 1)]
        self.headers = {
            "Host": "www.y***k.net",
            "Proxy-Connection": "keep-alive",
            "Content-Length": "101",
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Origin": "http://www.y***k.net",
            "X-Requested-With": "XMLHttpRequest",
            'User-Agent': self.Agent,
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Referer": "http://www.y***k.net/wh/web/picture.html?page=picture&work_id={work_id}&from=singlemessage&library_id={library_id}&is_weixin=1&login_version=1&is_login=1".
                format(work_id=work_id, library_id=library_id),
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,en-US;q=0.9"}
        self.data = {
            "issign": "1",
            "mac": "",
            "work_id": work_id,
            "token": token}

    def get_proxy(self):
        return requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')

    def run(self):
        i = 0
        while i < 3:
            try:
                # 投票前先请求分享页面,增加浏览数
                url_read = 'http://www.y***k.net/wh/api/asset/info/?workID=******&mac=&token='
                hreader_read = {
                    "Host": "www.y***k.net",
                    "Proxy-Connection": "keep-alive",
                    "Accept": "application/json, text/javascript, */*; q=0.01",
                    "Origin": "http://www.y***k.net",
                    "X-Requested-With": "XMLHttpRequest",
                    'User-Agent': self.Agent,
                    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                    "Accept-Encoding": "gzip, deflate",
                    "Accept-Language": "zh-CN,en-US;q=0.9"}

                for j in range(random.randint(2, 5)):
                    # 请求分享页,增加浏览量
                    req_read = requests.get(url_read, headers=hreader_read, proxies=self.proxy)
                    time.sleep(random.random() * 10)

                req = requests.post(self.url, data=self.data, headers=self.headers, proxies=self.proxy)
                req_json = json.loads(req.content)
                if req.status_code == 200 and 'praise_times' in req_json:
                    print('\r累计{}票,本账号今日已投{}票'.format(req_json['praise_times'], req_json['has_vote']))
                    i += 1
                    time.sleep(random.randint(2, 5))
                else:
                    print(req_json['err_msg'])

            except Exception as e:
                # self.proxy = {'http': self.get_proxy()}
                print('遇到问题{},跳过1次'.format(e))
                i += 1
                time.sleep(1)

2,​注册账号

class register_user(object):
    """
    自动注册一个账号(用手机号注册账号,获取每个账号的token,一个账号需要1分钟左右时间创建)

     格式:
	    ip                      账号           token
                                    小号           ******
                                    大号           ******
    :return:账号所用ip/手机号/token

    """

    def __init__(self, proxy=requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')):
        self.info_list = []
        self.token_ = 'null'
        self.proxy = proxy
        self.agent = vote_wechat().Agent
        self.nickname = self.nickname()[random.randint(0, 500)]
        self.tele_num = self.random_(17)

        self.regest_url = 'http://www.y***k.net/wh/web/mreg.html'
        options = webdriver.ChromeOptions()
        options.add_argument('--headless')
        options.add_argument("disable-infobars")
        options.add_argument('User-Agent={}'.format(self.agent))
        options.add_argument('--proxy-server={0}'.format(self.proxy))
        self.chrome = webdriver.Chrome(chrome_options=options)
        self.chrome.set_page_load_timeout(20)
        self.chrome.get(self.regest_url)

    def nickname(self):
        # 从SSDB数据库取昵称(根据自身数据情况进行替换)
        c = pyssdb.Client('192.168.1.7')
        nick = []
        user_list = c.hkeys('User_name_icon', '', '', 500)
        for i in user_list:
            rc = i.decode('utf-8').split('|,|')[1]
            nick.append(rc)
        c.disconnect()
        return nick

    def random_(self, up, num=9):
        """
        随机生成手机号码
        :param up: 手机号前缀,默认2位
        :param num:默认9位数
        :return:默认11位随机数字
        """
        nex = []
        for i in range(num):
            the_o = random.randint(0, 9)
            nex.append(str(the_o))
        return str(up) + ''.join(nex)

    def send_sms(self):
        # 发送验证码请求
        send_sms_url = 'http://www.y***k.net/wh/api/common/send_validate_sms/'
        header_send_sms = {
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Content-Length": "32",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Host": "www.y***k.net",
            "Origin": "http://www.y***k.net",
            "Proxy-Connection": "keep-alive",
            "Referer": "http://www.y***k.net/wh/web/mreg.html",
            "User-Agent": self.agent,
            "X-Requested-With": "XMLHttpRequest",
        }
        data_send_sms = {
            'phone': self.tele_num,
            'name': self.nickname,
        }
        proxy_send_sms = {
            'http': self.proxy
        }
        send_sms_req = requests.post(send_sms_url, headers=header_send_sms, data=data_send_sms, proxies=proxy_send_sms)
        v_code = json.loads(send_sms_req.content)['v_code']
        return v_code

    def get_proxy(self):
        return requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')

    def edit_info(self):
        print('\r正在浏览器编辑中......', end='')
        # 输入昵称、手机号、密码、确认密码,等待10秒后,输入验证码
        nickname_input = self.chrome.find_element_by_id("doc-ipt-1")
        nickname_input.send_keys(self.nickname)
        phone_input = self.chrome.find_element_by_id("doc-ipt-2")
        phone_input.send_keys(self.tele_num)
        psd_input = self.chrome.find_element_by_id("doc-ipt-3")
        psd_input.send_keys(self.tele_num)
        psd_again_input = self.chrome.find_element_by_id("doc-ipt-4")
        psd_again_input.send_keys(self.tele_num)
        time.sleep(10)
        # 输入验证码
        print('\r发送验证码中......', end='')
        verification_input = self.chrome.find_element_by_id("doc-ipt-5")
        verification_input.send_keys(self.send_sms())

    def run(self):
        self.edit_info()

        # 随机等待15-50秒后,提交信息
        time.sleep(random.randint(15, 50))
        btn = self.chrome.find_element_by_id('confirm_btn')
        btn.click()

        # 执行js,获取token值
        js = 'document.getElementById("doc-ipt-1").className = get_user_token()'
        count = 0
        while self.token_ == 'null' or count > 10:
            count += 1
            print('\r“token_” key is :', self.token_, end='')
            time.sleep(1)
            self.chrome.execute_script(js)
            self.token_ = self.chrome.find_element_by_id("doc-ipt-1").get_attribute('class')
        print('\r{}   {}    {}'.format(self.proxy, self.tele_num, self.token_))
        self.info_list.extend([self.proxy, self.tele_num, self.token_])
        return self.info_list

3,​代理ip写入,检查是否为高匿、是否可访问

# 检查url是否可以通过代理ip访问
class check_url(object):
    """
        检查url是否可以通过代理ip访问
            case:
                check = check_url('http://httpbin.org/ip')
                while not check.check_ip():
                    http_str = check.refresh()
                    if check.proxies['http'] == http_str:
                        break
                    check.proxies['http'] = http_str
    """

    def __init__(self, url, ip_proxy=None):
        self.url = url
        if ip_proxy:
            self.proxies = {
                'http': ip_proxy}
        else:
            self.proxies = {
                'http':  requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')}

    def check_ip(self):
        # 能访问返回True
        try:
            # 超过20秒的代理就不要了
            r = requests.get(self.url, proxies=self.proxies, timeout=10, verify=False)
            if r.status_code == 200:
                # print(r.content)
                print('{}可以正常访问'.format(self.proxies['http']))
                return True
        except Exception as e:
            print('\r{}---->{}---更换ip中'.format(self.proxies['http'], e), end='')
            time.sleep(0.1)

    def refresh(self):
        return requests.get("http://192.168.1.7:5010/get/").content.decode('utf-8')



# 从站大爷ip网站中取最新ip,写入文件
def write_zdy_ip():
    # 写入文件位置为:E:\ip3.txt
    def now_time(time_str="%Y-%m-%d-%H-", replace=['年', '月', '日', '时'], replace_str='-'):
        time_stamp = time.localtime(time.time())
        str_now_time = str(time_stamp.tm_year) + replace_str + str(time_stamp.tm_mon) + replace_str + \
                       str(time_stamp.tm_mday) + replace_str + str(time_stamp.tm_hour) + replace_str
        # str_now_time = time.strftime(time_str, time_stamp)  # 含0
        show_now_time = str_now_time
        for item in replace:
            # 将 中文 转化成 unicode
            show_now_time = show_now_time.replace(replace_str, item, 1)
            item = item.encode('unicode_escape').decode()
            str_now_time = str_now_time.replace(replace_str, item, 1)
        print('当前时间:', show_now_time)
        return str_now_time
    zdy_url = 'http://ip.zdaye.com/dayProxy.html'
    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Cookie": "acw_tc=781bad0815554276156886732e5dc4c8fa7bc5f5f7d49920ab817374586a8b; ASPSESSIONIDQSCADTTD=CPLINKOCBKENHNPBEHDCMAKJ; __51cke__=; Hm_lvt_8fd158bb3e69c43ab5dd05882cf0b234=1555427618; ASPSESSIONIDACRDDQQA=GMPHOIPCLFKBFGCPFMBDFAPM; __tins__16949115=%7B%22sid%22%3A%201555427617018%2C%20%22vd%22%3A%204%2C%20%22expires%22%3A%201555429600579%7D; __51laig__=4; Hm_lpvt_8fd158bb3e69c43ab5dd05882cf0b234=1555427801",
        "Host": "ip.zdaye.com",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
    }
    referer = {'Referer': 'http://ip.zdaye.com/dayProxy.html'}
    res = requests.get(zdy_url, headers=headers)
    if res.status_code == 200:
        soup = BeautifulSoup(res.content, "html.parser")
        panel = soup.find('div', class_='panel-body')
        panel = str(panel)
        time_str = now_time()
        pattern = r'.+href="(.+)">{}.+'.format(time_str)
        pattern_ = r'.+href="(.+)">{}.+'.format('2019\u5e74')
        if len(re.findall(pattern, panel)) < 1:
            href_day = re.findall(pattern_, panel)[0]
            url_day = 'http://ip.zdaye.com' + re.findall(pattern_, panel)[0]
        else:
            href_day = re.findall(pattern, panel)[0]
            url_day = 'http://ip.zdaye.com' + re.findall(pattern, panel)[0]

    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument("disable-infobars")
    chrome_day = webdriver.Chrome(chrome_options=options)
    chrome_day.get(zdy_url)
    hre = chrome_day.find_elements_by_css_selector('a[href="{}"]'.format(href_day))[0]
    hre.click()
    chrome_day.refresh()
    text = chrome_day.find_elements_by_css_selector('.cont')[0].text
    with open('E:\ip3.txt', 'w', encoding='utf-8') as f:
        f.write(text)
    print('ip已写入...', end='')

    # 从站大爷将ip放置txt文件(E:\ip3.txt)中,开始执行
    ip_proxy = []
    userful_ip = []
    with open('E:\ip3.txt', 'r', encoding='utf-8') as f:
        for item in f:
            ip = item.split('@')[0]
            type = re.findall(r'.+\[(.+)\].+', item)[0]
            if type == '高匿':
                ip_proxy.append(ip)
    print('共{}个高匿ip,现在开始检查可用性...'.format(len(ip_proxy)))
    # 检查高匿ip是否可以访问目标网站
    for i in range(len(ip_proxy)):
        check = check_url('http://www.y***k.net', ip_proxy[i])
        if not check.check_ip():
            print('{}不可用'.format(ip_proxy[i]))
        else:
            userful_ip.append(ip_proxy[i])
    print('共{}个可用ip,可用ip集合:'.format(len(userful_ip)), userful_ip)
    return userful_ip

4,​主函数

# 批量 新建账号
def new_start(userful_ip):
        for i in range(len(userful_ip)):
            try:
                print('第{}次开始运行...'.format(i + 1))
                info_list = register_user(proxy=userful_ip[i]).run()
                info_str = info_list[0] + '|' + info_list[1] + '|' + info_list[2] + '\n'
                with open(r"E:\users.txt", 'a') as f:
                    f.write(info_str)
                print('已成功写入第{}个用户,响应等待中...'.format(i + 1))
                time.sleep(random.randint(30, 600))
            except Exception as e:
                print('Error:', e)


# 批量  投票
def wechat_start():
    info_ip, token, ip_token = [], [], []
    # with open(r'E:\users.txt', 'r') as f:
    with open(r'E:\users_repeat2.txt', 'r') as f:
        for item in f:
            item_list = item.split('|')
            info_ip.append(item_list)

    for info in info_ip:
        if info[0] not in ip_token:
            ip_token.append(info[0])
            token.append(info[2].strip())
        # else:
        #     info__str = info[0] + '|' + info[1] + '|' + info[2]
        #     with open(r"E:\users_repeat2.txt", 'a') as f:
        #         f.write(info__str)
    print('可用用户:', len(ip_token))
    # time.sleep(100)
    # 10个用户一组进行投票,每个人间隔3~6分钟,每组间隔15~30分钟
    # 创建一个10的列表
    down = [i * 10 for i in range(1, 20)]
    # 将所有用户投票
    for i in range(len(token)):
        if i+1 < 1:
            continue

        for itemm in down:
            if i == itemm:
                time.sleep(random.randint(60 * 15, 60 * 30))

        print('正在使用第%s个用户投票' % str(i+1))
        wechat_yhl = vote_wechat(token=token[i], proxy={'http': ip_token[i]})
        wechat_yhl.run()
        time.sleep(random.randint(60 * 3, 60 * 6))


    # 0.获得最新ip
    userful_ip = write_zdy_ip()

    # 1. 注册
    new_start(userful_ip)

    # 2. 遍历 账号文件夹去投票
    wechat_start()

    while True:
        # 无限注册账号
        try:
            new_start(write_zdy_ip())
            time.sleep(60 * 90)
        except Exception:
            print('遇到问题,重试中...')
            time.sleep(10)

 

你可能感兴趣的:(Python)