3
2

More than 1 year has passed since last update.

【pychrome】高度にヒューマンライクなbotを作る

Last updated at Posted at 2022-05-11

SeleniumはBOTだとバレている

Seleniumやpupeteer始めとしたブラウザの自動操縦ライブラリはたくさんありますが、
大手CDNを利用しているサイトやスクレイピング対策を頑張っているサイトだと簡単に
アクセスが拒否されてしまいます。

Google Chromeでは

chromeのDevTools上で

navigator.webdriver;

を実行してみてください。

webdriverで実行しているわけではないのでfalse が返ってきます。

Seleniumでは

今度はSeleniumで同じ値を見てみましょう。以下を実行すると

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.google.com/')
is_driver = driver.execute_script("return navigator.webdriver;")
print(is_driver)
driver.quit()
true

が出力されます。botだとバレています。

pychromeを使う

先の例から、普段使っているGoogle Chromeを操作できれば良さそうなので、
pychromeというPythonプログラミングからChromeを操作するライブラリを使います。

Google Chromeを起動する

pychromeを使うにはdebugging-portを指定してChromeを起動しておく必要があります。

linuxの場合

google-chrome --headless --disable-gpu --remote-debugging-port=9222 --no-sandbox

macOSの場合

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-gpu --remote-debugging-port=9222 --no-sandbox

とする必要があります。

注意

headlessモードで起動した場合、UserAgentに

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/99.0.4844.51 Safari/537.36

Headlessの文字が含まれています。厳し目のサイトではここの値をチェックされ得るので注意が必要です。
Chromeの起動時に安全なUserAgentを指定して上げましょう。

google-chrome --user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36" --headless --disable-gpu --no-sandbox

--blink-settings=imagesEnabled=falseオプションもおすすめです。
画像の読み込みがなくなるため、ページの読み込みがかなり速くなります。
スクリーンショットを取りたい場合以外は積極的に使いたいです。

サンプルプログラム

適当なURLにアクセスしてHTMLの取得と、画面をPDFとして出力して見ます。
debugging-portを指定してChromeが起動されている必要があります。

import sys
import time
import base64
import pychrome

browser = pychrome.Browser(url="http://127.0.0.1:9222")
tab = browser.new_tab()
tab.start()
tab.Network.enable()

url = 'https://www.youtube.com/'
try:
    tab.Page.navigate(url=url, _timeout=7)
except pychrome.exceptions.TimeoutException as e:
    print(e)
    sys.exit()

# javascriptが以下のように実行できます
time.sleep(1)
res = tab.Runtime.evaluate(expression='document.querySelector("html").outerHTML;')
html = res['result']['value']

# pdf出力
pdf_content = tab.Page.printToPDF()
with open('sample.pdf', 'wb') as f:
    data = pdf_content['data']
    f.write(base64.b64decode(data))

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2