💪
Beautiful SoupでJava Scriptベースのサイトをスクレイピングしたい子のための一つのアイデァ
モチベーション
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