はじめに
この記事はUdon Advent Calendar 2025 - Adventarの2日目の記事です。
スクレイピングとは
みなさんは「スクレイピング」というものをご存じでしょうか。
スクレイピングとは、「Webサイトなどから必要な情報を抽出する」という意味です。似た言葉に「クローリング」がありますが、これは「Webサイトを巡回して情報を収集する」という意味です。
Webサイトの情報から必要なものを抜き出し、その他不必要な情報は削る、ということが特徴です。
用途
今の時代、刻々とデータはインターネット上を流れ蓄積されています。
こういったデータはいわば宝の山です。適切に収集し、成型することで多大な利益を得ることができます。
例えば、昨今ではAIの学習のために大量のデータが必要となっています。自前で学習データを用意すると偏ってしまいますが、スクレイピングを用いるとインターネット上から広くそして効率的にデータを集めてくることができます。
集めたデータはデータベースなどに蓄積され、文字通り企業や組織の財産になります。
スクレイピングの流れ
スクレイピングは主に以下のような流れで行います。
- 目的のサイトを決める
- サイトに適切なリクエストを送る
- サイトからレスポンスを受け取る
- そのレスポンスを解析し、扱いやすい形に整える
- 必要なデータを抜き出す
- データを記録する
といった感じです。
詳しい説明は省きますが、簡単に言うと、ブラウザで我々が見ているWebサイトは「指定したURLのサーバーにリクエストを送り、レスポンスとして返って来たファイルをブラウザが解釈しているもの」なのです。一度受け取ったファイルはブラウザにキャッシュされるので、急にネットワークが切れてもしばらくはページが読めるわけです。
つまり、通信によってデータファイルがやり取りされているわけです。要はこのデータファイルを解析するのがスクレイピングなわけですね。
今思いつきましたが、スクレイピングは魚釣りに似ていますね。
インターネットという海から適切な漁の方法でデータの魚を釣り上げ、捌き、必要なおいしい部分を取り出し、食べるという感じです。一見要らなさそうな内臓や鱗など(削った情報)もどこかで使われるかもしれませんね。食べるだけでなく、貯蔵する(データベースに保管する)ということもあります。
注意点
スクレイピングは非常に重要な技術ですが、もちろん使い方を誤ると恐ろしいことになります。
スクレイピングにより自動的かつ高速にサービスとの通信を行い、大量のデータをやり取りすることができるわけですが、1秒当たり何万もリクエストを送る事もできてしまいます。そんなことをすると、スクレイピング先のサーバーに多大な負荷をかけてしまいます。一歩間違えればサイバー攻撃となってしまうでしょう。
そのため、リクエストを送る前にはsleep 1などを入れることが推奨されます。これにより連続リクエストを避けることができ、相手側のサーバーの負担を減らせます。
スクレイピングを禁止しているサービスもかなりあります。例えば、Twitter(現X)は規約で明示的に無断スクレイピングを禁止しています。これを無視してスクレイピングを行うと法的措置を取られる可能性すらあります。
こういったサイトからデータを収集する場合は、サービスが提供するAPIなどを利用することとなります(有料の場合が多い)。
スクレイピングの方法
注意点こそありますが、スクレイピングはかなり需要の高い技術で、ルールさえ守れば強力なツールとなります。といったわけで、各プログラミング言語にはスクレイピングに必要なライブラリが公開されています。
今回は例としてhttps://example.com/ を使います。このサイトは明示的に「テストで使ってよい」とされているのでありがたく利用させていただきましょう。
今回はHTTP通信を用いたスクレイピングをしてみます。この通信は「ハイパーテキスト」、簡単に言うとHTMLをやり取りする通信です。
これによってWebページを構成するHTMLを取得し、その中の情報を抜き出そうというわけです。
Python
requestとBeautifulSoupが該当するライブラリです。
前者が指定したURLを元に通信を行い、後者はレスポンスとして受け取ったHTML情報を解析します。
https://example.com/ からh1タグの内容を取得するサンプルを示します。
import time
import requests
from bs4 import BeautifulSoup
# リクエストを送り、レスポンスを受け取る
url = "https://example.com"
time.sleep(1) # 1秒待つ
response = requests.get(url)
html = response.text
# レスポンスを解析し情報を抽出する
soup = BeautifulSoup(html, "html.parser")
h1_content = soup.find("h1").text if soup.find("h1") else None
print(h1_content)
$ python3 scraping_sample.py
Example Domain
これで、上で説明したような流れをプログラム内で行うことができます。もちろん、リクエストを送信する直前にはsleepを入れます。
今回はやりませんが、requestに認証情報を渡し、ログイン情報などが必要なページにリクエストを送ることもできます。
Ruby
request相当のGemには標準のNet::HTTPがあります。これによって基本的なHTTP通信が可能です。
また、HTML解析のためにはnokogiriというGemがあります。これはBeautifulSoupに相当します。
先ほどと同様にhttps://example.com/ からh1タグの内容を取得するサンプルを示します。
require 'net/http'
require 'uri'
require 'nokogiri'
# リクエストを送り、レスポンスを受け取る
uri = URI.parse("https://example.com")
sleep 1 # 1秒待つ
response = Net::HTTP.get_response(uri)
html = response.body
# レスポンスを解析し情報を抽出する
doc = Nokogiri::HTML(html)
h1_content = doc.css('h1')&.text
puts h1_content
$ ruby scraping_sample.rb
Example Domain
cURL
cURLは通信先URLを指定し、さまざまな形式で通信を行うことができるコマンドです。
HTMLを受け取るだけなら以下のようなシンプルな形で書けます。
curl https://example.com/
結果は以下の通りです。HTMLが返ってきているのがわかると思います。
$ curl https://example.com/
<!doctype html><html lang="en"><head><title>Example Domain</title><meta name="viewport" content="width=device-width, initial-scale=1"><style>body{background:#eee;width:60vw;margin:15vh auto;font-family:system-ui,sans-serif}h1{font-size:1.5em}div{opacity:0.8}a:link,a:visited{color:#348}</style><body><div><h1>Example Domain</h1><p>This domain is for use in documentation examples without needing permission. Avoid use in operations.<p><a href="https://iana.org/domains/example">Learn more</a></div></body></html>
オプションも非常に充実しており、通信結果を別ファイルに保存する、なんてこともできます(通信内容が画像とか動画の時に便利)。
また、ヘッダ情報にCookieなどの認証情報を付加することができ、ログイン情報などが必要なサイトにもアクセスして情報を取得することができます。
このあたりの話は今回は省略しますが、ブラウザの開発者ツールの「copy as cURL」機能を利用すると以下のようなものをコピーできます。
curl 'https://example.com/' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
-H 'accept-language: ja,en;q=0.9,en-GB;q=0.8,en-US;q=0.7' \
-H 'cache-control: max-age=0' \
-H 'if-modified-since: Thu, 09 Oct 2025 16:42:02 GMT' \
-H 'if-none-match: "bc2473a18e003bdb249eba5ce893033f:1760028122.592274"' \
-H 'priority: u=0, i' \
-H 'referer: https://www.google.com/' \
-H 'sec-ch-ua: "Chromium";v="142", "Microsoft Edge";v="142", "Not_A Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
-H 'sec-fetch-dest: document' \
-H 'sec-fetch-mode: navigate' \
-H 'sec-fetch-site: cross-site' \
-H 'sec-fetch-user: ?1' \
-H 'upgrade-insecure-requests: 1' \
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0'
これにより、自分が実際にブラウザで行っている通信を再現することができます。認証情報が付加されているので、ただcurlコマンドを実行するだけでは取得できないようなレスポンスを取得することもできます。どういったヘッダ情報が利用されているのかな、ということを確認することにも使えますね。
詳しくは以下のページなどを参考にしてみてください。
- https://qiita.com/tana0422/items/8e3d36b54638df7f6a4c
- https://qiita.com/ueokande/items/a580e9d9f17dbf82f382
- https://rooter.jp/web-crawling/fetch-curl-command-with-chrome-devtools/
cURLはかなり小回りが利くので、各プログラミング言語の通信用ライブラリの代わりにこれを外部呼び出ししてレスポンスを受け取り、それの解析はライブラリでやる、なんてこともよくあります。
おわりに
この記事を通して皆さんのスクレイピングに関する知識が深まれば幸いです。ルールを守って楽しくスクレイピングライフを送りましょう!
それではまた、明日の記事でお会いしましょう。