前端与反爬虫
爬虫爬取数据主要是从 dom 节点上获取的,那么我们前端可以在 dom 节点上搞点骚操作来干扰爬虫抓取数据
1.1 字符串穿插
在 html 字符间插入无关紧要的元素来达到干扰爬虫的效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
const randomText = () => { let _len = 2 let i = 0 let _str = '' let _base = 20000 let _range = 1000 while (i < _len) { i++ var _lower = parseInt(Math.random() * _range) _str += String.fromCharCode(_base + _lower) } return _str }
const randomStyle = () => { let css = [ 'margin:-100px;', 'top:100%;', 'border: 1px solid red;', 'flex-grow: 1;', 'width: 1000px', 'color: #fff', 'overflow: hidden;' ] let style = 'display:none;' let num = Math.floor(Math.random() * 7) for (let i = 0; i <= num; i++) { style += css[i] } return style } export default { bind(el, { value }) { let fontNum = ''; let numberArray = value.toString().split('') for (let item of numberArray) { fontNum += `${item}<span style="${randomStyle()}">${randomText()}</span>` } el.innerHTML = fontNum; } }
|
1.2 元素定位覆盖
根据数据位数生成位数*2
个标签,然后通过定位将正确数据覆盖在错误数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| export default { bind(el, { value }) { let { data, w } = value; if (!el.style.position) { el.style.position = 'relative'; }
let valueArray = data.toString().split(''); let fakeNum = Math.floor(Math.random() * valueArray.length); fakeNum = fakeNum ? fakeNum : 1; let newHTML = []; let normalStyle = ['font-style: normal', 'background: #252527', 'position:absolute']; newHTML = valueArray.map((item, index) => { let s = [...normalStyle, ...[`left: ${index * w}px`, `width:${w}px`]].join(';'); return `<i style="${s}">${item}</i>`; }); for (let i = 0; i <= fakeNum; i++) { let n = Math.floor(Math.random() * 9); let s = [...normalStyle, ...[`left: ${i * w}px`, `width:${w}px`]].join(';'); newHTML.unshift(`<i style="${s}">${n}</i>`); } el.style.width = valueArray.length * w + 'px'; el.style.height = '12px'; el.innerHTML = newHTML.join(''); } }
|
1.1 font-face 拼凑
font-face 定义一套自己的字符集,页面引用对应的 unicode
1 2 3 4 5 6 7
| @font-face { font-family: 'iconfont'; src: url('./font/iconfont.eot'); src: url('./font/iconfont.eot?#iefix') format('embedded-opentype'), url('./font/iconfont.woff2') format('woff2'), url('./font/iconfont.woff') format('woff'), url('./font/iconfont.ttf') format('truetype'), url('./font/iconfont.svg#iconfont') format('svg'); }
|
1
| <span></span>
|
自定义指令 v-fontface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const fontface = [ '', '', '', '', '', '', '', '', '', '' ] export default { bind(el, { value }) { let fontNum = '' let numberArray = value.toString().split('') for (let item of numberArray) { fontNum += fontface[item] ? fontface[item] : item } el.innerHTML = fontNum } }
|