Я видел проницательную статью раньшестатья, рассказывает о внешних методах защиты от сканирования различных крупных производителей, но, как говорится в статье, не существует стопроцентного метода защиты от сканирования. В этой статье представлен простой способ обойти все эти внешние методы защиты от сканирования.
В следующем коде в качестве примера используется Baidu Index.Код был инкапсулирован в библиотеку узлов поискового робота Baidu Index: https://github.com/Coffcer/baidu-index-паук
примечание: не злоупотребляйте поисковыми роботами, чтобы доставлять неприятности другим.
Стратегия Baidu Index против сканеров
Глядя на интерфейс Baidu Index, данные индекса представляют собой график тенденций.При наведении курсора мыши на определенный день будут запущены два запроса, а результаты будут отображаться в плавающем окне:
По общей идее, давайте сначала посмотрим на содержание этого запроса:
Запрос 1:
Запрос 2:
Можно обнаружить, что Baidu Index фактически реализовал определенную стратегию против рептилий на переднем крае. Когда мышь перемещается по диаграмме, запускаются два запроса, один из которых возвращает фрагмент html, а другой возвращает сгенерированное изображение. HTML не содержит фактического значения, но задав ширину и margin-left, отображаются соответствующие символы на картинке. И параметры запроса имеют параметры res и res1, которые мы не знаем, как имитировать, поэтому сложно сканировать данные индекса Baidu с помощью обычных имитационных запросов или методов сканирования html.
идеи рептилий
Как прорваться через метод защиты от рептилий Baidu на самом деле очень просто, просто не обращайте внимания на то, как он работает против рептилий. Нам нужно только смоделировать действия пользователя, сделать скриншоты необходимых значений и сделать распознавание изображений. Шаги примерно такие:
- Имитация входа
- Откройте индексную страницу
- Подведите мышку к указанной дате
- Дождаться окончания запроса, и перехватить картинку числовой части
- значение распознавания изображения
- Повторите шаги с 3 по 5, чтобы получить значение, соответствующее каждой дате.
Теоретически этим методом можно сканировать содержимое любого веб-сайта.Далее мы будем поэтапно реализовывать краулер.Будут использоваться следующие библиотеки:
- puppeteerИмитация работы браузера
- node-tesseractПакет tesseract для распознавания изображений
- jimpобрезка изображения
Установите Puppeteer, имитируйте действия пользователя
Puppeteer — это инструмент автоматизации Chrome, созданный командой Google Chrome, который используется для управления Chrome для выполнения команд. Он может имитировать пользовательские операции, проводить автоматизированное тестирование, поисковые роботы и т. д. Использование очень простое.В Интернете есть много вводных руководств.После прочтения этой статьи вы, вероятно, уже знаете, как им пользоваться.
Документация по API: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md
Установить:
npm install --save puppeteer
Puppeteer автоматически загружает Chromium при установке, чтобы обеспечить его правильную работу. Тем не менее, внутренняя сеть может не иметь возможности успешно загрузить Chromium.Если загрузка не удалась, вы можете использовать cnpm для его установки или изменить адрес загрузки на зеркало Taobao, а затем установить его:
npm config set PUPPETEER_DOWNLOAD_HOST=https://npm.taobao.org/mirrors
npm install --save puppeteer
Вы также можете пропустить загрузку Chromium при установке и запустить его, указав собственный путь Chrome с помощью кода:
// npm
npm install --save puppeteer --ignore-scripts
// node
puppeteer.launch({ executablePath: '/path/to/Chrome' });
выполнить
Для макета ниже указана только основная часть, код включает в себя часть селектора, вместо этого полный код, чтобы увидеть склад GitHub вверху статьи.
Откройте страницу индекса Baidu и смоделируйте вход
Здесь мы имитируем действия пользователя, шаг за шагом, нажимаем и вводим. Если вы не обрабатываете код подтверждения входа, обработка кода подтверждения является другой темой.Если вы вошли в Baidu на этом компьютере, вам обычно не нужен код подтверждения.
// 启动浏览器,
// headless参数如果设置为true,Puppeteer将在后台操作你Chromium,换言之你将看不到浏览器的操作过程
// 设为false则相反,会在你电脑上打开浏览器,显示浏览器每一操作。
const browser = await puppeteer.launch({headless:false});
const page = await browser.newPage();
// 打开百度指数
await page.goto(BAIDU_INDEX_URL);
// 模拟登陆
await page.click('...');
await page.waitForSelecto('...');
// 输入百度账号密码然后登录
await page.type('...','username');
await page.type('...','password');
await page.click('...');
await page.waitForNavigation();
console.log('✅ 登录成功');
Имитация перемещения мыши для получения необходимых данных
Вам нужно прокрутить страницу до области графика тренда, затем навести мышку на определенную дату, дождаться окончания запроса, во всплывающей подсказке отобразится значение, после чего сделать скриншот для сохранения картинки.
// 获取chart第一天的坐标
const position = await page.evaluate(() => {
const $image = document.querySelector('...');
const $area = document.querySelector('...');
const areaRect = $area.getBoundingClientRect();
const imageRect = $image.getBoundingClientRect();
// 滚动到图表可视化区域
window.scrollBy(0, areaRect.top);
return { x: imageRect.x, y: 200 };
});
// 移动鼠标,触发tooltip
await page.mouse.move(position.x, position.y);
await page.waitForSelector('...');
// 获取tooltip信息
const tooltipInfo = await page.evaluate(() => {
const $tooltip = document.querySelector('...');
const $title = $tooltip.querySelector('...');
const $value = $tooltip.querySelector('...');
const valueRect = $value.getBoundingClientRect();
const padding = 5;
return {
title: $title.textContent.split(' ')[0],
x: valueRect.x - padding,
y: valueRect.y,
width: valueRect.width + padding * 2,
height: valueRect.height
}
});
снимок экрана
Рассчитайте координаты значений, сделайте скриншоты и обрежьте изображения с помощью пар джимпов.
await page.screenshot({ path: imgPath });
// 对图片进行裁剪,只保留数字部分
const img = await jimp.read(imgPath);
await img.crop(tooltipInfo.x, tooltipInfo.y, tooltipInfo.width, tooltipInfo.height);
// 将图片放大一些,识别准确率会有提升
await img.scale(5);
await img.write(imgPath);
Идентификация изображения
Здесь мы используем Tesseract для распознавания изображений Tesseracts — это инструмент OCR с открытым исходным кодом от Google, который используется для распознавания текста на изображениях и может повысить точность путем обучения. На github уже есть простая обёртка узла:node-tesseract, требует, чтобы вы сначала установили Tesseract и установили его в переменную среды.
Tesseract.process(imgPath, (err, val) => {
if (err || val == null) {
console.error('❌ 识别失败:' + imgPath);
return;
}
console.log(val);
На самом деле, необученные тессеракты будут иметь несколько ошибок в распознавании, например, распознавать числа, начинающиеся с 9, как `3. Здесь необходимо повысить точность тессерактов путем обучения. Если проблемы в процессе распознавания одинаковы, эти проблемы могут быть исправлены просто регулярным выражением.
упаковка
После того, как вышеперечисленные пункты будут реализованы, его можно будет упаковать в библиотеку узлов обходчика индексов Baidu, только объединив их. Конечно, есть много методов оптимизации, таких как пакетное сканирование, сканирование по заданным дням и т. д., пока это реализовано на этой основе, это не сложно.
const recognition = require('./src/recognition');
const Spider = require('./src/spider');
module.exports = {
async run (word, options, puppeteerOptions = { headless: true }) {
const spider = new Spider({
imgDir,
...options
}, puppeteerOptions);
// 抓取数据
await spider.run(word);
// 读取抓取到的截图,做图像识别
const wordDir = path.resolve(imgDir, word);
const imgNames = fs.readdirSync(wordDir);
const result = [];
imgNames = imgNames.filter(item => path.extname(item) === '.png');
for (let i = 0; i < imgNames.length; i++) {
const imgPath = path.resolve(wordDir, imgNames[i]);
const val = await recognition.run(imgPath);
result.push(val);
}
return result;
}
}
Анти рептилия
Наконец, как противостоять такому краулеру, я лично думаю, что это может быть способ судить о траектории движения мыши. Конечно, не существует стопроцентного метода защиты от рептилий на переднем конце, все, что мы можем сделать, это добавить немного больше сложности краулерам.