💪

Beautiful SoupでJava Scriptベースのサイトをスクレイピングしたい子のための一つのアイデァ

2022/08/18に公開
1

モチベーション

Pythonベースで Beautiful Soupでコードを書くと比較的コンパクトにかつ解析が楽ちんです。ただ、Java Scriptを駆動させないと描写してくれないサイトでは辛い。私は、複数のサイトを一つのグループとして取得するために、解析はBeautiful Soupで統一したく、今回の構成を作成しました。

プログラム構成

データー取得の箇所にて Java Scriptベースかサーバーでhtmlを作成してくれている Beautiful Soupでサクッと取得できるかで分岐をします。 Java Scriptで描写するサイトは、puppeteer を使いますが、ページを丸々取得してしまうだけにとどめます。解析は Beautiful Soupで統一します。

Java Scriptベースのサイト用の取得コード

fetch_html.js

const { argv, exit } = require('process');
const puppeteer = require('puppeteer');
const fs = require('fs');
var headlessModeFlag = true;

if (argv.length < 3) {
  console.log('require url argument');
  exit();
}
const url = process.argv[2];

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await Promise.all([
    page.waitForNavigation({ waitUntil: 'networkidle2'}),
    page.goto(url),
  ]);
  const html = await page.content();
  console.log(html);
  await browser.close();
})();

node側のライブラリーとして puppeteerだけインストールしておいてくださいね。

でこれをpython側で呼ぶコードはこちら。実際に運用しているコードです。


def get_html_by_pupeteer(url):
    cmd = []
    cmd.append("node")
    cmd.append("fetch_html.js")
    cmd.append(url)
    res = subprocess.run(cmd, stdout=subprocess.PIPE)
    return res.stdout.decode("utf-8")

url ="https://hoge.com"

if is_js_base_site:
    html = get_html_by_pupeteer(url)
else:
    html = requests.get(url).text

soup = BeautifulSoup(html, 'html.parser')

取得サイトごとに取得方法を振り分けています。pupeteerで取得したものは標準出力に出すようにしておいて、それをPIPEでpython側で受けるようにしました。多少の加工をしてデータを最終的にはBeautifulSoupに戻してあげて、Pythonでつくった楽ちん解析にかけるだけです。

エンジョイ!

Discussion