PythonでGoogleマップをスクレイピングする方法

セットアップから結果のエクスポートまで、PythonでGoogleマップをスクレイピングする方法を学び、Bright DataのAPIを使用して高度な課題に取り組んでみましょう。
9 分読
How to Scrape Google Maps With Python blog image

このチュートリアルでは以下について説明します。

  • Googleマップスクレイパーの定義
  • それを使って抽出できるデータ
  • PythonでGoogleマップのスクレイピングスクリプトを作成する方法

さっそく始めましょう!

Googleマップスクレイパーとは?

Googleマップスクレイパーは、Googleマップからデータを抽出するための専用ツールです。たとえばPythonスクレイピングスクリプトを使用して、マップデータを収集するプロセスを自動化します。このようなスクレイパーで取得したデータは、一般的に市場調査や競合分析などに使用されます。

Googleマップから取得できるデータ

Googleマップから取得できる情報には次のものが含まれます。

  • ビジネスの名称:Googleマップに掲載されている事業者またはロケーションの名前。
  • 住所:事業者またはロケーションの実際の住所。
  • 電話番号:事業者の連絡先電話番号。
  • Webサイト:事業者のWebサイトのURL。
  • 営業時間:営業時間の開始時刻と終了時刻。
  • レビュー:評価や詳細なフィードバックを含むカスタマーレビュー。
  • 評価:ユーザーフィードバックに基づく平均星評価。
  • 写真:事業者または顧客がアップロードした画像。

PythonでGoogleマップをスクレイピングする方法

このガイド付きセクションでは、GoogleマップをスクレイピングするためのPythonスクリプトの作成方法を学びます。

最終目標は、「イタリアンレストラン」ページのGoogleマップアイテムに含まれるデータを取得することです。

以下の手順に従ってください!

ステップ1:プロジェクトを準備する

始める前に、マシンにPython 3がインストールされていることを確認する必要があります。されていない場合は、それをダウンロードしてインストールし、インストールウィザードに従ってください。

その後、次のコマンドを使用してプロジェクト用のフォルダを作成して、そのフォルダに移動し、その中に仮想環境を作成します。

mkdir google-maps-scraper
cd google-maps-scraper
python -m venv env

google-maps-scraperディクショナリは、Python Googleマップスクレイパーのプロジェクトフォルダを表しています。

お好みのPython IDEにプロジェクトフォルダを読み込みます。PyCharm Community EditionまたはPython拡張機能を入れたVisual Studio CodeがあればOKです。

プロジェクトフォルダ内にscraper.pyファイルを作成します。これがこのプロジェクトの現在のファイル構造です。

scraper.pyは現在は空白のPythonスクリプトですが、まもなくスクレイピングロジックが含まれるようになります。

IDEのターミナルで、仮想環境を有効にします。そのためには、LinuxまたはmacOSで以下のコマンドを実行してください。

./env/bin/activate

または、Windowsでは以下を実行してください。

env/Scripts/activate

これでスクレイパー向けのPython環境が整いました!

ステップ2:スクレイピングライブラリを選択する

Googleマップは非常にインタラクティブなプラットフォームであるため、静的サイトか動的サイトかを判断するために時間を費やすのは無意味です。こうした場合、ベストなスクレイピングの方法はブラウザ自動化ツールを使用することです。

このテクノロジーに詳しくない場合は、ブラウザ自動化ツールを使用すると、制御可能なブラウザ環境でWebページのレンダリングや操作を行うことができます。さらに、有効なGoogleマップ検索URLを作成するのは簡単ではありません。この問題を解決する最も簡単な方法は、ブラウザで直接検索を実行することです。

Python向けの最良のブラウザ自動化ツールの1つはSeleniumで、Googleマップをスクレイピングするのに理想的な選択肢です。このタスクで使用する主なライブラリとなるので、インストールする準備をしておいてください!

ステップ3:スクレイピングライブラリのインストールと構成

アクティブなPython仮想環境で、次のコマンドでseleniumpipパッケージを使用してSeleniumをインストールします。

pip install selenium

このツールの使用方法の詳細については、Seleniumを使用したWebスクレイピングに関するチュートリアルに従ってください。

Seleniumをscraper.pyにインポートし、Chromeインスタンスをヘッドレスモードで制御するためにWebDriverオブジェクトを作成します。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

# to launch Chrome in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# create a Chrome web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

上記のスニペットは、Chromeのブラウザウィンドウをプログラムで制御するためにChrome WebDriverインスタンスを初期化します。--headlessフラグはChromeをヘッドレスモードで起動するためのオプションです。ヘッドレスモードでは、Chromeはバックグラウンドで起動し、ウィンドウは表示されません。デバッグ時には、この行をコメントアウトしてスクリプトのアクションをリアルタイムで確認できます。

Googleマップのスクレイピングスクリプトの最後の行では、忘れずにWebドライバを閉じてください。

driver.quit()

できました!これで、Googleマップページのスクレイピングを始めるための構成が完了しました。

ステップ4:対象のページに接続する

get()メソッドを使用してGoogleマップのホームページに接続します。

driver.get("https://www.google.com/maps")

今のところ、scraper.pyには次の行が含まれています。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

# to launch Chrome in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# create a Chrome web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

# connect to the Google Maps home page
driver.get("https://www.google.com/maps")

# scraping logic...

# close the web browser
driver.quit()

それでは、Googleマップのような動的Webサイトのスクレイピングを始めましょう。

ステップ5:GDPR(一般データ保護規則)クッキーダイアログへの対処

:EU(欧州連合)圏内にお住まいでない方は、このステップをスキップできます。

scraper.pyスクリプトをヘッドモードで実行し、可能であれば最後の行の前にブレークポイントを追加します。これにより、ブラウザウィンドウがすぐに閉じることなく、開いたままで観察できます。EU圏内にお住まいの場合は、以下のように表示されるはずです。

ヨーロッパにお住まいの場合のGDPRクッキーに関する通知

注:「Chromeは自動テストソフトウェアにより制御されています」というメッセージは、ChromeがSeleniumによって正常に制御されていることを確認するものです。

GDPR要件により、GoogleはEU圏内のユーザーにいくつかのクッキーポリシーオプションを表示する必要があります。これに該当する場合、ページの操作を行なうためには、この選択を処理する必要があります。該当しない場合は、ステップ6に進んでください。

ブラウザのアドレスバーのURLを見てみると、get()で指定されたページと一致していないことがわかります。その理由は、Googleがあなたをリダイレクトしたからです。[すべて承認]ボタンをクリックすると、対象となるページ、つまりGoogleマップのホームページに戻ります。

GDPRオプションを処理するには、Googleマップのホームページをブラウザでシークレットモードで開き、リダイレクトされるまでお待ちください。「すべて承認」ボタンを右クリックし、「調査」オプションを選択します。

お気づきかもしれませんが、ページ上のHTML要素のCSSクラスはランダムに生成されているように見えます。これは、それらがWebスクレイピングには不向きであることを示しています。というのも、それらは展開のたびに更新される可能性が高いからです。そのため、aria-labelのような、より安定した属性をターゲットに絞る必要があります。

accept_button = driver.find_element(By.CSS_SELECTOR, "[aria-label=\"Accept all\"]")

find_element()は、さまざまな戦略を用いてページ上のHTML要素を特定するために使用されるSeleniumのメソッドです。このケースでは、CSSセレクターを使用しました。さまざまなセレクタータイプについて詳しく知りたい場合は、「XPathとCSSセレクター」を参照してください。

このインポートをscraper.pyに追加してByをインポートすることをお忘れなく。

from selenium.webdriver.common.by import By

次の指示はボタンをクリックするよう指示しています。

accept_button.click()

以下は、オプションのGoogleクッキーページを処理するにあたり、すべての要素がどう連携しているかを示しています。

try:
     # select the "Accept all" button from the GDPR cookie option page
    accept_button = driver.find_element(By.CSS_SELECTOR, "[aria-label=\"Accept all\"]")
    # click it
    accept_button.click()
except NoSuchElementException:
    print("No GDPR requirenments")

click()コマンドで「すべて承認」ボタンを押すと、GoogleによりGoogleマップのホームページにリダイレクトされます。EU圏外にお住まいの場合、このボタンはページに表示されないため、NoSuchElementExceptionが発生します。これは重大なエラーではなく、潜在的なシナリオにすぎないため、スクリプトは例外をキャッチして処理を進めます。

必ずNoSuchElementExceptionをインポートしてください。

from selenium.common import NoSuchElementException

お疲れ様でした!これで、Googleマップのスクレイピングに集中するための準備ができました。

ステップ6:検索フォームを送信する

現在、Googleマップスクレイパーは、以下のようなページに到達しているはずです。

スクリプトでアクセスしたページ

Googleマップ上のロケーションは、IPのロケーションによって異なることに注意してください。この例では、所在地はニューヨークです。

次に、「Googleマップを検索」フィールドに入力し、検索フォームを送信してみましょう。この要素を見つけるには、ブラウザのシークレットモードでGoogleマップのホームページを開きます。検索入力フィールドを右クリックし、「調査」オプションを選択します。

search_input = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "#searchboxinput"))
)

WebDriverWaitは特殊なSeleniumクラスで、ページ上で指定された条件が満たされるまでスクリプトを一時停止します。上の例では、入力されたHTML要素が表示されるまで最大5秒待機します。この待機は、(リダイレクトを理由として)ステップ5に従った場合に必要となる、ページの完全な読み込みを保証します。

上記の行を機能させるには、これらのインポートをscraper.pyに追加してください。

from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC

Next, fill out the input with the `[send_keys()](https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/#send-keys)` method:

search_query = "italian restaurants"
search_input.send_keys(search_query)

この場合、「イタリアンレストラン」が検索クエリですが、他の用語でも検索できます。

あとはフォームを送信するだけです。虫めがねの形をした送信ボタンを調査します。

送信ボタンを調査中

送信ボタンのaria-label属性をターゲットにしてボタンを選択し、クリックしてください。

search_button = driver.find_element(By.CSS_SELECTOR, "button[aria-label=\"Search\"]")
search_button.click()

素晴らしい!これで、制御されたブラウザがスクレイピング対象のデータを読み込むようになります。

ステップ7:Googleマップアイテムを選択する

スクリプトは、現在以下の場所にあるはずです。

スクレイピング対象のデータは、左側のGoogleマップアイテムに含まれています。これはリストであるため、スクレイピングされたデータを格納するのに最適なデータ構造は配列です。1つを初期化:

items = []

ここでの目標は、左側のGoogleマップアイテムを選択することです。そのうちの1つを調査してください。

左側の商品の1つを調査中

繰り返しになりますが、CSSクラスはランダムに生成されているように見えるため、スクレイピングには適していません。代わりに、jsaction属性をターゲットにするといいでしょう。この属性のコンテンツの一部もランダムに生成されて表示されるので、その中の一貫した文字列、具体的には"mouseover:pane"に注目してください。

以下のXPathセレクタは、role="feed"であり、そのjsaction属性に"mouseover:pane"という文字列が含まれる親

内の、すべての

要素を選択するのに役立ちます。

maps_items = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.XPATH, '//div[@role="feed"]//div[contains(@jsaction, "mouseover:pane")]'))
)

繰り返しになりますが、左側のコンテンツは動的にページに読み込まれるため、WebDriverWaitが必要です。

各要素を繰り返し処理し、Googleマップスクレイパーでデータを抽出できるように準備します。

for maps_item in maps_items:
    # scraping logic...

素晴らしい!次のステップでは、これらの要素からデータを抽出します。

ステップ8:Googleマップのアイテムを削除する

Googleマップのアイテムを1つ調べて、その中の要素に注目してください。

1つのGoogleマップアイテムを調査中

ここでは、スクレイプできることが分かります。

  • [jsaction][jslog]要素からのGoogleマップアイテムのリンク
  • div.FontheadlinesMall要素からのタイトル
  • span[role="img"]からの星とレビューの数

これは以下のロジックで実現できます。

link_element = maps_item.find_element(By.CSS_SELECTOR, "a[jsaction][jslog]")
url = link_element.get_attribute("href")

title_element = maps_item.find_element(By.CSS_SELECTOR, "div.fontHeadlineSmall")
title = title_element.text

reviews_element = maps_item.find_element(By.CSS_SELECTOR, "span[role=\"img\"]")
reviews_string = reviews_element.get_attribute("aria-label")

# define a regular expression pattern to extract the stars and reviews count
reviews_string_pattern = r"(\d+\.\d+) stars (\d+[,]*\d+) Reviews"

# use re.match to find the matching groups
reviews_string_match = re.match(reviews_string_pattern, reviews_string)

reviews_stars = None
reviews_count = None

# if a match is found, extract the data
if reviews_string_match:
    # convert stars to float
    reviews_stars = float(reviews_string_match.group(1))
    # convert reviews count to integer
    reviews_count = int(reviews_string_match.group(2).replace(",", ""))

get_attribute()関数は指定されたHTML属性内のコンテンツを返し、.textはノード内の文字列コンテンツを返します。

“X.Y stars in Z reviews”という文字列から特定のデータフィールドを抽出するために、正規表現が使用されていることに注目してください。詳細については、「Webスクレイピングの正規表現」の使用についての記事を参照してください。

Python標準ライブラリから忘れずにreパッケージをインポートしてください。

import re

Googleマップアイテムを引き続き調査します。

Googleマップアイテム全体を調査しています

fondBodyMediumクラスを持つ

要素の内側では、属性を持たない、またはstyle属性のみを持つノードから、ほとんどの情報を取得できます。オプションの価格設定要素については、aria-label属性に“Price”を含むノードをターゲットにすることで選択できます。

info_div = maps_item.find_element(By.CSS_SELECTOR, ".fontBodyMedium")

# scrape the price, if present
try:
    price_element = info_div.find_element(By.XPATH, ".//*[@aria-label[contains(., 'Price')]]")
    price = price_element.text
except NoSuchElementException:
    price = None

info = []
# select all <span> elements with no attributes or the @style attribute
# and descendant of a <span>
span_elements = info_div.find_elements(By.XPATH, ".//span[not(@*) or @style][not(descendant::span)]")
for span_element in span_elements:
  info.append(span_element.text.replace("⋅", "").strip())

# to remove any duplicate info and empty strings
info = list(filter(None, list(set(info))))

価格要素はオプションなので、そのコードをtry...exceptブロックで囲む必要があります。これにより、価格ノードがページ上にない場合でも、スクリプトは失敗することなく続行されます。ステップ5をスキップする場合は、NoSuchElementExceptionのインポートを追加してください。

from selenium.common import NoSuchElementException

空の文字列や重複した情報要素を避けるため、filter()set()の使用に注意してください。

では、今度は画像にフォーカスを当てます。

画像の調査

次のコードでデータを抽出できます。

img_element = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "img[decoding=\"async\"][aria-hidden=\"true\"]"))
)
image = img_element.get_attribute("src")

画像は非同期で読み込まれ、表示されるまでに時間がかかる場合があるため、WebDriverWaitが必要であることに注意してください。

最後のステップは、最下部の要素のタグをスクレイピングすることです。

要素のタグをスクレイピング中

最後の.fontBodyMedium要素のstyle属性を持つノードから、それらすべてを取得できます。

tags_div = maps_item.find_elements(By.CSS_SELECTOR, ".fontBodyMedium")[-1]
tags = []
tag_elements = tags_div.find_elements(By.CSS_SELECTOR, "span[style]")
for tag_element in tag_elements:
  tags.append(tag_element.text)

お見事!PythonのGoogleマップスクレイピングロジックが完成しました。

ステップ9:スクレイピングされたデータを収集する

これで、いくつかの変数にスクレイピングしたデータが格納されました。新しいアイテムオブジェクトを作成し、そこにそのデータを入力します。

item = {
  "url": url,
  "image": image,
  "title": title,
  "reviews": {
    "stars": reviews_stars,
    "count": reviews_count
  },
  "price": price,
  "info": info,
  "tags": tags
}

次に、それをアイテム配列に追加します。

items.append(item)

Googleマップのアイテムノードのforループの終了時には、アイテムにすべてのスクレイピングデータが含まれます。その情報をCSVなどの人間が読めるファイルにエクスポートするだけで済みます。

ステップ10:CSVにエクスポートする

Python標準ライブラリからcsvパッケージをインポートします。

import csv

次に、これを使用してフラットなCSVファイルにGoogleマップデータを入力します。

# output CSV file path
output_file = "items.csv"

# flatten and export to CSV
with open(output_file, mode="w", newline="", encoding="utf-8") as csv_file:
    # define the CSV field names
    fieldnames = ["url", "image", "title", "reviews_stars", "reviews_count", "price", "info", "tags"]
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

    # write the header
    writer.writeheader()

    # write each item, flattening info and tags
    for item in items:
        writer.writerow({
            "url": item["url"],
            "image": item["image"],
            "title": item["title"],
            "reviews_stars": item["reviews"]["stars"],
            "reviews_count": item["reviews"]["count"],
            "price": item["price"],
            "info": "; ".join(item["info"]),  
            "tags": "; ".join(item["tags"])
        })

上記のスニペットはアイテムitems.csvという名前のCSVファイルにエクスポートします。使用されている主な関数は以下のとおりです。

  • open():指定されたファイルをUTF-8エンコーディングの書き込みモードで開き、テキスト出力を処理します。
  • csv.dictWriter():指定されたフィールド名を使用してCSVライターオブジェクトを作成すると、行をディクショナリとして書き込めるようになります。
  • writeheader():フィールド名に基づいてヘッダー行をCSVファイルに書き込みます。
  • writer.writerow():各項目をCSVに行として書き込みます。

join()文字列関数を使用して配列をフラット文字列に変換していることに注意してください。これにより、出力CSVはクリーンな単一レベルのファイルになります。

ステップ11:仕上げ

PythonのGoogleマップスクレイパーの最終コードは次のとおりです。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.common import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
import csv

# to launch Chrome in headless mode
options = Options()
options.add_argument("--headless") # comment it while developing

# create a Chrome web driver instance with the
# specified options
driver = webdriver.Chrome(
    service=Service(),
    options=options
)

# connect to the Google Maps home page
driver.get("https://www.google.com/maps")

# to deal with the option GDPR options
try:
     # select the "Accept all" button from the GDPR cookie option page
    accept_button = driver.find_element(By.CSS_SELECTOR, "[aria-label=\"Accept all\"]")
    # click it
    accept_button.click()
except NoSuchElementException:
    print("No GDPR requirenments")

# select the search input and fill it in
search_input = WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "#searchboxinput"))
)
search_query = "italian restaurants"
search_input.send_keys(search_query)

# submit the search form
search_button = driver.find_element(By.CSS_SELECTOR, "button[aria-label=\"Search\"]")
search_button.click()

# where to store the scraped data
items = []

# select the Google Maps items
maps_items = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.XPATH, '//div[@role="feed"]//div[contains(@jsaction, "mouseover:pane")]'))
)

# iterate over the Google Maps items and
# perform the scraping logic
for maps_item in maps_items:
    link_element = maps_item.find_element(By.CSS_SELECTOR, "a[jsaction][jslog]")
    url = link_element.get_attribute("href")

    title_element = maps_item.find_element(By.CSS_SELECTOR, "div.fontHeadlineSmall")
    title = title_element.text

    reviews_element = maps_item.find_element(By.CSS_SELECTOR, "span[role=\"img\"]")
    reviews_string = reviews_element.get_attribute("aria-label")

    # define a regular expression pattern to extract the stars and reviews count
    reviews_string_pattern = r"(\d+\.\d+) stars (\d+[,]*\d+) Reviews"

    # use re.match to find the matching groups
    reviews_string_match = re.match(reviews_string_pattern, reviews_string)

    reviews_stars = None
    reviews_count = None

    # if a match is found, extract the data
    if reviews_string_match:
        # convert stars to float
        reviews_stars = float(reviews_string_match.group(1))
        # convert reviews count to integer
        reviews_count = int(reviews_string_match.group(2).replace(",", ""))

    # select the Google Maps item <div> with most info
    # and extract data from it
    info_div = maps_item.find_element(By.CSS_SELECTOR, ".fontBodyMedium")

    # scrape the price, if present
    try:
        price_element = info_div.find_element(By.XPATH, ".//*[@aria-label[contains(., 'Price')]]")
        price = price_element.text
    except NoSuchElementException:
        price = None

    info = []
    # select all <span> elements with no attributes or the @style attribute
    # and descendant of a <span>
    span_elements = info_div.find_elements(By.XPATH, ".//span[not(@*) or @style][not(descendant::span)]")
    for span_element in span_elements:
      info.append(span_element.text.replace("⋅", "").strip())

    # to remove any duplicate info and empty strings
    info = list(filter(None, list(set(info))))

    img_element = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "img[decoding=\"async\"][aria-hidden=\"true\"]"))
    )
    image = img_element.get_attribute("src")

    # select the tag <div> element and extract data from it
    tags_div = maps_item.find_elements(By.CSS_SELECTOR, ".fontBodyMedium")[-1]
    tags = []
    tag_elements = tags_div.find_elements(By.CSS_SELECTOR, "span[style]")
    for tag_element in tag_elements:
      tags.append(tag_element.text)

    # populate a new item with the scraped data
    item = {
      "url": url,
      "image": image,
      "title": title,
      "reviews": {
        "stars": reviews_stars,
        "count": reviews_count
      },
      "price": price,
      "info": info,
      "tags": tags
    }
    # add it to the list of scraped data
    items.append(item)

# output CSV file path
output_file = "items.csv"

# flatten and export to CSV
with open(output_file, mode="w", newline="", encoding="utf-8") as csv_file:
    # define the CSV field names
    fieldnames = ["url", "image", "title", "reviews_stars", "reviews_count", "price", "info", "tags"]
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

    # write the header
    writer.writeheader()

    # write each item, flattening info and tags
    for item in items:
        writer.writerow({
            "url": item["url"],
            "image": item["image"],
            "title": item["title"],
            "reviews_stars": item["reviews"]["stars"],
            "reviews_count": item["reviews"]["count"],
            "price": item["price"],
            "info": "; ".join(item["info"]),
            "tags": "; ".join(item["tags"])
        })

# close the web browser
driver.quit()

約150行のコードで、Googleマップのスクレイピングスクリプトを作成できました。

scraper.pyファイルを起動して、正しく動作することを確認してください。Windowsでは、以下のコマンドでスクレイパーを起動します。

python scraper.py

同様に、LinuxまたはmacOSでは、以下を実行してください。

python3 scraper.py

スクレイパーの実行が終了するのを待つと、プロジェクトのルートディレクトリにitems.csvファイルが表示されます。ファイルを開いて抽出されたデータを表示します。このデータには次のようなデータが含まれているはずです。

最終結果を含むitems.csvファイル

おめでとうございます、ミッション完了です!

まとめ

このチュートリアルでは、Googleマップスクレイパーの概要とPythonでの作成方法を学びました。ここで見てきたように、Googleマップからデータを自動的に取得するシンプルなスクリプトを構築するには、Pythonコードを数行書くだけで済みます。

このソリューションは小規模なプロジェクトでは機能しますが、大規模なスクレイピングには実用的ではありません。Googleでは、ユーザーをブロックできるCAPTCHAやIP禁止などの高度なボット対策を講じています。プロセスを複数のページにまたがって拡張すると、インフラストラクチャのコストも増加します。さらに、この単純な例では、Googleマップページで必要な複雑な操作をすべて網羅しているわけではありません。

それはつまり、Googleを効率的かつ確実にスクレイピングすることは不可能だということでしょうか?そんなことはありません!必要なのはBright DataのGoogleマップスクレイパーAPIのような高度なソリューションだけです。

Google Maps Scraper APIは、Googleマップからデータを取得するためのエンドポイントを提供しており、主な課題をすべて解決します。簡単なAPI呼び出しで、必要なデータをJSONまたはHTML形式で取得できます。API呼び出しがお好みでない場合は、すぐに使えるGoogleマップデータセットもご覧ください。

今すぐ無料のBright Dataアカウントを作成して、スクレイパーAPIをお試しいただくか、当社のデータセットをじっくりご覧ください。

クレジットカードは必要ありません

あなたは下記にもご興味がおありかもしれません

web scraping with claude blog image
ウェブデータ

2025年のクロードによるウェブスクレイピング

Pythonを使ってWebスクレイピングを自動化し、構造化データを楽に抽出するClaude AIの使い方を学ぶ。
18 分読
Building AI-Ready Vector Datasets for LLMs blog image
AI

LLMのためのAI対応ベクトルデータセット構築:Bright Data、Google Gemini、Pineconeを使ったガイド

大規模言語モデル(LLM)は、私たちが情報にアクセスし、インテリジェントなアプリケーションを構築する方法を変革しています。LLMの可能性を最大限に引き出すには、特にドメイン固有の知識や独自のデータを使用する場合、高品質で構造化されたベクトルデータセットを作成することが重要です。LLMの性能と精度は、入力データの品質に直接結びついています。準備不足のデータセットは劣悪な結果をもたらす可能性があり、一方、十分にキュレーションされたデータセットはLLMを真のドメイン・エキスパートに変えることができます。 このガイドでは、AIに対応したベクターデータセットを生成するための自動パイプラインの構築方法を順を追って説明する。 課題:LLMのためのデータ収集と準備 LLMは膨大な汎用テキストコーパスで学習されますが、商品関連のクエリへの回答、業界ニュースの分析、顧客フィードバックの解釈など、特定のタスクやドメインに適用すると、不足することがよくあります。LLMを真に役立てるには、ユースケースに合わせた高品質のデータが必要です。 このデータは通常、ウェブ上に分散していたり、複雑なサイト構造の背後に隠されていたり、ボット対策によって保護されていたりする。 当社の自動ワークフローは、データセット作成の最も困難な部分を処理する合理化されたパイプラインでこれを解決します: コア技術の概要 パイプラインを構築する前に、関連するコアテクノロジーと、それぞれがワークフローをどのようにサポートしているかを簡単に見ておこう。 ブライトデータスケーラブルなウェブデータ収集 AIに対応したベクターデータセットを作成するための最初のステップは、関連性のある高品質なソースデータを収集することです。ナレッジベースやドキュメンテーションのような内部システムから得られるものもあるが、大部分は公共のウェブから得られることが多い。 しかし、最近のウェブサイトは、CAPTCHA、IPレート制限、ブラウザフィンガープリントなどの高度なボット対策メカニズムを使用しているため、大規模なスクレイピングは困難である。 Bright Dataは、データ収集の複雑さを抽象化するWeb Unlocker APIでこの課題を解決します。プロキシのローテーション、CAPTCHAの解決、ブラウザのエミュレーションを自動的に処理するため、データへのアクセス方法ではなく、データに集中することができます。 Google Gemini: インテリジェント・コンテンツ・トランスフォーメーション Geminiは、Googleによって開発された強力なマルチモーダルAIモデルのファミリーであり、様々なタイプのコンテンツを理解し処理することに優れている。私たちのデータ抽出パイプラインにおいて、Geminiは3つの重要な機能を果たします: このAIを活用したアプローチは、特に以下のような使用例において、脆弱なCSSセレクタや壊れやすい正規表現に依存する従来の方法よりも大きな利点をもたらす: AIがデータ抽出プロセスにどのような変化をもたらしているかについては、Using AI for Web Scrapingをご覧ください。スクレイピングのワークフローにGeminiを実装するための実践的なチュートリアルをお探しの場合は、包括的なガイドをご覧ください:GeminiによるWebスクレイピングをご覧ください。 文の変形意味埋め込み文の生成 エンベッディングは、高次元空間におけるテキスト(または他のデータタイプ)の密なベクトル表現である。これらのベクトルは意味的な意味を捉え、コサイン類似度やユークリッド距離のようなメトリクスを用いて測定される、類似したテキスト片を近接したベクトルで表現することを可能にする。この特性は、セマンティック検索、クラスタリング、検索拡張生成(RAG)のようなアプリケーションで重要である。 Sentence Transformersライブラリは、高品質の文や段落の埋め込みを生成するための使いやすいインターフェースを提供する。Hugging Face Transformersの上に構築され、意味タスクのために微調整された幅広い事前学習済みモデルをサポートしています。 このエコシステムで最も人気があり、効果的なモデルの1つがオールMiniLM-L6-v2である: より大きなモデルはより微妙なエンベディングを提供するかもしれないが、all-MiniLM-L6-v2は性能、効率、コストの間で非常に優れたバランスを提供する。その384次元ベクトルは ほとんどの実用的なユースケース、特に初期段階の開発やリソースに制約のある環境では、このモデルで十分すぎる。エッジケースにおける精度のわずかな低下は、通常、スピードとスケーラビリティの大幅な向上によって相殺されます。そのため、AIアプリケーションの最初のイテレーションを構築する場合や、控えめなインフラストラクチャでパフォーマンスを最適化する場合は、all-MiniLM-L6-v2を使用することをお勧めします。 Pineconeベクトル埋め込み画像の保存と検索 テキストがベクトル埋め込みデータに変換されると、それを効率的に保存、管理、照会するための専用のデータベースが必要になります。従来のデータベースはこのために設計されていません。ベクトル・データベースは、埋め込みデータの高次元の性質を扱うために特別に設計されており、RAGパイプライン、セマンティック検索、パーソナライゼーション、その他のAI駆動型アプリケーションに不可欠なリアルタイムの類似性検索を可能にします。 Pineconeは、開発者フレンドリーなインターフェイス、低レイテンシの検索パフォーマンス、完全に管理されたインフラストラクチャで知られる人気のベクトルデータベースです。ベクトル検索インフラストラクチャの複雑さを抽象化することで、複雑なベクトルインデックスと検索を効率的に管理します。主なコンポーネントは以下の通りです: Pineconeは2つのデプロイメントアーキテクチャを提供する:ServerlessとPod-Based です。ほとんどのユースケース、特に開始時や動的な負荷に対処する場合は、シンプルさとコスト効率からサーバーレスが推奨されます。 セットアップと前提条件 パイプラインを構築する前に、以下のコンポーネントが適切に設定されていることを確認する。 前提条件 各APIキーの生成方法については、以下のツール固有の設定セクションを参照してください。 必要なライブラリのインストール このプロジェクトのコアとなるPythonライブラリをインストールする: これらのライブラリーは提供している: 環境変数の設定 プロジェクトのルート・ディレクトリに.envファイルを作成し、APIキーを追加する: ブライトデータ設定 Bright DataのWeb Unlockerを使用するには: 実装例と統合コードについては、Web Unlocker GitHub […]
6 分読
AI

LLMにおけるスーパーバイズド・ファインチューニングとは?

このPythonガイドでは、概念、ツール、ワークフロー、そしてAIプロジェクトを向上させる実践的な例を取り上げています。
7 分読