スクレイピングされたくないですよね。そういう人は多いかと思います。ましてやコンテンツを根こそぎ抜かれて、文章微妙に改変されて記事アップなんて、数年前DeNAのキュレーションサイトで問題になったやつのように。記事作りのバイトへのやらせ方など醜すぎて、よくあんな事やらせていたなと・・・あれが大問題にならなければ、スクレイピング合戦が始まりそれはそれで面白かったかもしれませんが、可哀そうなのは元記事を書いた人ですね。
とは言え筆者もスクレイピングしたいのが本音。バイトは使いませんが記事を参考にします。さすがにあそこまで醜いコピペはしません。自分でも動くか実際にコード書いて確かめるし。
1. 基本、navigator.webdriver変数がセットされる
Selenium含め、WebDriver使うとnavigator.webdriver=trueがセットされます。
なので、もし自分のサイトがスクレイピングなどされたくない場合はヤフーや(優しい人)、もっと悪質なサイト(ある人はxvideos.comにしていた)に飛ばしてしまいましょう。
<script>
if( navigator.webdriver == true ){
location.href = “https://cfautog.tokyo”;
}
</script>
2. puppeteerではnavigator.webdriverを消せる
puppeteerだと削除することが出来ます。
なので、今後クローラーは更に増加すると思うので、各サイトクローラー対策されていくことを見越すと、puppeteerでやるのがいいかもしれませんね。
というわけで、今回はDockerでpuppeteerを動かすのをメインに試してみます。
3. Dockerでpuppeteerを動かして試す
というわけで、Dockerでpuppeteerを動かして試してみます。
3.1 Dockerfile
puppeteerのTroubleshooting Running on Alpineを見てDockerfile作成します。まんまコピペ。
FROM alpine:latest RUN apk add --no-cache \ chromium \ nss \ freetype \ freetype-dev \ harfbuzz \ ca-certificates \ ttf-freefont \ nodejs \ yarn \ font-noto-cjk \ unifont ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true RUN yarn add puppeteer # Add user so we don't need --no-sandbox. RUN addgroup -S pptruser && adduser -S -g pptruser pptruser \ && mkdir -p /home/pptruser/Downloads /app \ && chown -R pptruser:pptruser /home/pptruser \ && chown -R pptruser:pptruser /app # Run everything after as non-privileged user. USER pptruser ################################################################################# # WORKDIR /app CMD ["sh"]
3.2 docker-compose.yml
適当にググって書きます。
version: '3.3' services: puppeteer: container_name: puppeteer privileged: true build: puppeteer volumes: - ./app:/app ports: - 8100:3000 tty: true
3.3 docker-compose build, up -dしておく
docker-compose build, docker-compose up -dして起動しておきます。
3.4 app/test.js
app/test.jsを作り、下記作成。
const puppeteer = require('puppeteer'); (async() => { const browser = await puppeteer.launch({ executablePath: '/usr/bin/chromium-browser', args: ['--no-sandbox'] }); const page = await browser.newPage(); await page.evaluateOnNewDocument(() => { // Object.defineProperty(navigator, 'webdriver', ()=>{}); // delete navigator.__proto__.webdriver; }); await page.goto('あなたのサイト'); await page.waitFor(2000); await page.screenshot({path: 'ttt.png'}); browser.close(); })();
3.5 サイトのhtmlにnavigator.webdriverチェック入れる
下記を入れます。
<script> if( navigator.webdriver == true ){ location.href = "https://cfautog.tokyo"; } </script>
3.6 test.jsを実行
docker exec で入り、node test.jsを実行
docker exec -it puppeteer /bin/sh
/app $ node app.js
で数秒後にttt.pngというファイルが出来ています。
まずは、navigator.webdriver変数がセットされているので、本サイトトップがスクショされています。
3.7 navigator.webdriverを削除する
3.4にあるtest.jsのコメントアウトをはずして有効にしましょう。
そしてtest.jsを実行すると、今度はあなたの指定したサイトがスクショされています。
puppeteerで起動したChromiumブラウザにnavigator.webdriverがセットされていない為です。
これで、とりあえずはwebdriverで操作していないように見せることが出来ます。
4. google search console系のクローラーは?
webdriver=trueなら弾くのはいいのですが、クローラー(googlebotというらしい)まで弾くとインデックス登録してくれません。googleやbingのクローラーにwebdriverがセットされているかはググっても見つけることが出来ませんでした。ユーザーエージェントで判定して、botでなければwebdriver判定するのがいいかもですね。

9. 参考サイト
puppeteer webdriver変数を削除

puppeteer running-puppeteer-in-docker
コメント