腾讯微视 爬虫

关于腾讯微视频采集解决方案

Github 地址 点这里

前段时间看到一个关于微信数据采集的小项目,我感觉非常不错, 修改它做一些好玩的事,用来获取短视频平台的一些数据,

它很容易理解,也很容易进行修改,可以为以后其他爬虫提供思路。

首先确保你有一台或多台安卓 手机,使用adb 对手机进行模拟操作,我们可以使用代理拦截的方式进行获取数据 当然我们也可以使用其他的方式,多种多样的玩法或许很有成就感

关于adb 使用 可以  点这里

控制手机

from os import system
import random
import time
from threading import Thread


def connect_phone(func):
    """
    装饰器负责每次命令前连接手机
    :param func:
    :return:
    """

    def wrapper(*args, **kwargs):
        system('adb connect ' + args[0].phone)
        return func(*args, **kwargs)

    return wrapper


class PhoneControl():
    def __init__(self, phone):
        """
        :param phone:adb 操作手机所需要的端口信息
        """
        self.phone = phone

    def get_phone(self):
        """
        获取实例手机端口信息
        """
        return self.phone

    @connect_phone
    def get_screen_cap(self, file_name='screen_cap'):
        """
        获取截图
        """
        system('adb -s ' + str(self.phone) + ' shell screencap -p /sdcard/' + file_name + '.png')
        system('adb -s ' + str(self.phone) + ' pull /sdcard/' + file_name + '.png' + ' ./' + file_name + '.png')
        return file_name + '.png'

    @connect_phone
    def input_tap(self, pos):
        """
        点击屏幕
        pos为一个区域的左上与右下坐标
        如果事先已经随机化了pos可以只是一个点 随机点击一个位置是为防止被被认为是机器人
        返回实际点击位置
        """
        if len(pos) == 2:
            _pos = pos
        else:
            _pos = (random.randint(pos[0], pos[2]), random.randint(pos[1], pos[3]))
        command = r'adb -s ' + str(self.phone) + ' shell input tap {} {}'.format(_pos[0], _pos[1])
        system(command)
        return _pos

    @connect_phone
    def input_swipe(self, x1, x2):
        """
        从一个位置滑动到另一位置
        :param x1:起始坐标,屏幕左上角为原点
        :param x2:终点坐标,屏幕左上角为原点
        :return:[x1,x2]
        """
        command = r'adb -s ' + str(self.phone) + ' shell input swipe {} {} {} {}'.format(x1[0], x1[1], x2[0], x2[1])
        system(command)
        return [x1, x2]

    @connect_phone
    def input_roll(self, dx=500, dy=0):
        """
        拉动屏幕 向上拉动屏幕
        :param dx:x方向速度
        :param dy:y方向速度
        :return:[dx, dy]
        """
        command = r'adb -s ' + str(self.phone) + ' shell input roll {} {}'.format(dx, dy)
        system(command)
        return [dx, dy]

    @connect_phone
    def input_key_event(self, event_cmd):
        """
        按键事件 比如home menue back volum_up volum_down等等 具体定义在配置文件中
        :param event_cmd:事件ID
        :return:event_cmd
        """
        command = r'adb -s ' + str(self.phone) + ' shell input keyevent ' + event_cmd
        system(command)
        return event_cmd

    @connect_phone
    def input_text(self, text):
        """
        输入文本信息 可能不支持中文输入
        :param text:待输入的文本信息
        :return:文本信息
        """
        command = r'adb -s ' + str(self.phone) + ' shell input text {}'.format(text)
        system(command)
        return text

    @connect_phone
    def input_chn(self, text):
        """
        支持中文 需要事先将ADB键盘设置为默认输入法而且打开软键盘
        :param text:待输入的文本信息
        :return:文本信息
        """
        # command = r'adb -s '+str(self.phone)+' shell am broadcast -a ADB_INPUT_TEXT --es msg {}'.format(text)
        command = r'adb -s ' + str(self.phone) + ' shell am broadcast -a ADB_INPUT_TEXT --es msg {}'.format(text)
        system(command)
        return text


class OperateAllPhone():
    """
    同时控制给定abd端口的所有手机 请确保手机初始界面一致
    """

    def __init__(self, phone_list):
        """
        :param phone_list:
        """
        self.phone_list = phone_list
        self.pcs = []
        for ap in self.phone_list:
            self.pcs.append(PhoneControl(ap))

    def key(self, event):
        self.operate_all("input_key_event", (event,))

    def text(self, str_data):
        self.operate_all("input_chn", (str_data,))

    def swap(self, x1, x2):
        self.operate_all("input_swipe", (x1, x2))

    def roll(self, dx, dy):
        self.operate_all("input_roll", (dx, dy))

    def tap(self, pos):
        self.operate_all("input_tap", (pos,))


    def operate_all(self, operation, args):
        """
        :param operation: PhoneControl实例方法字符串名称
        :param args:tuple格式参数
        :return:
        """
        _tasks = []
        for pc in self.pcs:
            _tasks.append(Thread(target=pc.__getattribute__(operation), args=args))
        for t in _tasks:
            t.start()
        for t in _tasks:
            t.join()
        return operation


if __name__ == '__main__':
    p = PhoneControl('xxx')
    for i in range(20):
        p.input_swipe([761, 1390], [806, 999])
        time.sleep(0.8)

2 进行某些必须操作, 比如模拟点击加载, 下拉刷新,左右滑动 等

3 如果使用代理拦截 我们这里使用mitmproxy, 可以将拦截到的代理发送到redis或者其地方,也可以使用粘贴剪切板方式,明显代理拦截要更为快捷。

import mitmproxy.http
from mitmproxy import ctx


class Counter(object):
    def __init__(self):
        self.num = 0
        self.url_list = list()

    def request(self, flow: mitmproxy.http.HTTPFlow):
        if 'http://v.weishi.qq.com/shg' in flow.request.pretty_url:
            print('+'*20)
            u = flow.request.pretty_url
            print('+'*20)
            with open('u_list.txt', 'a') as f:
                f.write(str(u) + '\n')


addons = [
    Counter()
]

4 这样就可以拦截到需要的请求,保存到了本地文件

5 另外 还有一种方式可以使用 因为代理拦截方式有时候并不那么完美,可以使用复制剪切板的方式

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值