自学Python爬虫js逆向(二)chrome浏览器开发者工具的使用

js逆向中很多工作需要使用浏览器中的开发者工具,所以这里以chrome为例,先把开发者工具的使用总结一下,后面用到的时候可以回来查询。

Google Chrome浏览器的开发者工具是前端开发者的利器,它不仅提供了丰富的功能用于开发、调试和优化网页,还以其用户友好的接口而受到广泛欢迎。

打开一个网页,比如www.baidu.com,按下Ctrl+Shift+i 可以看到页面右半部分出现了如下的画面:

右边这部分就是开发者工具页面

这一排就是开发者工具的面板菜单,我们主要用到其中的4个面板:Elements(元素) Console(控制台)Sources(源代码) Network(网络),下面挨个来说

1、Elements(元素)面板

这里显示的是网页对应的HTML代码,一些静态网站的数据直接在这里就可以得到。

在这里我们可以修改Dom 和 Css 来调整我们网站的布局和设计,并且可以对网页内容做一个简单修改。比如这里我们调皮一下,把下面这个标签修改一下:

然后打开页面,就看到效果:

2、Console(控制台)面板

在控制台面板中,可以看到网页运行的一些诊断信息,或者可以使用它与页面上的javascript进行交互。

它可以理解为一个编辑器,我们经常用console输出变量的值,用console.log console.info console.error等不同形式打印信息,方便我们观察调试代码

console.count可以统计方法调用的次数

console.table可以以表格形式显示数据

我们在console面板中间的编辑器里先定义一个变量data,然后用console.table展示出来

console.copy方法可以复制变量的值

**$_**记录了最后一次在console中计算的表达式的值

**$('.subject')**可以找出所有类为subject的DOM

**$x()**可以结合xpath查看DOM内容

比如我们在网站上找到一个标签,在Element面板里找到这个标签,右键复制xpath地址

然后打开Console面板,在编辑器里输入如下代码

可以看到该标签内容被正确显示了出来。

3、Sources(源代码)面板

这是js逆向中使用最多的面板,因为网站的源代码都在这,我们就是要从中找到规律才能突破反爬获取数据。在这个面板中,我们可以通过设置断点来调整JavaScript的运行,或者使用我们的工作区域来连接本地文件,来使用开发者工具自带的实时编辑器来修改我们的源代码

可以看到sources面板分为三个部分:左边的是文件导航窗口,中间的是编辑器窗口,右边的是调试窗口。

3.1 调用本地文件

点击中间窗口的 select folder, 如果标题栏弹出要求获取权限的提示,点击允许

这时候就可以在local文件夹下看到我们准备好的本地文件

在这里可以对它进行打断点、调试等操作。

左边导航窗口的右箭头打开,选择overrides标签,可以进行本地代理操作

本地代理操作的意思是将远程的资源下载一份在本地,然后可以在开发者工具下进行编辑,开发者工具会更新展示我们编辑后的文件,即可以直接将一些请求代理到本地的文件当中,以更好地观察请求的运行情况。

点击 Select folder for overrides,跟上面一样添加一个本地文件夹local,也要允许权限,然后还要勾选 Enable Local Overrides。这时候我们就可以进行本地代理操作了。

打开Network,选择一个请求右键弹出菜单,选择override content

界面回到overrides,在中间编辑窗口就可以对文件进行修改,保存之后就可以在页面上看到效果

3.2 Snippets面板:

是一个代码片段工具,可以在该部分预先编辑好一些功能代码,在需要的时候方便运行。比如我们放一个常见的All Colors 脚本,用来输出RGB的颜色

javascript 复制代码
// allcolors.js
// https://github.com/bgrins/devtools-snippets
// Print out CSS colors used in elements on the page.

(function () {
  // Should include colors from elements that have a border color but have a zero width?
  var includeBorderColorsWithZeroWidth = false;

  var allColors = {};
  var props = ["background-color", "color", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color"];
  var skipColors = {
    "rgb(0, 0, 0)": 1,
    "rgba(0, 0, 0, 0)": 1,
    "rgb(255, 255, 255)": 1
  };

  [].forEach.call(document.querySelectorAll("*"), function (node) {
    var nodeColors = {};
    props.forEach(function (prop) {
      var color = window.getComputedStyle(node, null).getPropertyValue(prop),
        thisIsABorderProperty = (prop.indexOf("border") != -1),
        notBorderZero = thisIsABorderProperty ? window.getComputedStyle(node, null).getPropertyValue(prop.replace("color", "width")) !== "0px" : true,
        colorConditionsMet;

      if (includeBorderColorsWithZeroWidth) {
        colorConditionsMet = color && !skipColors[color];
      } else {
        colorConditionsMet = color && !skipColors[color] && notBorderZero;
      }

      if (colorConditionsMet) {
        if (!allColors[color]) {
          allColors[color] = {
            count: 0,
            nodes: []
          };
        }

        if (!nodeColors[color]) {
          allColors[color].count++;
          allColors[color].nodes.push(node);
        }

        nodeColors[color] = true;
      }
    });
  });

  function rgbTextToRgbArray(rgbText) {
    return rgbText.replace(/\s/g, "").match(/\d+,\d+,\d+/)[0].split(",").map(function(num) {
      return parseInt(num, 10);
    });
  }

  function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
  }

  function rgbToHex(rgbArray) {
    var r = rgbArray[0],
      g = rgbArray[1],
      b = rgbArray[2];
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
  }

  var allColorsSorted = [];
  for (var i in allColors) {
    var rgbArray = rgbTextToRgbArray(i);
    var hexValue = rgbToHex(rgbArray);

    allColorsSorted.push({
      key: i,
      value: allColors[i],
      hexValue: hexValue
    });
  }

  allColorsSorted = allColorsSorted.sort(function (a, b) {
    return b.value.count - a.value.count;
  });

  var nameStyle = "font-weight:normal;";
  var countStyle = "font-weight:bold;";
  function colorStyle(color) {
    return "background:" + color + ";color:" + color + ";border:1px solid #333;";
  };

  console.group("Total colors used in elements on the page: " + window.location.href + " are " + allColorsSorted.length);
  allColorsSorted.forEach(function (c) {
    console.groupCollapsed("%c    %c " + c.key + " " + c.hexValue + " %c(" + c.value.count + " times)",
      colorStyle(c.key), nameStyle, countStyle);
    c.value.nodes.forEach(function (node) {
      console.log(node);
    });
    console.groupEnd();
  });
  console.groupEnd("All colors used in elements on the page");

})();

运行后效果:

3.3 常用断点

在Sources(源代码)面板中我们经常会进行一些断点调试,这里总结一下常用的几种断点:

条件断点:

我们先准备一段测试代码放到Snippets

javascript 复制代码
console.log("断点测试");
let i = 0;
while (i<10) {
    console.log("本轮测试开始");
    console.log("现在i的值为:"+ i);
    // debugger;
    console.log("本轮测试结束");
    i++;
}

console.log("断点测试完成");

然后在代码行号点右键,弹出菜单里面选择 Add conditional breakpoint

在弹出的菜单里填写条件i=4,并在右边的watch里添加一个监控的变量 i

再次运行代码片段,发现运行到 i 的值为4时,程序就停住了

XHR断点:

我们先打开Network面板,勾选 XHR/fetch,然后刷新一下百度网站,看看有没有xhr请求

发现了一个,先不用管这请求是干嘛用的,我们截取前面一段字符串 sugrec ,然后点开Sources面板,在右边的XHR/fetch Breakpoints 标签右边点击 + 号增加一个xhr断点,然后把刚刚的字符串填进去,这样当网页再次发起包含 "sugrec" 这个字符串的xhr请求时,就会断点停下

再次刷新网站,发现果然断点了

DOM 断点:

在元素列表,找到想要断点的元素,点击右键,在弹出菜单里选择Break on => subtree modifications

然后在Sources面板里就可以看到该断点

当该元素发生改变的时候,就会断点停到这里

事件断点:

我们打开一个网站的登录界面,选择登录按钮,看到按钮的type是一个 submit,意味着这里调用了一个submit事件,我们打开Sources面板,选择Event Listenner Breakpoints => Control => submit

这样每当这个事件调用的时候,这里就会断点停到这里

3.4 工具栏介绍

最后再来说下右边的调试窗口最上方的这一排小图标

第1个 是暂停按钮,当运行到断点时会变成蓝色箭头,点击恢复执行直到下一个断点

第2个 是直接执行下一行然后直接就跳转到下一行

第3个 是如果下一行包含一个函数调用的话,就会进入到函数内部,并且在这个函数的第一行断上

就是经常会说的 追进去

第4个 是跳出当前函数的调用

第5个 是单步按钮,表示执行下一步

第6个 是暂时禁用所有的断点,用于恢复正常的执行

4、Network(网络)面板

这也是JS逆向中经常使用到的面板,在这个面板中可以用来抓包、查看每个请求的请求头、响应、以及它所耗费的时间等信息。

它包括控制器、过滤器、概览和请求

4.1 控制器

控制器可以用来控制我们网络面板的一个外观还有功能

第1个红色按钮控制是否抓包。

第2个是清除现有列表中的所有请求。

第3个是过滤器网格的开关。

第4个是一个搜索开关,打开可以出现一个搜索界面。

第5个是控制是否进行跨页面加载保存请求。不勾选的话,跨页面请求的时候之前的请求就会被清除。

第6个是控制是否禁用浏览器缓存。如果不勾选的话我们每一个请求都会去请求新的浏览器资源。

第7个是慢速网络模拟。可以使用slow 3G 或者离线状态来看一下浏览器在不同网络环境下请求是什么样子的。

4.2 过滤器

过滤器可以用来控制请求列表,显示哪些资源,比如说通过点选 Fetch/XHR,可以只显示异步请求(XHR),点选img标签,可以只显示图片资源。也可以通过Ctrl来多选。最左边的选择框可以进行关键字筛选,比如我们可以 输入 www.baidu.com 直接筛选出来自 www.baidu.com网站的请求。

4.3 概览

这里显示的是每个请求的时间线。

4.4 请求

这部分是重点。网页访问过程中的每一个请求都会被记录在这里。请求列表默认是以请求的时间顺序排列。这里可以看到请求的一些信息:Name(请求的名称) Status(状态码) Type(请求类型)Intiator(请求来源) Size(请求大小) Time(请求时间) 等等,这里最重要的是请求来源,可以看到请求的发起方,这很重要,很多时候我们可以通过它是从哪里发起的来判断它的JS大概是哪一个。

选中某个请求之后还可以看到该请求的详细情况:

Headers是请求头,包含了很多请求的信息。

Preview可以预览,比如图片啊之类的。

Response可以查看返回的数据。

Cookies 可以查看相关的cookies数据。

Timing 可以看到请求的耗时。

Tips小技巧1:用postman快速写一个爬虫:

随便找一个请求点击右键,选择 Copy as cURL(bash)注意:选别的格式postman不认。

然后在postman中打开import

在弹出的对话框中把刚刚复制的cURL地址粘贴进来,

然后界面跳转到如下,点击右边的这个</>符号

然后在右边会弹出相应的代码,如果显示的不是python代码,就点击这个下拉菜单,选择python-request,得到python爬虫代码

复制右边这些代码,到python程序中去执行,即可得到结果

tips小技巧2:查看依赖关系

选择一个请求,按住shift键,鼠标上下移动并悬停,可以看到下面显示红色的请求,都是依赖上面的请求而来

相反,我们按住shift键,选中某个请求,发现另一个请求是绿色的,则表示绿色的请求是该请求的发起者。

5、其他面板

其他面板jsweb逆向用到的不多,大致了解一下即可。

**Performance(性能)面板:**可以通过时间轴记录、查看网站生命周期内发生的各项事件来了解页面运行性能。

**Memory(内存)面板:**可以用来分析页面的执行时间以及内存的使用情况。

**Security(安全)面板:**可以用来调试混合内容问题、证书问题等等。

**Application(应用)面板:**可以记录网站加载的所有资源信息,比如cookie或者缓存数据、字体、图片、脚本、样式表等等。也可以清除网站数据。

相关推荐
数据小小爬虫4 分钟前
如何利用Python爬虫获取商品历史价格信息
开发语言·爬虫·python
黑色叉腰丶大魔王16 分钟前
《基于 Python 的网页爬虫详细教程》
开发语言·爬虫·python
高山我梦口香糖37 分钟前
[react] <NavLink>自带激活属性
前端·javascript·react.js
撸码到无法自拔42 分钟前
React:组件、状态与事件处理的完整指南
前端·javascript·react.js·前端框架·ecmascript
高山我梦口香糖42 分钟前
[react]不能将类型“string | undefined”分配给类型“To”。 不能将类型“undefined”分配给类型“To”
前端·javascript·react.js
Elena_Lucky_baby1 小时前
实现路由懒加载的方式有哪些?
前端·javascript·vue.js
一雨方知深秋2 小时前
智慧商城:封装getters实现动态统计 + 全选反选功能
开发语言·javascript·vue2·foreach·find·every
海威的技术博客2 小时前
关于JS中的this指向问题
开发语言·javascript·ecmascript
王解2 小时前
Vue CLI 脚手架创建项目流程详解 (2)
前端·javascript·vue.js
刘大浪2 小时前
vue.js滑动到顶便锁定位置
前端·javascript·vue.js