爬虫分享

爬虫相关笔记

爬虫核心

爬虫本质是获取外部数据的行为,只能获取暴露出来的数据。
暴露出来的数据可以是c端消费者肉眼能够看到的数据,这种数据比较可信。
也可以是接口返回的或者是html隐藏在页面下的一些数据,这些数据的可信度没有保障,还得去理解数据的含义。

主要有以下两种方式:

  1. 接口方式爬虫
    1. 抓包
    2. 分析接口
    3. 调用接口
    4. 数据处理
  2. 模拟人的行为
    1. web端
      • 可以通过自动化框架(如selenium,pyppteer等)操作浏览器内核模拟人的点击行为。
        但这种方式效率很低,如果接口的反爬实在很严重,可以尝试这种方法。
        但是还是会有很多方法来检测是否是无头爬虫,某宝在这方面做得非常好。
      • 也可以使用一些js渲染框架,如splash等。
        有些框架比较小众,没人维护,会有很多坑需要自己解决。而且部署难度也比较大。
        如非必要,还是不用的好。
        费时费力。
    2. 移动端
      • 本地可以使用网易的airtest测试框架来模拟,但是这种方法获取到的数据极为有限。

抓包

主要工具

  • PC端主要有fiddlercharles
  • 安卓端可使用packet capture,也可通过设置代理,使用PC端的软件来抓包。

抓包作为爬虫第一步,至关重要。

  • web端
    网页抓包可以直接通过f12使用浏览器来获取一个网页请求接口。
  • h5
    同web端
  • 移动端
    大部分的移动端应用会通过各种手段来阻碍你抓包。
  1. 应用会检测你是否挂了代理,会阻止你访问某些接口。返回网络错误的信息。
  2. 再有就是你抓不到这个接口的请求,只会有心跳和图片的请求信息。
    这种一般是应用不信任抓包软件的证书导致。
    因为在安卓7.0.0版本以前应用是信任所有证书的,这跟应用版本没有关系。
    所以抓包的最好是拥有一台安卓版本在7.0.0以前的或者ios系统的手机。
    ios系统没有这种版本限制。
    如果没有手机也没有关系,可以使用雷电模拟器来模拟手机环境来抓包。

分析接口与爬虫对抗

1. 主要有两种请求方式GETPOST

  • GET请求的参数是直接拼接在path后面的。
  • POST请求的参数是放在Body里,json格式或者是 k e y = v a l u e key=value key=value形式以&符号连接。
    这取决于request header里的content-type字段
    POST请求相比于GET,它的header里还多了content-length字段。
    一个http请求需要知道它的Body参数的长度,读取到哪里为止才算当前请求的数据。
    从经验上来看,content-length并不是强校验的,虽然理论上post请求是必需带上这个字段的。

这里我遇见过一个case。
爬过一个小程序,它的post请求的content-length并不是它的body的长度。而是以接口纬度在body的长度上固定加一个值,相加后的值才是应该传的content-length。这里坑了我一段时间,这是让人疑惑的地方。
怀疑是故意为之或是一个bug。

2. 接口来源分为四种apph5web端小程序

  • 一般的web接口是没有任何加签参数,是裸的,是可以直接重放的。
    现在是移动端的时代,web端的流量与移动端相比会小很多,如果有异常,大多数都是爬虫导致。
    正因为如此某些网站会加强web端的风控,使得爬虫很难获取到什么信息。
    最常见的反爬手段就是直接强制登录
    一旦登录,就能通过分析用户行为和限频限次等多种手段去风控。
    一般的网站是没有这种风控的。
    当然有的网站还是会存在加签校验的。

  • h5接口一般都会有加签函数。h5的加签都会在js里,虽然加了混淆,但是可以先搜索关键词再通过打断点的方式,一步一步跟到对应的加签函数上。
    大多数的加签函数都是根据参数的key值先排好序根据k=v的形式用&拼接,然后再在最后加上盐值,最后再算md5值
    例如
    假设有一个post请求
    它的body参数为

    {
        "goodsId":1567,
        "shopId":56897,
        "timestamp":1234567891
    }
    

    假设salt = afddsaffdaf
    那么sign = md5(goodsId=1567&shopId=56897×tamp=1234567891afddsaffdaf)

    一般的网站加签函数可能就是这样了,但是某宝比较特殊,它的请求参数里有与服务器交互得到的值,是类似于session的值。
    对于使用代理的爬虫,需要去维护这个session值会严重加大难度。

    因为h5和web端一样,流量都比较少,所以有异常大部分情况下都可以判断为爬虫。
    因此大网站的反爬都会比较严。

  • app接口
    app的接口一定是有签的,难度也是最大的。
    而且apk的都是加壳并且代码也都是混淆过的,核心的加签函数也都是在so层里,是需要反编译apk,打断点跟踪汇编代码,一步一步调试出来的。

    如果爬虫规模较小,不需要很高的效率,可以先通过Xposed框架hook相应的加签函数。把手机当成一个微型服务器,不需要关心加签函数的实现,只需要输入对应的参数就能得到加签值。

    除了签之外,还会有设备信息,很多app的接口请求里都会有设备id,这也是用来做反爬手段的一种参数。

    特别是某手和某音,对设备id的风控非常严。而且这两个App的签也非常多,迭代非常快,某些接口在账号和设备纬度被限频限次,能获取到数据的微乎其微。

    某宝在201911的版本更新了新签,并增加了x-mini-wua的header。这个参数也是设备相关,而且是x-sign参数生成的必传参数。当时因为某宝加了这个参数导致爬虫全跪,后来才发现的这个参数。

    x-mini-wua: HHnB_7EyCHC1hWtpmmlOKbg06JPWj2Xv3bNsFAf23la5PYPmLXlEGOv%2BXClxFQJmCR63NYye8nDVEgs4k2efWqtvtYzl2NGIP6rrD905ibmdTrAG1Vte6NDDTcQjHHaXUQeWr
    

    202008底开始对x-mini-wua加强了风控。

    • 之前是会返回419的httpStatusCode,会要求登录。过一段时间,又可以使用。这是可以通过更换x-mini-wua解决,我们只需要一个可供更换的池子。
      419返回的json,大概是被检测到挂了代理。
    {
           
    	"ret": ["FAIL_SYS_USER_VALIDATE::亲,访问被拒绝了哦!请检查是否使用了代理软件或VPN哦~"],
    	"data": {
           }
    }
    
    • 202009变成了code是200,但是返回的json数据变成了这样。
    todo 具体的现在找不到,之后补充
    ret : SESSION_EXPIREFD
    

    尝试更换wua之后,发现秒跪。一般来说为了防止误杀是不会风控这么严的,说明某宝很自信有地方能辨明是爬虫。
    肯定是有什么地方被检测出是爬虫了,现在有很多因素。
    比如:

    1. 因为是挂了代理的,会不会是ip纬度被风控。
    2. 也有可能是同一个wua被限制了频次。
    3. 会不会是wua里带了初始生成的一些信息,比如地址,ip等。
    4. 也有可能是其他的字段加了辅助校验。
    5. 等等

    后续与其他组交流得知大概率是ip被风控了。

  • 小程序

  1. 爬虫对抗,这也是爬虫最难搞的地方,因为调用的是外部的接口,很多参数只能靠自己一点点尝试去理解。

    一旦爬虫跪了,是无法知道原因在哪的。因为你不可能知道很清楚的每个参数它所代表的的含义,只能一点一点的控制变量去尝试它的意义。这就给爬虫调试增加了很大的难度。

    假设成功调用了外部接口,也只能说明这种传参方式和值可以调用,你也不知道是否合法调用。有人会说跟抓包参数一一比对,模拟抓包的参数传值。但是有些参数是带链路的,是动态变化,是无法做到百分百一样的。

    最难的是接口之间调用还存在调用依赖和顺序的,增加了调试的难度而且费时费力。

    而且每个接口都是会进行迭代,做为爬虫很难感知到参数上的变化。只有当失败率上升了才能发现一些问题,外部接口每变更一个参数都会加大调试的难度。到后期接口越堆越多,每个接口都在迭代,维护成本越来越高。

    所以爬虫理论上是离线数据的获取,是不能有线上业务实时强依赖爬虫的,所有的业务都必须基于历史的离线数据进行分析。

你可能感兴趣的:(工作经验,java,python,大数据,爬虫)