1. 程式人生 > 實用技巧 >Python爬蟲-正則表示式

Python爬蟲-正則表示式

<!DOCTYPE html>
<html lang="en" ng-app="myModel">
<head>
  <meta charset="UTF-8">
  <title>   </title>
  <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.6.2/angular.js"></script>
</head>
<body>
  <div ng-controller="thisCtrl
"> <divide-page allDatas='allDatas'></divide-page> </div> </body> </html> <script> var app = angular.module('myModel', []); app.controller('thisCtrl', function ($scope,checkListAndDividePage) { checkListAndDividePage({ scope:$scope, more:'one', idKey:
'id',//配置分頁的勾選 allDatas: { trueCb: function (result) { $scope.allDatas.nowPageNum = result.data[1].nowPageNumKey; $scope.allDatas.eachPageItemsNum = 10; $scope.allDatas.allPagesNum = result.data[1].allPagesNumKey; $scope.allDatas.allItemsNum = result.data[1].allItemsNumKey; $scope.allDatas.tableDatas
= result.data[1].tableDatasKey; //另,也可以先接收資料,再匯入彈窗頁面,然後將前者插入後者 }, errorCb: function (result) {/* 錯誤處理 */} } }); }); app.directive('dividePage', function () { var html = ` <div ng-show="allDatas.allPagesNum>=1"> <div> <div> <button ng-hide="allDatas.allPagesNum<=10" ng-click="clickDividePage('front') " ng-disabled="allDatas.nowPageNum===1" >上一頁</button> <button ng-repeat="num in allDatasArray track by $index" ng-bind="num" ng-click="clickDividePage(num) " ng-class="num===allDatas.nowPageNum?'classA':'classB'" ng-disabled="num==='...'"> </button> <button ng-hide="allDatas.allPagesNum<=10" ng-click="clickDividePage('back') " ng-disabled="allDatas.nowPageNum===allDatas.allPagesNum" >下一頁</button> </div> <div> <span>轉到</span> <input type="text" ng-model="customString" ng-keydown="clickDividePage('leap',$event)"> <span>頁</span> <button ng-click="clickDividePage('leap',{which:13})">Go</button> </div> </div> <div> <div> <span ng-bind="allDatas.frontMoreText"></span> <span ng-bind="allDatas.totalText||'共'"></span> <span ng-bind="allDatas.allItemsNum"></span> <span ng-bind="allDatas.totalUnit||'條'"></span> <span ng-bind="allDatas.backMoreText"></span> </div> <div> <span>每頁顯示</span> <select ng-model="allDatas.eachPageItemsNum" ng-options="item.back as item.front for item in numOptions"></select> <span>條</span> </div> </div> `; return { restrict: 'E', template: html, scope: { allDatas: '=allDatas' }, controller: function ($scope/* , cyRequest, wholeService */) { //頁面通過scope['allDatas']把配置資料注入到分頁; //在分頁控制器裡執行$scope.request(1),進而執行函式$scope.createDividePage,獲取分頁例項。 //不需要手動監聽資料的變化。 $scope.numOptions = [ { back: 10, front: 10 }, { back: 20, front: 20 }, { back: 30, front: 30 }, { back: 40, front: 40 }, { back: 50, front: 50 } ]; $scope.handleParameters = function (num,isFilter) { var clientDatas = {}; var pageNum = {}; var eachPageItemsNum = {}; var otherDatas = $scope.allDatas.otherDatas || {}; pageNum[$scope.allDatas.nowPageNum] = num; eachPageItemsNum[$scope.allDatas.eachPageItemsNumKey] = $scope.allDatas.eachPageItemsNum; clientDatas = angular.merge({}, pageNum, eachPageItemsNum, otherDatas); if (isFilter) { clientDatas = angular.merge({}, clientDatas, $scope.allDatas.filterOptions); } return clientDatas; }; $scope.request = /* $scope.allDatas.request = */ function (pageNum, message, isFilter, isInitCheck) { //isInitCheck:是否初始化複選框。點選“重新整理”、“過濾”、“清除過濾”時,需要用到此引數 var toServer={ method: $scope.allDatas.method, url: $scope.allDatas.url, isWholeCircle: $scope.allDatas.isWholeCircle, isUseWholeCircle: $scope.allDatas.isUseWholeCircle, isPartCircle: $scope.allDatas.isPartCircle, isUsePartCircle: $scope.allDatas.isUsePartCircle, }; if($scope.allDatas.isShowParams){ toServer.params = $scope.handleParameters(pageNum,isFilter); delete toServer.data }else{ toServer.data = $scope.handleParameters(pageNum,isFilter); delete toServer.params }; cyRequest(toServer) .then(function (result) { $scope.allDatas.trueCb(result, isInitCheck); $scope.createDividePage();//非同步DOM更新:資料發生改變後,angular1沒有立即將改變的資料更新到檢視中,而是等到資料不再變化的時候,一次性的將資料的改變更新到檢視中。因此需要在$scope.createDividePage裡強行更新。 if (message) { // <whole-popup required-data="requiredData"></whole-popup> // $scope.requiredData = { // isShow: $scope.allDatas.isShowTip, // width:'400px', // title: '詳情', // tip: $scope.allDatas.tipContent // }; $scope.allDatas.isShowTip = true; $scope.allDatas.tipContent = message; } }) .catch(function (result) { $scope.allDatas.isShowTip=false; angular.isFunction($scope.allDatas.errorCb) ? $scope.allDatas.errorCb(result,isInitCheck) : angular.noop(); }); }; $scope.createDividePage = function () { var dividePageArray = []; var allPagesNum = $scope.allDatas.allPagesNum; var nowPageNum = $scope.allDatas.nowPageNum; if (allPagesNum >= 1 && allPagesNum <= 10) { for (var i = 1; i <= allPagesNum; i++) { dividePageArray.push(i); } } else if (allPagesNum >= 11) { // 當前頁的左邊 if (nowPageNum > 6) {//如果當前頁前面超過5項,即包含自身超過6項,那麼省略顯示; dividePageArray.push(1); dividePageArray.push('...'); dividePageArray.push(nowPageNum - 3); dividePageArray.push(nowPageNum - 2); dividePageArray.push(nowPageNum - 1); dividePageArray.push(nowPageNum);//這是當前頁。 } else {//如果當前頁前面不超過5項,即包含自身不超過6項,那麼全部顯示; for (i = 1; i <= allPagesNum; i++) { dividePageArray.push(i); } } // 當前頁的右邊 if (allPagesNum - nowPageNum >= 6) { //如果當前頁後面有6項及以上,那麼省略顯示; dividePageArray.push(nowPageNum + 1); dividePageArray.push(nowPageNum + 2); dividePageArray.push(nowPageNum + 3); dividePageArray.push('...'); dividePageArray.push(allPagesNum); } else {//如果當前頁後面有5項及以下,那麼全部顯示; for (var i = nowPageNum + 1; i <= allPagesNum; i++) { dividePageArray.push(i); } } } setTimeout(function () { $scope.dividePageArray = dividePageArray; $scope.$apply(); }); }; $scope.clickDividePage = function (stringOfNum, event) { var allPagesNum = $scope.allDatas.allPagesNum; var nowPageNum = $scope.allDatas.nowPageNum; if (stringOfNum === 'front' && nowPageNum != 1) { nowPageNum--; } else if (stringOfNum === 'back' && nowPageNum != allPagesNum) { nowPageNum++; } else if (stringOfNum === 'leap') { if (event.which != 13) return;//不攔截情形:(1)聚焦輸入框、按“Enter”鍵時;(2)點選“GO”時 var customNum = Math.ceil(parseFloat($scope.customString)); if (customNum < 1 || customNum == 'NaN') { nowPageNum = 1;//不給提示 } else if(customNum > allPagesNum) { nowPageNum = allPagesNum;//不給提示 } else { nowPageNum = customNum; } } else { nowPageNum = Math.ceil(parseFloat(stringOfNum)); } $scope.customString = nowPageNum; $scope.request(nowPageNum); }; /* if (!$scope.allDatas.isNoInit) { $scope.request(1); } */ }, }; }); app.factory('checkListAndDividePage', function () { function checkListFn(idKey) { return { idKey: idKey ? idKey : 'id',//每條資料的唯一標誌 isSelectThisPage: false,//當前頁所有項是否全選 allIncludedIds: [],//所有被選中資料的ID構成的陣列 allExcludedIds: [],//所有沒被選中資料的ID構成的陣列 numOfAllSelected: 0,//所有頁被選中資料的條數 textAfterClick: '全選未啟用!',//複選框被點選後的提示文字。 allCheckbox: { noUse: { isTrue: true,//用這個值作為是否“啟用”全選的依據,進而決定如何向後臺傳參。 text: '全選未啟用!' }, partUse: { isTrue: false, text: '全選已啟用,還有未勾選項。' }, allUse: { isTrue: false,//全選是否勾選與這個值繫結。 text: '全選已啟用!' }, }, init: function(){//點選“重新整理”、“過濾”、“清除過濾”時執行 this.idKey = idKey ? idKey : 'id', this.isSelectThisPage = false, this.allIncludedIds = [], this.allExcludedIds = [], this.numOfAllSelected = 0, this.textAfterClick = '全選未啟用!', this.allCheckbox = { noUse: { isTrue: true, text: '全選未啟用!' }, partUse: { isTrue: false, text: '全選已啟用,有排除項!' }, allUse: { isTrue: false, text: '全選已啟用!' }, } }, handleAllPagesClicked: function (use, isTrueNoUse, isTruePartUse, isTrueAllUse) { this.allCheckbox.noUse.isTrue = isTrueNoUse; this.allCheckbox.partUse.isTrue = isTruePartUse; this.allCheckbox.allUse.isTrue = isTrueAllUse; this.textAfterClick = this.allCheckbox[use].text + (this.numOfAllSelected === 0 ? '' : '已選擇' + this.numOfAllSelected + '條!'); }, clickAllPages: function (itemArray, numOfAllDatas) {//所有頁所有條目全選複選框被點選時執行的函式 var isAll = this.allCheckbox.allUse.isTrue = !this.allCheckbox.allUse.isTrue; angular.forEach(itemArray, function (item) { item.isChecked = isAll; }); this.isSelectThisPage = isAll; if (isAll) { this.allExcludedIds = []; this.numOfAllSelected = numOfAllDatas; this.handleAllPagesClicked('allUse', false, false, true); } else { this.allIncludedIds = []; this.numOfAllSelected = 0; this.handleAllPagesClicked('noUse', true, false, false); } }, clickCurrentPage: function (itemsArray, numOfAllDatas) {//當前頁所有條目全選複選框被點選時執行的函式 var that = this; this.isSelectThisPage = !this.isSelectThisPage angular.forEach(itemsArray, function (item) { item.isChecked = that.isSelectThisPage; if (item.isChecked) { that.delID(item[that.idKey], that.allExcludedIds); that.addID(item[that.idKey], that.allIncludedIds); } else { that.delID(item[that.idKey], that.allIncludedIds); that.addID(item[that.idKey], that.allExcludedIds); } }); this.numOfAllSelected=allIncludedIds.length; if(this.numOfAllSelected === 0){ this.handleAllPagesClicked('noUse', true, false, false); }else if(this.numOfAllSelected === numOfAllDatas){ this.handleAllPagesClicked('allUse', false, false, true); }else{ this.handleAllPagesClicked('partUse', false, true, false); } }, clickSingleItem: function (item, itemsArray, numOfAllDatas) {//當前頁單個條目複選框被點選時執行的函式 var that = this; item.isChecked = !item.isChecked; if (item.isChecked) { this.isSelectThisPage = true; this.addID(item[this.idKey], this.allIncludedIds); this.delID(item[this.idKey], this.allExcludedIds); angular.forEach(itemsArray, function (item) { if (!item.isChecked) { that.isSelectThisPage = false; } }); } else { this.isSelectThisPage = false; this.addID(item[this.idKey], this.allExcludedIds); this.delID(item[this.idKey], this.allIncludedIds); } this.numOfAllSelected=allIncludedIds.length; if(this.numOfAllSelected === 0){ this.handleAllPagesClicked('noUse', true, false, false); }else if(this.numOfAllSelected === numOfAllDatas){ this.handleAllPagesClicked('allUse', false, false, true); }else{ this.handleAllPagesClicked('partUse', false, true, false); } }, signCheckbox: function (itemsArray) {//標註當前頁被選中的條目,在翻頁成功後執行。 var that = this; if (this.allCheckbox.noUse.isTrue) { angular.forEach(itemsArray, function (item) { var thisID = item[that.idKey]; var index = that.allIncludedIds.indexOf(thisID); if (index = -1) { item.isChecked = false; } else { item.isChecked = true; } }); }else{ angular.forEach(itemsArray, function (item) { var thisID = item[that.idKey]; var index = that.allExcludedIds.indexOf(thisID); if (index = -1) { item.isChecked = true; } else { item.isChecked = false; } }); } }, addID: function (id, idArray) { var index = idArray.indexOf(id); if (index = -1) { idArray.push(id);//如果當前頁的單項既有勾選又有非勾選,這時勾選當前頁全選,需要這個判斷,以免重複新增 } }, delID: function (id, idArray) { var index = idArray.indexOf(id); if (index > -1) { idArray.splice(index, 1) } }, getResultOfCheckAndFilter: function (filterOptions) {//獲取傳送給後臺的所有引數。 var toServerDatas; if (this.allCheckbox.noUse.isTrue) { if (this.allIncludedIds.length === 0) { //return 彈窗告知:沒有勾選項 } toServerDatas = { allIncludedIds: this.allIncludedIds, isSelectAll: false } }else { toServerDatas = { //exclude allExcludedIds: this.allExcludedIds, isSelectAll: true }; } if (filterOptions) { angular.merge(toServerDatas, filterOptions); } return toServerDatas; }, } }; function dividePageFn(allDatas) {//下面這些資料,在例項化後,傳送給後臺之前,有可能會改變 return { //1、請求配置 url: allDatas.url || '', method: allDatas.method || 'post', isShowParams: allDatas.isShowParams || false,//顯式還是隱式傳參。有時需要在請求發出前手動改變。 //2、響應配置(前端通過這個配置,獲取後臺的資料) nowPageNumKey: allDatas.nowPageNumKey || 'nowPageNumKey',//來自伺服器的當前頁碼key allPagesNumKey: allDatas.allPagesNumKey || 'allPagesNumKey',//來自伺服器的所有頁頁數key allItemsNumKey: allDatas.allItemsNumKey || 'allItemsNumKey',//來自伺服器的所有頁資料數key eachPageItemsNumKey: allDatas.eachPageItemsNumKey || 'eachPageItemsNumKey',//來自伺服器的每頁最多資料數key tableDatasKey: allDatas.tableDatasKey || 'tableDatasKey',//來自伺服器的表格資料key //3、分頁展示配置(前端通過這個配置,接收後臺的資料) nowPageNum:1,//當前頁數 allPagesNum:1,//所有頁數 allItemsNum:1,//所有頁所有條目數 eachPageItemsNum: allDatas.eachPageItemsNum ||10,//每頁展示條目數 //4、以下配置使用哪種轉圈方式(前端根據需要決定,不受後臺影響) partCircle: allDatas.partCircle,//區域性是否轉圈。allDatas.partCircle=$scope.partCircle={isShow:false}。 isUsePartCircle: allDatas.isUsePartCircle,//區域性是否轉圈,由當前頁的一個變數控制 isUseWholeCircle: allDatas.isUseWholeCircle,//全域性是否轉圈,由本專案的一個服務控制 //5、初始化以下資料,供頁面使用(前端根據需要決定,不受後臺影響) otherDatas: {},//頁碼、頁條目數、過濾條件外的引數,呼叫allDatas.request函式,重新渲染頁面。 filterOptions: {},//過濾條件 isShowFilter: false,//是否顯示過濾條件 isNoInit: allDatas.isNoInit||false,//是否不立即向後臺傳送請求 totalText: allDatas.totalText || "",//'共', totalUnit: allDatas.totalUnit || '',//總資料的單位 frontMoreText: allDatas.frontMoreText || "",//('文字 ')或者("文字 "+result.numOne+" 文字 "), backMoreText: allDatas.backMoreText || "",//(' 文字')或者("文字 "+result.numThree+" 文字"), //6、以下是現成方法,呼叫即可 toggleShowFilter: function () { this.isShowFilter = !this.isShowFilter; if (!this.isShowFilter) { this.request(1); } }, emptyFilterOptions: function (extraObject) { //清空選項時,所有值恢復成預設 var that = this; angular.forEach(that.filterOptions, function (value, key) { //大部分選項的預設值是undefined that.filterOptions[key] = undefined; }); if (extraObject) { //小部分選項的預設值不是undefined angular.forEach(extraObject, function (value, key) { that.filterOptions[key] = value; }); } this.request(1); } } } return function (configures) {//執行步驟二。========================= var scope = configures.scope;//獲取當前作用域。 var more = configures.more || '';//如果一個頁面有兩個分頁,那麼用more進行區分。 var idKey = configures.idKey; var params = configures.allDatas; var checkBox = scope['checkBox' + more] = checkListFn(idKey); //獲取分頁勾選的例項。 var dividePage = scope['dividePage' + more] = dividePageFn(params); //獲取分頁元件的例項。 dividePage.trueCb = function (result, isInitCheck) {//獲取新資料後,執行的回撥 if(angular.isFunction(params.trueCb)){ params.trueCb(result) }else{ scope.dividePage.nowPageNum = result.data[scope.dividePage.nowPageNumKey]; scope.dividePage.eachPageItemsNum = result.data[scope.dividePage.eachPageItemsNumKey]|| 10; scope.dividePage.allPagesNum = result.data[scope.dividePage.allPagesNumKey]; scope.dividePage.allItemsNum = result.data[scope.dividePage.allItemsNumKey]; scope.dividePage.tableDatas = result.data[scope.dividePage.tableDatasKey]; scope.trueDatas = result.data[dividePage.tableDatasKey]; } if(isInitCheck){ checkBox.init();//通過點選“重新整理”、“過濾”、“清除過濾”獲取新資料,初始化勾選 }else{ checkBox.signCheckbox(result[dividePage.tableDatasKey], result.allItemsNum);//通過點選分頁獲取新資料,用已儲存的勾選 } }; dividePage.errorCb = function (result) {//獲取新資料後,執行的回撥 scope.errorDatas = result.data; angular.isFunction(params.errorCb) ? params.errorCb(scope, result) : angular.noop(); } } }) </script>