ブログ
【PHP】ウェブスクレイピング
こんにちは!T.Uです!
今回はPHPでウェブスクレイピングをする話です。
Pythonの場合
ウェブスクレイピングといえば、Pythonがよく知られています。
Pythonには、Beautiful SoupやSeleniumといった強力なライブラリがあります。
Beautiful Soupはシンプルな構文で要素を検索し、データを抽出することができるライブラリです。
例えば、Beautiful Soupで弊社のお知らせ一覧からタイトルとURLを取得し、Consoleに出力する場合、以下のようなコードになります。
import requests
from bs4 import BeautifulSoup
# URLのHTMLを取得する
response = requests.get('https://wingdoor.co.jp/news/')
# HTMLをもとに、BeautifulSoup オブジェクトを作成する
soup = BeautifulSoup(response.text, 'html.parser')
# 記事の一覧を取得する
posts = soup.select('.blogBox li a')
for post in posts:
# 記事のタイトルを取得する
post_title = post.select_one('.postTtl').get_text().strip()
# 記事のURLを取得する
post_url = post.get('href')
print(post_title)
print(post_url)
PHPの場合
PHPでスクレイピングをする場合も、kub-at/php-simple-html-dom-parserやpaquettg/php-html-parserなどのライブラリを使う方法があります。しかし、PHPではライブラリを追加することなく、DOMDocumentとDOMXPathを使うことで、HTMLの解析やデータの抽出を行うことができます。
<?php
// スクレイピング対象のURL
$url = 'https://wingdoor.co.jp/news/';
// HTMLを取得する
$html = file_get_contents($url);
// DOMDocumentオブジェクトを作成して、HTMLを読み込む
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
// DOMXPathオブジェクトを作成する
$xpath = new DOMXPath($dom);
// 記事の一覧を取得する
$posts = $xpath->query('//ul[contains(@class, "blogBox")]//li/a');
foreach ($posts as $post) {
// 記事のタイトルを取得する
$post_title = $xpath
->evaluate('string(.//p[contains(@class, "postTtl")])', $post);
// 記事のURLを取得する
$post_url = $xpath->evaluate('string(.//@href)', $post);
echo trim($post_title) . PHP_EOL;
echo $post_url . PHP_EOL;
}
DOMDocumentの作成とHTMLの読み込み
ここでは、DOMDocument オブジェクトを作成し、HTMLをロードします。libxml_use_internal_errors(true)
はHTMLの解析時に発生する可能性のある警告やエラーを抑制するために使用します。
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
記事の一覧を取得
この部分では、DOMXPath
オブジェクトを作成します。DOMXPath
を使用することで、XPathを指定して、特定のHTML要素を検索することができるようになります。
$xpath = new DOMXPath($dom);
$posts = $xpath->query('//ul[contains(@class, "blogBox")]//li/a');
記事のタイトルとURLの取得および出力
この部分では、evaluate()メソッドでXPathを使用して、記事のタイトルとURLを取得します。
// 記事のタイトルを取得する
$post_title = $xpath
->evaluate('string(.//p[contains(@class, "postTtl")])', $post);
// 記事のURLを取得する
$post_url = $xpath->evaluate('string(.//@href)', $post);
また、以下のように書くこともできます。
// 記事のタイトルを取得する
$post_title = $xpath
->query('.//p[contains(@class, "postTtl")]', $post)
->item(0)
->nodeValue;
// 記事のURLを取得する
$post_url = $post->getAttribute('href');
PHP 8.4の場合
今までのDOMDocument
クラスはHTML4までサポートが中心で、HTML5の構文を正しく扱うことができませんでした。
PHP 8.4からは、DOM\HTMLDocument
クラスが追加され、HTML5の構文を正しく扱うことができるようになるようです。
PHP 8.4 正式版のリリースは11月21日に予定されており、リリースがとても待ち遠しいです!
参考:DOMDocument::loadHTML
参考:PHP RFC: DOM HTML5 parsing and serialization
スクレイピングによって対象サーバーに過度の負荷をかけないようにし、リクエストの間隔を適切に設けるなどの配慮が必要です。
また、ウェブサイトによってはスクレイピングが禁止されている場合があります。対象サイトの利用規約を必ず確認し、遵守しましょう。
株式会社ウイングドアは福岡のシステム開発会社です。
現在、私達と一緒に"楽しく仕事が出来る仲間"として、新卒・中途採用を絶賛募集しています!
ウイングドアの仲間達となら楽しく仕事できるかも?と興味をもった方、
お気軽にお問い合わせ下さい!