由于一些巨大的困难,一些后端爬虫改成了前端爬虫。
前端爬虫是只有js语言,后端爬虫有python java nodejs php这些语言。
前端爬虫有window.document对象,在浏览器端的爬虫即使是二次发送ajax,也不需要学后端爬虫来构造一堆请求头,特别是困难的cookie token。最为重要的还是天然的突破了ip限制。
提取个人信息,直接使用页面渲染后的结构:
/*** Created by xy49476 on 2018/1/9.*//* * http://iservice.10010.com/e4/index_server.html * 提取个人信息 * */function extractPersonalInfomation() {var loginName = document.querySelector('#personalInfo td').innerText;var userLevel = document.querySelector('#font').innerText;var userName = document.querySelector('div.data_basic_c.ly_gr_zl > dl:nth-child(1) > dd').innerText;var sex = document.querySelector('div.data_basic_c.ly_gr_zl > dl:nth-child(3) > dd').innerText;var idNo = document.querySelector('div.data_basic_c.ly_gr_zl > dl:nth-child(5) > dd').innerText;var contactPhone = document.querySelector('div.data_basic_c.ly_gr_zl > dl:nth-child(9) > dd').innerText;var contactAddress = document.querySelector('div.data_basic_c.ly_gr_zl > dl:nth-child(11) > dd').innerText;var package = document.querySelector('#packageInfocontext > div.add_main > div > dl:nth-child(1) > dd').innerText;var chargeType = document.querySelector('#packageInfocontext > div.add_main > div > dl:nth-child(3) > dd').innerText;var currentStatus = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_l > dl:nth-child(1) > dd').innerText;var netInDate = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_r > dl:nth-child(1) > dd').innerText;var billingAccount = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_l > dl:nth-child(3) > dd').innerText;var brand = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_r > dl:nth-child(2) > dd').innerText;var communicatelevel = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_l > dl:nth-child(4) > dd').innerText;var pukCode = document.querySelector('#numberContext > div.data_basic_c2 > div.data_basic_c2_r > dl:nth-child(3) > dd').innerText;var contractName = document.querySelector('#contractPeriod > div.ly_gr_l2 > dl:nth-child(1) > dd').innerText;var effectiveTime = document.querySelector('#contractPeriod > div.ly_gr_l2 > dl:nth-child(3) > dd').innerText;var uneffectiveTime = document.querySelector('#contractPeriod > div.ly_gr_l2 > dl:nth-child(5) > dd').innerText;personalObj = {loginName:loginName,userLevel:userLevel,userName:userName,sex:sex,idNo:idNo,contactPhone:contactPhone,contactAddress:contactAddress,package:package,chargeType:chargeType,currentStatus:currentStatus,netInDate:netInDate,billingAccount:billingAccount,brand:brand,communicatelevel:communicatelevel,pukCode:pukCode,contractName:contractName,effectiveTime:effectiveTime,uneffectiveTime:uneffectiveTime};return '{"personalInfo":' + JSON.stringify(personalObj) + '}';}//extractPersonalInfomation();
提取通话记录,这里和上面不同,发送了ajax来获取json,按月份按分页获取通话记录:
/*** Created by xy49476 on 2018/1/10.*/
/*http://iservice.10010.com/e4/query/bill/call_dan-iframe.html?menuCode=000100030001
提取通话记录
*
* */function extractCallRecordsOuter() {function getNear6Montgh(){var near6MonthArray = [];for (var i=0;i<6;i++){var d = new Date();d.setMonth(d.getMonth() - i);var yy1 = d.getFullYear();var mm1 = d.getMonth() + 1;//因为getMonth()返回值是 0(一月) 到 11(十二月) 之间的一个整数。所以要给其加1var dd1 = d.getDate();// if (mm1 < 10) {// mm1 = '0' + mm1;// }if (dd1 < 10) {dd1 = '0' + dd1;}console.info(yy1 + '-' + mm1 + '-' + dd1);near6MonthArray.push([yy1,mm1]);}return near6MonthArray;}//按照年月,获取一个月有多少天 mGetDate(2004,2)function mGetDate(year, month){var d = new Date(year, month, 0);return d.getDate();}var callRecordsArray = [];function extractCallRecords() {//历史账单var near6MonthArray = getNear6Montgh();for (i of near6MonthArray) {var dates = mGetDate(i[0], i[1]);var mm1 = i[1];if (mm1 < 10) {mm1 = '0' + mm1;}var yearMonth = i[0] + '' + mm1;var callRecordsObj = {};callRecordsObj.pagelist = [];callRecordsObj.yearMonth = yearMonth;function extractCallRecordByPage(page) {var page = page || 1;var url = 'http://iservice.10010.com/e3/static/query/callDetail?_=1515561593328&accessURL=http://iservice.10010.com/e4/query/bill/call_dan-iframe.html?menuCode=000100030001&menuid=000100030001';var data = {pageNo: page,pageSize: 200,beginDate: yearMonth + '01',endDate: yearMonth + dates};console.debug(data);var htmlObj = $.ajax({type: 'POST',url: url,data: data,async: false //一定要设置这个,否则异步的还没得到返回结果就执行到下面去了,代码 一定会报错});var htmlStr = htmlObj.responseText;console.debug('htmlStr:',htmlStr);var callRecordsRawObj = JSON.parse(htmlStr);callRecordsObj.pagelist = callRecordsObj.pagelist.concat(callRecordsRawObj.pagelist);var totalpage = callRecordsRawObj.totalpage;if (page < totalpage) {extractCallRecordByPage(page + 1); //回调自己}}extractCallRecordByPage();callRecordsArray.push(callRecordsObj);}callRecordsInfoObj = {callRecordsInfo:callRecordsArray};return JSON.stringify(callRecordsInfoObj);}return extractCallRecords();
}
//extractCallRecordsOuter();
为了一个脚本一个函数,在最外层套了一个函数。
有没有很像js闭包,但这不是闭包。
最后三行是
return extractCallRecords();
}
extractCallRecordsOuter();
如果改成下面,
return extractCallRecords;
}
extractCallRecordsOuter()();
这样就是js之闭包了。
前端爬虫时候,使用jqury选择器或者document的queryselector方法就能使用css3选择器的语法了。比getElementByxx能更精确的提取某些元素。
使用jquery时候,如果被爬页面没有引入jquery库,需要先在document注入jquery地址或者完整的执行一遍jquery代码。