ホームページ  >  記事  >  ウェブフロントエンド  >  Puppeteer 画像認識テクノロジーを使用して Baidu インデックス クローラーを実装する方法

Puppeteer 画像認識テクノロジーを使用して Baidu インデックス クローラーを実装する方法

亚连
亚连オリジナル
2018-06-05 15:18:233018ブラウズ

この記事では、Node Puppeteer 画像認識を使用して Baidu インデックス クローラーを実装する例を主に紹介します。編集者はそれが非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう

以前、さまざまな大手メーカーのフロントエンドのクロール対策技術を紹介した啓発的な記事を読みましたが、この記事にあるように、100% のクロール対策方法はありません。記事 これらのフロントエンドのクローラー対策メソッドをすべてバイパスする簡単な方法を紹介します。

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

注: クローラーを悪用しないでください。

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

Baidu Index のインターフェイスを観察すると、特定の日にマウスを置くと、2 つのリクエストがトリガーされます。結果はフローティング ボックスに表示されます:

一般的な考え方に従って、まずこのリクエストの内容を見てみましょう:

リクエスト 1:

リクエスト 2:

Baidu Index が実際にフロントエンドのクローラー対策戦略に何らかの取り組みを行っていることがわかります。マウスがグラフ上に移動すると、2 つのリクエストがトリガーされ、1 つのリクエストは HTML を返し、もう 1 つのリクエストは生成された画像を返します。 html には実際の値は含まれていませんが、width と margin-left を設定することで、対応する文字が画像上に表示されます。さらに、リクエストパラメータには res や res1 など、シミュレート方法が不明なパラメータが含まれているため、従来のシミュレートされたリクエストや HTML クローリング方法を使用して Baidu Index データをクロールすることは困難です。

クローラーの考え

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

  1. ログインをシミュレートする

  2. インデックスページを開く

  3. 指定した日付にマウスを移動する

  4. リクエストが終了するのを待ち、数値部分の画像を傍受する

  5. 値を取得するための画像認識

  6. ステップ 3 から 5 をループして、各日付に対応する値を取得します

このメソッドは理論的にはあらゆる Web サイトのコンテンツをクロールできます。 次に、次のようにクローラ ステップを実装します。次のライブラリが使用されます:

  1. puppeteer ブラウザ操作をシミュレート

  2. node-tesseract tesseractパッケージ、画像認識に使用されます

  3. jimp 画像のトリミング

インストールPuppeteer 、ユーザー操作をシミュレートします

Puppeteer は、Google Chrome チームによって作成された 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' });

implementation

レイアウトをきれいに保つために、セレクターに関係するコードの部分のみを以下に示します。完全なコードについては、記事の上部にある github リポジトリを参照してください。

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

ここで行うのは、ユーザーの操作、クリックと入力を段階的にシミュレートすることです。ログイン認証コードを処理する必要はありません。認証コードの処理は別のトピックです。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(':white_check_mark: 登录成功');

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

ページをトレンドチャート領域までスクロールし、マウスを特定の日付に移動し、リクエストが終了するまで待ちます。ツールチップに値が表示されます。そしてスクリーンショットを撮って画像を保存します。

// 获取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-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%的反爬虫手段,我们能做的只是给爬虫增加一点难度。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在Node.js中使用cheerio制作简单的网页爬虫(详细教程)

在vue中如何实现父组件向子组件传递多个数据

在React中使用Native如何实现自定义下拉刷新上拉加载的列表

以上がPuppeteer 画像認識テクノロジーを使用して Baidu インデックス クローラーを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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