zoukankan      html  css  js  c++  java
  • 爬取ofo共享单车信息

      前段时间看到很多微信公众号在转发一篇爬取mobike单车的信息,也不知道什么原因,在网上搜索了下很少有人在爬取ofo共享单车的数据,所以决定看看可以爬取ofo共享单车的那些数据。

      抓取数据开始的时候,分析了下可以通过几个渠道看到ofo共享单车的数据,主要是通过ofo公众号,ofo APP、ofo微信小程序 三个渠道可以获取数据,一般情况下手机配置代理以后,APP会出现无法联网的情况,导致无法获取数据;由于之前微信公众号可以在浏览器打开,抓取过程比较的容易,所以我比较倾向通过微信公众号进入获取共享单车数据;

     在整个爬取的过程中使用到比较关键的工具fiddler,辅助我们来抓取一些接口地址,这里我共享下ofo网页登陆的入口地址,大家可以通过这个地址登陆ofo来抓取附近单车信息,登陆地址:https://common.ofo.so/newdist/?Login&~next=%22%22。从登陆到开始到获取附近的单车,分析了一下对我们比较有用的几个接口:

      1.登陆接口,获取token信息

        https://san.ofo.so/ofo/Api/login

      2.获取图片验证码接口

        https://base.api.ofo.com/ofo/Api/v4/getCaptchaCode

      3.获取短信验证码接口

        https://base.api.ofo.com/ofo/Api/v4/getVerifyCode

      4.获取附近单车的接口

        https://san.ofo.so/ofo/Api/nearbyofoCar

    一、探索单车接口,获取单车数据

      1.首先我们来模拟下实际的操作过程,主要三大步:获取图片验证码,获取短信验证码,获取附近单车。

      

      2.根据上诉步骤我们逆向的来看下获取附近单车数据需要那些那些请求数据,主要的请求参数主要需要token、经度、纬度

      3.经度和纬度属于位子信息,token 属于认证信息,所以我们需要看看如何获取token;

      4.登录成功以后需要返回token,但是登录需要手机号、图片验证码、手机短信验证码来登录获取token,整个过程分析清楚,分析的时候我们是逆向分析,但是我们实现的时候需要正向一步一步,我们下面来写一下代码实现整个过程。

      

    # -*- coding: utf-8 -*-
    # @Time    : 2017/10/20 16:33
    # @Author  : Hunk
    # @Email   : qiang.liu@ikooo.cn
    # @File    : getToken.py.py
    # @Software:
    import json
    import requests
    
    
    def get_captcha_code():
        """
        获取图片验证码base64位加密数据
        :return : captcha,verifyId
        """
        url = 'http://base.api.ofo.com/ofo/Api/v4/getCaptchaCode'  # 图片验证码获取地址
        headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, '
                                 'like Gecko) Mobile/14E304 MicroMessenger/6.5.7 NetType/WIFI Language/zh_CN'}
        CaptchaCode = requests.post(url, headers=headers, verify=False).text
        return json.loads(CaptchaCode)['values']
    
    
    def code_picture_convert_string(appCode, query, base64Picture):  # appCode 接口的认证key,query 验证码类型
        """通过第三方结果获取验证码
        :param appCode: 认证ID
        :param query: 验证码类型
        :param base64Picture: base64 加密的地址
        """
        header = {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',   # 根据API的要求,定义相对应的Content-Type
            "Authorization": "APPCODE " + appCode
        }
        url = 'http://jisuyzmsb.market.alicloudapi.com/captcha/recognize'  # 调用地址
        bodys = {'type': query, 'pic': base64Picture}   # 请求参数
        resultCode = json.loads(requests.post(url, headers=header, data=bodys).text)
        return resultCode['result']['code']
    
    
    def get_verify_code(tel, captcha, verifyId):
        """
        获取短信验证码
        :param tel: 手机号
        :param captcha 图片验证码
        :param verifyId: 校验ID
        :return: 返回短信验证码
        """
    
        url = 'http://base.api.ofo.com/ofo/Api/v4/getVerifyCode'  # 获取短信验证码获取地址
        headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, '
                                 'like Gecko) Mobile/14E304 MicroMessenger/6.5.7 NetType/WIFI Language/zh_CN'}
        parameter = {
            "tel": tel,
            "captcha": captcha,
            "verifyId": verifyId
    
        }
        VerifyCode = requests.post(url, headers=headers, data=parameter, verify=False).text
        return json.loads(VerifyCode)['msg']
    
    
    def get_token(tel, code):
        """
        获取登录时返回的token
        :param tel: 手机号
        :param code: 短信验证码
        :return: token
        """
        url = 'http://san.ofo.so/ofo/Api/login'  # 获取token地址
        headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, '
                                 'like Gecko) Mobile/14E304 MicroMessenger/6.5.7 NetType/WIFI Language/zh_CN'}
        parameter = {"tel": tel, "code": code}
        token = requests.post(url, headers=headers, data=parameter, verify=False).text
        return json.loads(token)["values"]["token"]

    根据上述的代码获取到了token(da37bc80-02ed-11e7-a5c5-d3660a2fde97),这里获取验证码的时候需要通过手动的读取验证码,下面我们来获取下附近单车

    # -*- coding: utf-8 -*-
    # @Time    : 2017/10/19 16:09
    # @Author  : Hunk
    # @Email   : qiang.liu@ikooo.cn
    # @File    : ofoCrawler.py
    # @Software: PyCharm
    
    import json
    import requests
    
    
    def get_ofo_info(longitude, latitude):
        url = 'https://san.ofo.so/ofo/Api/nearbyofoCar'
        headers = {
            'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, '
                          'like Gecko) Mobile/14E304 MicroMessenger/6.5.7 NetType/WIFI Language/zh_CN'
        }
        data = {
            'token': 'DA37BC80-02ED-11E7-A5C5-D3660A2FDE97',
            'lng': str(longitude),  # 经度
            'lat': str(latitude)  # 纬度
        }
        result = requests.post(url, data=data, headers=headers, verify=False).text
        return json.loads(result)['values']['info']['cars']
    
    
    if __name__ == '__main__':
        data = get_ofo_info(116.4360666275, 39.9310311788)
        print(data)

    看看我们获取到的数据,拿到的数据我们可以看到每辆单车的编号,目前的位子。

     拿到这么多的数据,我们更希望利用数据做一些事情,所以下节介绍下对数据的思考,利用数据我们来分析下单车的运行轨迹。

    本教程只提供学习

  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/mengyu/p/7700980.html
Copyright © 2011-2022 走看看