• 30分钟学会爬虫 实战演习


    混迹博客园那么久,人也很懒。思考了一下还是把这篇文章记录下来。原创https://www.cnblogs.com/y112102/p/10788564.html。

    这里说的是只基于google插件 

    30分钟

    准备知识:javascript, sql(新建一个表就可以了),一个接口webapi(入库数据)。

    传统的做法:

    1:后台发送一个请求(request),获取输出(response) 然后对输出的结果分析。筛选符合自己业务的数据 (还是不理解的查看 http://www.cnblogs.com/youuuu/archive/2011/06/17/2083714.html)。

    2:【难度】数据筛选,后台模拟请求 可能采集的页面涉及到token,登入身份信息....当然我也不会说他不好。一个字麻烦。 系数大。

    主角登场:先易后难。

    场景:

    1:建立好数据库,简单除暴 没啥好说的。

     2:一个api接口能插入数据 就可以(接受参数,插入数据库)简单粗暴 没什么逻辑。

    3:主角 google插件

    1:一个manifest.json文件

    2:1个html页面

    3:一个js文件

    manifest.json:

    {
      // 清单文件的版本,
      "manifest_version": 2,
      // 插件的名称
      "name": "xxx采集",
      // 插件的版本
      "version": "1.0",
      // 插件描述
      "description": "色卡xxx内部使用",
      // 作者
      "author": "sxei",
      // 图标,一般偷懒全部用一个尺寸的也没问题
      "icons": {
        "48": "img/icon.png",
        "128": "img/icon.png"
      },
      // 浏览器右上角图标设置,browser_action、page_action、app必须三选一
      "browser_action": {
        "default_icon": "img/icon.png",
        "default_popup": "popup.html"
      },
      // 需要直接注入页面的JS
      "content_scripts": [
        {
          //匹配的网站
          "matches": [ "https://www.x.com/Producttxxxx", "https://www.x.com/Color/*" ],
          // 多个JS按顺序注入
          "js": [ "js/jquery-1.10.2.min.js", "js/content-script.js" ]
        }
      ],
      // 权限申请 (这个很重要 如何没有它 我们的请求是无法跨域的) 有啥就写啥 权限最大化
      "permissions": [
        "contextMenus",
        "tabs",
        "notifications",
        "webRequest", // web请求
        "webRequestBlocking",
        "storage",
        "http://*/*",
        "https://*/*"
      ]
    }
    View Code

    2:html页面和 manifest.json 【browser_action】里面的名称保持一致就好popup.html

    html内容:根据业务需求(我一般弄一个链接打开要采集的页面 和一些说明信息)原因:某一些网站有很多域名 同一个业务地址栏不同。干脆指定

    如图:

    <!DOCTYPE html>
    <html>
    <head>
        <title>【xxx】</title>
        <meta charset="utf-8"/>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style  type="text/css" >
        body {
            padding-bottom: 20px;   
            font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
            font-size: 14px;
            line-height: 1.42857143;
            color: #333;
            background-color: #fff;   
            margin: 0;
            width: 200px;
            text-align: center;
        }
    
        @-webkit-keyframes shake{
            0%{
                opacity: 1;
            }
            50%{
                opacity: 0.5;
            }
            100%{
                opacity: 1;
            }
        }
        @keyframes shake{
            0%{
                opacity: 1;
            }
            50%{
                opacity: 0.5;
            }
            100%{
                opacity: 1;
            }
        }
        .shake{
            -webkit-animation: shake 2s infinite;
            animation: shake 2s infinite;
            color:red;
        }
        </style>
    </head>
    <body>
        <h4>【x入口】</h4>
        <a href="#" id="openCtripWindow">xx(不要点击其他页签)</a>
        <h5 class="shake">采集失败请联系电脑部</h5>
        <h5 class="shake">提示:x内部使用</h5>
        <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
        <script type="text/javascript" src="js/popup.js"></script>
    </body>
    </html>
    View Code

    js:(为了方便省事 用的jquery)我都写上注释了。写在 manifest.json 配置 注入的 content-script.js文件 里面

     
      1 (function() {
      2     var tempVriable = {
      3         apiUrl: "http://localhost:62930/api/Ctrip/InsetSeKa",
      4         nowUrl: window.location.href,
      5         mainPage: "xxxxx",
      6         caiJiePage: "https://www.xxx.com/Color/",
      7     };
      8 
      9     var systemMethod = {
     10         Ajax: function(obj) {
     11             var objs = $.extend({
     12                     dataType: "json",
     13                     data: obj.data,
     14                     error: function(xmlHttpRequest, textStatus, errorThrown) {
     15                         console.group("system.js文件 ajax入口");
     16                         console.error(`url:${this.url}`);
     17                         console.error(`错误原因(默认显示150字):${xmlHttpRequest.responseText}`);
     18                         console.groupEnd();
     19                         console.count("ajax error 错误次数");
     20                     },
     21                     success: obj.success,
     22                     url: obj.url,
     23                     //timeout: 6000,  //超时时间设置,单位毫秒
     24                     type: "get",
     25                     beforeSend: function(request) {
     26                         //request.setRequestHeader("Authorization", variableObj.keys);
     27                     },
     28                     //当请求完成之后调用这个函数
     29                     complete: function (xmlHttpRequest, status) {
     30                         if (status === 'timeout') {
     31                             console.error("请求时间超时6秒 问题频繁出现请联系管理员");
     32                             // console.trace();
     33                         }
     34                         if (typeof (this.globalAjax) == "undefined") {
     35 
     36                         }
     37                     }
     38                 },  obj);
     39             $.ajax(objs);
     40         },
     41         //主页面
     42         mainPage: function () {
     43             if (tempVriable.nowUrl.indexOf(tempVriable.mainPage) == -1) return;
     44             var tempElement = $(".productColors ul").find(".show-color-image");
     45             //注意for循环定义用的let 闭包 注意不要太频繁 控制频率
     46             for (let j = 0; j < 10; j++) {
     47                 setTimeout(function () {
     48                     let thisInfo = $(tempElement[j]);
     49                     thisInfo.trigger("click");
     50                 }, j * 1000);
     51             }
     52         },
     53         //采集页面
     54         sendCaiJiePage: function() {
     55             if (tempVriable.nowUrl.indexOf(tempVriable.caiJiePage) > -1) {
     56                 let tempName = $(".SimpleColorBlock h1")[0].childNodes,
     57                     RGB = $(".cmyk"),
     58                     tableDom = $(".block-detail table td");
     59                 //采集的数据
     60                 var data = {
     61                     TPX: tempName[0].textContent,
     62                     colorName: tempName[2].textContent,
     63                     R: RGB[0].innerText,
     64                     G: RGB[1].innerText,
     65                     B: RGB[2].innerText,
     66                     Hex: tableDom[6].innerText
     67                 };
     68                 //发送请求
     69                 systemMethod.Ajax({
     70                     data: data,
     71                     url: tempVriable.apiUrl,
     72                     success: function (json) {
     73                         if (json != undefined && json.Result == 0) {
     74                             systemMethod.closePage();
     75                         } else {
     76                             console.error(`api 500${json}`);
     77                         }
     78                     }
     79                 });
     80             }
     81         },
     82         //窗口关闭 释放资源
     83         closePage: ()=>{
     84             window.opener = null;
     85             window.open("", "_self", "");
     86             window.close();
     87         },
     88         //初始化入口
     89         Init: function () {
     90             //打印控制台日志 
     91             setTimeout(() => {
     92                 console.clear();
     93                 if (tempVriable.nowUrl.indexOf(tempVriable.mainPage) > -1) {
     94                     console.log('%c 页面启动成功-内部使用', 'color:red;');
     95                 }
     96                 if (tempVriable.nowUrl.indexOf(tempVriable.caiJiePage) > -1) {
     97                     console.group('页面启动成功-内部使用');
     98                     console.log('%c 页面启动成功-内部使用', 'color:red;');
     99                     console.groupEnd();
    100                 }
    101             }, 200);
    102 
    103             //入口页面 防止第3方页面未加载完 延迟
    104             setTimeout(() => {
    105                 systemMethod.setData();
    106             }, 2000);
    107 
    108             //采集页面 防止第3方页面未加载完成延迟
    109             setTimeout(() => {
    110                 systemMethod.sendCaiJiePage();
    111             }, 2000);
    112         },
    113         registeEevent: function() {
    114 
    115         }
    116     };
    117     systemMethod.Init();
    118 })();

    结果:

    附加到google插件,然后打开自己的页面吧 去见证这个奇迹

    花了40分钟大功告成

    总结:建好数据库,一个接口(这些对我们来说都是5分钟的事情)。

    1个:manifest.json 文件 格式按规定写。依葫芦画瓢 不要问为什么 google的规矩

    js文件 想怎么写就怎么写 是不是很简单。30分钟你看可以吗?

    3:细节 后台打印 记录日志 前台打印记录日志, 可能某一些采集的页面 在实现模拟人工操作 可能会复杂一点 。这个只能多花时间了。

    4:可能某一些反爬虫的 页面 有很多限制。比如说访问太频繁 ,页面故意制造一线逻辑 数据获取麻烦 比如说 (自己体验的携程的机票数据) 可能是自己水平有限 携程的反爬虫 做的还是可以 。

     5:你的爬虫来源的对方的成功的 。最高的反爬虫就是放对方一码 都是码农 何必为难自己。 

    6:缺点 需要打开浏览器 毕竟他的名字是叫google插件

    补充知识:如果你想跟详细的了解 google插件    https://github.com/sxei/chrome-plugin-demo

    如果对你有帮助 帮忙推荐一下。如果你有什么问题也可以留言。

  • 相关阅读:
    css中margin-left与left的区别
    Python文件和目录模块介绍:glob、shutil、ConfigParser
    [ Python入门教程 ] Python文件基本操作_os模块
    使用Pyinstaller转换.py文件为.exe可执行程序
    Windows命令行打开常用界面
    如何做好性能测试_流程篇
    Windows查看指定端口是否占用和查看进程
    ‘操作无法完成 ,因为其中的文件夹或文件已在另一程序中打开’问题解决
    bat脚本基础教程
    vi编辑器常用命令
  • 原文地址:https://www.cnblogs.com/y112102/p/10788564.html
Copyright © 2020-2023  润新知