ホームページ >ウェブフロントエンド >jsチュートリアル >Baiduインデックスクローラー機能の実装方法

Baiduインデックスクローラー機能の実装方法

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-12 16:45:484691ブラウズ

今回は、Baidu インデックス クローラー機能の実装方法と、Baidu インデックス クローラー機能を実装するための notes について説明します。以下は実際的なケースです。見てみましょう。

以前、さまざまな大手メーカーのフロントエンドのクロール対策技術を紹介した想像力豊かな記事を読んだことがありますが、この記事で述べられているように、100% のクロール対策方法は存在しません。この記事では、これらすべてのフロントエンドを回避する簡単な方法を紹介します。クローラー対策終了。

次のコードは、Baidu Index を例として取り上げており、コードは Baidu Index クローラー ノード ライブラリにパッケージ化されています: https://github.com/Coffcer/baidu-index-spider

注: クローラーを悪用して他人に迷惑をかけないでください

Baidu Index のクローラー対策戦略

Baidu Index のインターフェイスを観察してください。インデックス データはトレンド チャートです。マウスを特定の日に置くと、2 つのリクエストがトリガーされ、結果がフローティング ボックスに表示されます。 Baidu Index が実際にフロントエンドに特定のクローラー対策戦略を実装していることがわかります。マウスがグラフ上に移動すると、2 つのリクエストがトリガーされ、1 つのリクエストは HTML を返し、もう 1 つのリクエストは生成された画像を返します。 HTML には実際の値は含まれていませんが、width と

margin-left

を設定することで、画像上に対応する文字が表示されます。さらに、リクエストパラメータには、シミュレーション方法がわからないresやres1などのパラメータが含まれているため、従来のシミュレートされたリクエストやHTMLクローリング方法を使用してBaidu Indexデータをクロールすることは困難です。

クローラーのアイデア

Baidu のクローラー対策方法を突破する方法は実際には非常に簡単です。クローラー対策方法については気にしないでください。ユーザーの操作をシミュレートし、必要な値をスクリーンショットし、画像認識を行うだけで済みます。手順は大まかに次のとおりです:

    模擬ログイン
  1. インデックスページを開きます
  2. 指定した日付にマウスを移動します
  3. リクエストが終了するのを待って、画像の数値部分をキャプチャします
  4. 画像認識が価値を得る
  5. ステップ 3 ~ 5 をループして、各日付に対応する値を取得します
  6. この方法では、理論的にはあらゆる Web サイトのコンテンツをクロールできます。次に、次のライブラリを段階的に実装します。
人形遣い

ブラウザ操作をシミュレートします

  1. node-tesseract 画像認識に使用されるtesseractのパッケージ

  2. jimp 画像のトリミング

  3. Puppeteer をインストールしてユーザー操作をシミュレートする

  4. Puppeteer は、Google Chrome チームによって作成された Chrome 自動化ツールで、Chrome の実行コマンドを制御するために使用されます。ユーザー操作をシミュレートしたり、自動テストやクローラーなどを実行したりできます。使い方はとても簡単です。この記事を読めば使い方がわかると思います。

API ドキュメント: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md インストール:

rree

Puppeteer はインストール中に Chromium を自動的にダウンロードし、正しく動作することを確認します。ただし、国内ネットワークでは Chromium を正常にダウンロードできない場合があります。ダウンロードに失敗した場合は、cnpm を使用してインストールするか、ダウンロード アドレスを Taobao ミラーに変更してからインストールしてください:

npm install --save puppeteer

インストール中に Chromium のダウンロードをスキップし、コードでネイティブ Chrome パスを指定して実行することもできます:

npm config set PUPPETEER_DOWNLOAD_HOST=https://npm.taobao.org/mirrors
npm install --save puppeteer

達成しました

レイアウトをわかりやすくするために、主要な部分のみを以下にリストします。セレクターに関係するコードの部分は次のように置き換えられます。完全なコードについては、記事の上部にある github リポジトリを参照してください。

Baidu Index ページを開いてログインをシミュレートします

ここで行われるのは、ユーザーの操作、クリックと入力を段階的にシミュレートすることです。ログイン

認証コード

を処理する必要はありません。Baidu にローカルでログインしている場合は、通常、認証コードの処理は必要ありません。 りー

マウスの動きをシミュレートし、必要なデータを取得します

需要将页面滚动到趋势图的区域,然后移动鼠标到某个日期上,等待请求结束,tooltip显示数值,再截图保存图片。

// 获取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
 }
});

截图

计算数值的坐标,截图并用jimp对裁剪图片。

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是Google开源的一款OCR工具,用来识别图片中的文字,并且可以通过训练提高准确率。github上已经有一个简单的node封装: node-tesseract ,需要你先安装Tesseract并设置到环境变量。

Tesseract.process(imgPath, (err, val) => {
if (err || val == null) {
 console.error(':x: 识别失败:' + imgPath);
 return;
}
console.log(val);

实际上未经训练的Tesseracts识别起来会有少数几个错误,比如把9开头的数字识别成`3,这里需要通过训练去提升Tesseracts的准确率,如果识别过程出现的问题都是一样的,也可以简单通过正则去修复这些问题。

封装

实现了以上几点后,只需组合起来就可以封装成一个百度指数爬虫node库。当然还有许多优化的方法,比如批量爬取,指定天数爬取等,只要在这个基础上实现都不难了。

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;
 }
}

反爬虫

最后,如何抵挡这种爬虫呢,个人认为通过判断鼠标移动轨迹可能是一种方法。当然前端没有100%的反爬虫手段,我们能做的只是给爬虫增加一点难度。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

easyui日期时间框在IE中的兼容性如何处理

vue判断input输入内容有否有空格

以上がBaiduインデックスクローラー機能の実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。