mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
18500 文字
48 分
クローリングの基礎知識
2024-01-13
2024-01-14

HTTPの基本原理#

URIとURL#

ここでは URI と URL をまず理解します。URI の正式名称は Uniform Resource Identifier(統一資源識別子)、URL の正式名称は Universal Resource Locator(統一資源定位子)です。

例えば、[https://github.com/favicon.ico、それ自体が] URLでもあり URI でもあります。つまりこのようなアイコン資源があり、私たちは URL/URI を用いてそのアクセス方法を一意に指定します。これには https のアクセスプロトコル、アクセスパス(根ディレクトリ)およびリソース名 favicon.ico が含まれます。こうしたリンクを通じて、私たちはインターネット上からこの資源を見つけることができます。これが URL/URI です。

URL は URI のサブセットです。つまりすべての URL は URI ですが、すべての URI が URL であるとは限りません。では、どのような URI が URL でないのでしょうか。URI には URN(Uniform Resource Name、統一資源名)というサブクラスも含まれます。URN は資源を命名するだけで、資源の定位方法を指定しません。例えば urn:isbn<0451450523> は本の ISBN を指定し、その本を一意に識別しますが、どこでその本を位置づけるかは指定されていません。これが URN です。

20240114035901.png

しかし現在のインターネットでは URN の使用は非常に少なく、ほぼすべての URI は URL です。したがって一般的なウェブリンクは URL と呼ぶことも URI と呼ぶこともできます。私は個人的には URL と呼ぶ習慣です。

超テキスト#

続いて、概念の一つである超テキストを理解します。その英語名は hypertext。ブラウザで見えるウェブページは超テキストとして解析されたもので、ウェブページのソースコードは一連の HTML コードであり、そこには img タグ(画像)、p タグ(段落表示)などのタグが含まれます。ブラウザがこれらのタグを解析した後、私たちが普段見るウェブページが形成され、ウェブページのソース HTML は超テキストと呼べます。

例えば、Chrome ブラウザで任意のページを開き、任意の場所を右クリックして「検証」項目を選択(もしくは F12 キーを直接押す)と、ブラウザの開発者ツールを開くことができます。ここで Elements タブには現在のウェブページのソースコードが表示され、これらはすべて超テキストです。

HTTPとHTTPS#

淘宝のトップページには https://www.taobao.com/中、URL の先頭に http または https がつくことがあります。これは資源へアクセスするためのプロトコルの種類で、時には ftp、sftp、smb で始まる URL も見られます。ここでの ftp、sftp、smb はすべてプロトコルの種類を指します。スクレイピングでは、取得するページは通常 http または https のプロトコルを用いるので、ここでこの二つのプロトコルの意味を説明します。

HTTP の正式名称は Hyper Text Transfer Protocol(超テキスト転送プロトコル)で、ウェブ上の超テキストデータをローカルのブラウザへ転送するための伝送プロトコルです。高速かつ正確に超文書を伝送できることを保証します。HTTP は World Wide Web Consortium(W3C)と Internet Engineering Task Force(IETF)によって共同で制定された規格で、現在広く使われているのは HTTP/1.1 版です。

HTTPS の正式名称は Hyper Text Transfer Protocol over Secure Socket Layer で、安全性を目的とした HTTP のチャンネルです。要するに HTTP のセキュア版で、HTTP に SSL レイヤーを追加したものを HTTPS と呼びます。

HTTPS のセキュリティの基礎は SSL です。従って HTTPS を通じて伝送される内容はすべて SSL で暗号化されます。主な役割は二つです。

  • 情報セキュアなチャネルを構築し、データ転送の安全を保証する。
  • サイトの信頼性を確認する。HTTPS を使用するサイトは、ブラウザのアドレスバーの錠マークをクリックしてウェブサイトの認証情報を確認でき、CA 機関が発行したセキュリティ署名を参照して調べることもできます。

ただし、HTTPS を使用しているサイトでもブラウザに「安全でない」と表示されることがあります。

HTTPリクエストの過程#

ブラウザに URL を入力してエンターを押すと、ブラウザ上でページの内容を観察できます。実際にはこの過程は、ブラウザがサイトのサーバへリクエストを送信し、サーバがそのリクエストを処理してレスポンスを返し、それをブラウザが受け取り、レスポンスにはページのソースコードなどが含まれ、それをブラウザが解析してウェブページを表示します。

20240114035924.png

このときクライアントは私たち自身の PC やスマホのブラウザを指し、サーバはアクセスしようとするウェブサイトが置かれているサーバです。

Chrome ブラウザを開き、右クリックして「検証」を選択するとブラウザの開発者ツールを開くことができます。ここで百度にアクセスして http://www.baidu.com/ を開き、URL を入力してエンターを押すと、ネットワークのリクエストがどう発生したかを観察できます。Network ページの下部にはエントリが現れ、そのうちのひとつがリクエストの送信とレスポンスの受信の過程を表します。

20240114040004.png

まず最初のネットワークリクエストを観察します。すなわち http://www.baidu.com/ です。各列の意味は以下のとおりです。

  • Name:リクエストの名称。通常は URL の最後の部分を名称として用います。
  • Status:レスポンスのステータスコード。ここは 200 と表示され、レスポンスが正常であることを意味します。ステータスコードでリクエスト後に正しいレスポンスを得られたかを判断します。
  • Type:リクエストされた文書のタイプ。ここでは document で、今回のリクエストは HTML 文書で、内容は HTML コードです。
  • Initiator:リクエストの発火元。どのオブジェクトやプロセスがリクエストを発したかを示します。
  • Size:サーバからダウンロードしたファイルとリクエスト資源のサイズ。キャッシュから取得した場合は from cache と表示されます。
  • Time:リクエストの開始からレスポンスを得るまでの総時間。
  • Waterfall:ネットワークリクエストの可視化された瀑布状表示。

このエントリをクリックすると、より詳細な情報が表示されます。

まず General 部分、Request URL はリクエストの URL、Request Method はリクエストの方法、Status Code はレスポンスの状態コード、Remote Address はリモートサーバのアドレスとポート、Referrer Policy は Referrer の判定ポリシーです。さらに下に進むと、Response Headers と Request Headers があり、これはそれぞれレスポンスヘッダーとリクエストヘッダーを表します。リクエストヘッダーには多くのリクエスト情報が含まれ、例としてブラウザの識別子、Cookies、Host などの情報があります。これはリクエストの一部で、サーバはリクエストヘッダー内の情報に基づいてリクエストが正当かどうかを判断し、それに応じたレスポンスを返します。図に見える Response Headers はレスポンスの一部で、サーバの種類、文書タイプ、日付などの情報を含み、ブラウザはレスポンスを受け取るとレスポンス内容を解析し、ウェブページを表示します。

リクエスト#

リクエストは、クライアントからサーバへ送信され、4 つの部分に分かれます:リクエストメソッド(Request Method)、リクエストURL(Request URL)、リクエストヘッダー(Request Headers)、リクエストボディ(Request Body)。

  1. リクエストメソッド

    よく使われるリクエストメソッドは 2 つ、GET と POST です。

    ブラウザで URL を直接入力してエンターを押すと、GET リクエストが発行され、リクエストのパラメータは URL に直接含まれます。例えば、百度で Python を検索する場合、リンクは https://www.baidu.com/s?wd=Python となり、URL に検索キーワード wd の情報が含まれます。POST リクエストは多くがフォームの送信時に発行されます。例えば、ログインフォームでユーザー名とパスワードを入力して「ログイン」ボタンをクリックすると、通常は POST リクエストが発行され、そのデータはフォームの形式で送信され、URL には現れません。

    GET と POST の違いは以下のとおりです。

    • GET のパラメータは URL に含まれ、URL からデータが見えます。一方、POST の場合は URL にデータは含まれず、データはフォーム形式で送信され、リクエストボディに含まれます。
    • GET で送信できるデータ量は最大で 1024 バイトですが、POST には制限がありません。

    一般的に、ログイン時にはユーザー名とパスワードを送信します。機密情報を含むためGET でのリクエストはURL にパスワードが露出してしまい、パスワードの漏洩を招くため、POST で送信するのが望ましいです。ファイルのアップロード時にはファイル内容が大きいため、POST を選択します。

    私たちが日常的に遭遇するほとんどのリクエストは GET または POST です。ほかにも GET、HEAD、POST、PUT、DELETE、OPTIONS、CONNECT、TRACE などのリクエストメソッドがあります。

    メソッド説明
    GET指定されたページ情報を要求し、エンティティ本文を返します。
    HEADGET に似ていますが、レスポンスには具体的な内容が含まれず、ヘッダを得るのに用います。
    POST指定リソースへデータを提出して処理を要求します(例:フォーム送信やファイルのアップロード)。データはリクエストボディに含まれます。POST は新しいリソースの作成や既存リソースの変更を引き起こすことがあります。
    PUTクライアントからサーバへ送信したデータで指定の文書の内容を置換します。
    DELETE指定されたページをサーバが削除するよう要求します。
    CONNECTHTTP/1.1 で、接続をパイプライン化できるプロキシサーバのために予約されています。
    OPTIONSクライアントがサーバの機能を確認します。
    TRACEサーバが受信したリクエストをエコーします。主にテスト・診断用です。
    PATCHPUT の補足で、既知のリソースの部分更新を行います。
  2. リクエストURL

    リクエストURL、すなわち統一リソース定位子 URL は、リクエストしたい資源を一意に特定します。

  3. リクエストヘッダー

    リクエストヘッダーは、サーバに対して追加情報を伝えるためのものです。特に重要な情報として Cookie、Referer、User-Agent などがあります。以下によく使われるヘッダーを簡単に説明します。

    • Accept:リクエストヘッダ領域で、クライアントが受け入れる情報のタイプを指定します。
    • Accept-Language:クライアントが受け入れる言語の種類を指定します。
    • Accept-Encoding:クライアントが受け入れる内容のエンコードを指定します。
    • Host:リクエスト資源のホスト IP とポート番号を指定します。その内容はリクエストURLの原本サーバーもしくはゲートウェイの位置です。HTTP/1.1 以降、リクエストには必須です。
    • Cookie:Cookies の複数形として使われることもあり、サイトがユーザーを識別してセッションを追跡するために端末に保存するデータです。主な機能は現在のアクセスセッションを維持することです。例えば、あるサイトにログイン後、サーバはセッションでログイン状態を保存します。以降、ページを更新したり別ページを要求してもログイン状態が維持され、表示されるページはログイン後の内容になります。Cookies には、サーバのセッションを識別する情報が含まれており、ブラウザがそのサイトのページをリクエストするたびに Cookies をリクエストヘッダーに追加してサーバに送信します。サーバは Cookies で自分自身を識別し、現在の状態がログイン状態であることを確認し、ログイン後のみ閲覧できるページを返します。
    • Referer:このリクエストがどのページから送信されたかを識別する情報で、サーバはこれを取得して対応します。例えば参照元の統計や防盗リンク対策など。
    • User-Agent:略称 UA。サーバがクライアントのOSとバージョン、ブラウザとバージョンなどを認識します。スクレイピング時にこれを設定するとブラウザを偽装できます。設定しないとクローラーと識別される可能性があります。
    • Content-Type:インターネットメディアタイプ(MIME type)とも呼ばれ、HTTP ヘッダ内でリクエスト内のメディアタイプ情報を表します。例えば text/html は HTML、image/gif は GIF、application/json は JSON など。対応表はこの対照表を参照してください:[http://tool.oschina.net/commons。]

    したがって、リクエストヘッダーはリクエストの重要な構成要素です。クローリングを行う際には大半の場合、リクエストヘッダーを設定する必要があります。

  4. リクエストボディ

    リクエストボディには一般に POST リクエストのフォームデータが含まれ、GET リクエストの場合は空になります。

    ログイン前にユーザー名とパスワードを入力して送信すると、これらはフォームデータとしてサーバへ送信されます。このとき、Request Headers の Content-Type を application/x-www-form-urlencoded に設定しておく必要があります。Content-Type を application/x-www-form-urlencoded に設定すると、フォームデータとして送信されます。あるいは Content-Type を application/json に設定して JSON データを送信したり、multipart/form-data に設定してファイルをアップロードすることもできます。

    Content-Type提出データの方式
    application/x-www-form-urlencodedフォームデータ
    multipart/form-dataフォームファイルのアップロード
    application/jsonJSON データのシリアライズ
    text/xmlXML データ

    クローラーで POST リクエストを作成する場合、正しい Content-Type を使用し、各種ライブラリのパラメータ設定でどの Content-Type が使用されているかを理解する必要があります。そうでないと POST 提出後に正しく応答されない可能性があります。

レスポンス#

レスポンスはサーバからクライアントへ返され、3つの部分に分かれます。レスポンスステータスコード(Response Status Code)、レスポンスヘッダー(Response Headers)、レスポンスボディ(Response Body)。

  1. レスポンスステータスコード

    レスポンスステータスコードはサーバの応答状態を表します。例として 200 はサーバが正常に応答、404 はページが見つからない、500 はサーバ内部エラーを意味します。スクレイピングではステータスコードに基づいてサーバの応答状態を判断します。例えば 200 ならデータの取得に成功したとみなし、次の処理へ進みます。そうでなければ無視します。

よくあるエラーコード
ステータスコード説明詳細
100続行クライアントはリクエストを継続して送るべき。サーバはリクエストの一部を受信し、残りを待機。
101プロトコルの切替クライアントがサーバにプロトコル切替を要求し、サーバがそれを確認して切替準備完了。
200成功サーバがリクエストを正常に処理しました。
201作成済みリクエストは成功し、サーバが新しいリソースを作成。
202受理サーバはリクエストを受理したが、まだ処理中。
203非認証情報サーバはリクエストを処理したが、返される情報は別のソースから。
204内容なしサーバはリクエストを処理したが、返す内容はなし。
205内容をリセットサーバはリクエストを処理し、内容をリセット。
206部分的内容サーバはリクエストの一部を処理。
300複数の選択肢要求に対してサーバは複数の操作を実行可能。
301永久移動要求されたページは新しい場所へ永久に移動。
302一時移動ページは一時的に別ページへ転送。
303他の場所を参照元のリクエストが POST の場合、リダイレクト先は GET で取得されるべき。
304未変更今回のリクエストで返されたページは変更されず、前回の資源を使用。
305プロキシ使用クライアントはこのページへプロキシを使用してアクセスするべき。
307一時リダイレクト資源は一時的に別の場所から応答。
400不正なリクエストサーバはこのリクエストを解析できません。
401未認証リクエストは認証されていない、または認証に失敗。
403アクセス禁止サーバがこのリクエストを拒否。
404見つからないサーバが要求されたページを見つけられません。
405メソッド禁止サーバがリクエスト中の指定メソッドを許可していません。
406受理不能要求内容でページを応答できません。
407プロキシ認証が必要クライアントはプロキシ認証を使用する必要があります。
408リクエストタイムアウトサーバのリクエスト処理がタイムアウト。
409競合サーバはリクエストの完了時に競合を検出。
410すでに削除要求された资源は永久に削除。
411有効長が必要有効な Content-Length ヘッダを欠くリクエストは受け付けません。
412前提条件失敗サーバはリクエストの前提条件の一部を満たしていません。
413リクエストエンティティが大きすぎるリクエストのエンティティが大きすぎて処理不能。
414リクエスト URI が長すぎるリクエストURLが長すぎて処理不能。
415サポートされていないメディアタイプリクエスト形式が閲覧ページでサポートされていません。
416リクエスト範囲不適合要求範囲を提供できません。
417期待値失敗サーバが期待するリクエストヘッダを満たしていません。
500サーバ内部エラーサーバがエラーに遭遇し、リクエストを完了できません。
501実装されていないサーバはリクエストを完了する機能を持ちません。
502バッドゲートウェイ上流サーバから無効な応答を受け、ゲートウェイとして動作します。
503サービス利用不可サーバは現在利用できません。
504ゲートウェイタイムアウト上流サーバからの応答を timely に受け取れませんでした。
505HTTP バージョン不支援サーバはリクエストで使用された HTTP バージョンをサポートしていません。
  1. レスポンスヘッダー

    レスポンスヘッダーには、サーバがリクエストに対して返す情報が含まれます。例えば Content-Type、Server、Set-Cookie など。よく使われるヘッダーを簡単に説明します。

    • Date:レスポンスが生成された時刻。
    • Last-Modified:資源の最終更新時刻。
    • Content-Encoding:レスポンス内容のエンコード。
    • Server:サーバの情報(名称、バージョンなど)。
    • Content-Type:文書タイプ。返されるデータの種類を指定。例: text/html は HTML、application/x-javascript は JavaScript、image/jpeg は画像。
    • Set-Cookie:Cookies の設定。レスポンスヘッダーの Set-Cookie はブラウザにこの内容を Cookies に格納させ、次回のリクエストで Cookies を送信させます。
    • Expires:レスポンスの有効期限。キャッシュの更新に利用され、再訪問時にキャッシュから読み込みサーバ負荷を軽減します。
  2. レスポンスボディ

    最も重要なのはレスポンスボディの内容です。レスポンス本文はレスポンスボディに含まれ、例えばウェブページを要求した場合のレスポンスボディはページの HTML コード、画像を要求した場合は画像のバイナリデータなどです。スクレイピングでウェブページを要求した後、解析すべき内容はレスポンスボディです。

    ブラウザの開発者ツールの Preview をクリックするとページのソースコード、すなわちレスポンスボディの内容を見られ、解析対象となります。スクレイピングでは、レスポンスボディからウェブページのソースコードや JSON データなどを取得し、そこから目的の内容を抽出します。

ウェブページの基礎#

ウェブページの構成#

ウェブページは大きく 3 つの部分に分けられます。HTML、CSS、JavaScript。ウェブページを人に例えるなら、HTML は骨格、JavaScript は筋肉、CSS は皮膚です。3つが組み合わさって初めて、完成されたウェブページになります。

  1. HTML

    HTML はウェブページを記述する言語で、その正式名称は Hyper Text Markup Language(超テキストマークアップ言語)です。ウェブページには文章、ボタン、画像、動画などの複雑な要素が含まれ、基本構造は HTML。異なるタイプの要素は、画像は img、動画は video、段落は p などのタグで表現されます。これらは div などのレイアウトタグでネスト・組み合わせることで、ウェブページの枠組みを形成します。

    Chrome で百度を開き、右クリックして「検証」を選択(または F12)して開発者モードを開くと、Elements タブでウェブページのソースコードが表示されます。

    これが HTML です。ウェブページ全体はさまざまなタグのネストで構成され、これらのタグが定義するノードは互いにネスト・組み合わせて複雑な階層関係を作り、ウェブページの構造を形成します。

  2. CSS

    HTML はウェブページの構造を定義しますが、単に HTML のレイアウトだけでは美しくありません。CSS を用いてスタイルを整えます。

    CSS の正式名称は Cascading Style Sheets(カスケーディング・スタイル・シート)です。「層叠」は、HTML に複数のスタイルシートを参照し、スタイルが衝突した場合にブラウザが層叠順序に従って処理できることを指します。「スタイル」はウェブページの文字サイズ、色、要素間の間隔、配置などのフォーマットを指します。

    CSS は現在、ウェブページのレイアウト・スタイリングの標準となる唯一の規格です。

    #head_wrapper.s-ps-islite .s-p-top {
    position: absolute;
    bottom: 40px;
    width: 100%;
    height: 181px;
    }

    これは CSS のスタイルです。中括弧の前には CSS セレクターが来ます。セレクターの意味は、まず id が head_wrapper かつ class が s-ps-islite のノードを選択し、その内部の class が s-p-top のノードをさらに選択します。中括弧内には一つずつのスタイル規則が書かれており、例えば position はこの要素のレイアウトを絶対配置に、bottom は要素の下端の余白を 40 ピクセル、width は幅を 100%、parent 要素を満たすように指定します。つまり、位置・幅・高などのスタイル設定をこのような形で一括して書き、先頭に CSS セレクターを付けることで、CSS セレクターで選択した要素にこのスタイルが適用され、要素はこのスタイルに従って表示されます。 ウェブページでは、通常はウェブ全体のスタイル規則を統一して CSS ファイル(拡張子は .css)に書き込みます。HTML では link タグを用いて作成済みの CSS ファイルを読み込むだけで、ページ全体が美しく洗練されたものになります。

  3. JavaScript

    JavaScript(略称 JS)はスクリプト言語です。HTML と CSS を組み合わせて使うことで、ユーザーに提供される情報は静的なものになり、インタラクションが欠如します。ウェブページにはダウンロードの進捗バー、ダイアログ、カルーセルなどのインタラクションやアニメーションが見られますが、これは通常 JavaScript の貢献です。JavaScript の登場により、ユーザーと情報の関係は単なる閲覧・表示の関係ではなく、リアルタイムで動的・インタラクティブなページ機能を実現しました。

    JavaScript は通常、js 拡張子の単独ファイルとして読み込まれ、HTML の中で script タグを通じて導入します。

    <script src="jquery-2.1.0.js"></script>

    総括すると、HTML はウェブページの内容と構造を、CSS はページのレイアウトを、JavaScript はページの動作を定義します。

ウェブページの構造#

まず例を使って HTML の基本構造を体感します。名前は任意で、拡張子は.html のテキストファイルを作成し、次の内容とします。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h2 class="title">Hello World</h2>
<p class="text">Hello, this is a paragraph.</p>
</div>
</div>
</body>
</html>

これは最も基本的な HTML の例です。先頭の DOCTYPE は文書型を定義し、最も外側は html タグ、最後に対応する終了タグで閉じられ、内部には head タグと body タグがあり、それぞれウェブページのヘッダーと本文を表します。head タグ内にはページの設定や参照が定義されます。

<meta charset="UTF-8"> はウェブページのエンコーディングを UTF-8 に指定します。

title タグはウェブページのタイトルを定義し、タブに表示されますが本文には表示されません。body 内にはウェブページの本文として表示される要素が含まれ、div タグはページ内の区分を表します。その id は container で、これはウェブページ内で一意です。さらにこの区分の中には div タグがあり、class は wrapper です。これも CSS と組み合わせてスタイルを設定する際に頻繁に使われる属性です。次に内部には h2 タグがあり、これは見出しの二級分を表します。さらに p タグは段落を表します。これらの内容をそのまま書くと、ウェブページに表示されます。それぞれに class 属性も付いています。

コードを保存してブラウザで開くと、図のような内容が表示されます。

20240114040127.png

タブには This is a Demo の文字が表示され、これは head の title で定義した文字列です。ウェブページ本文は body タグ内の各要素によって生成され、ここでは二級見出しと段落が表示されます。この例はウェブページの一般的な構造です。ウェブページの標準形は html タグが内包する head と body で、head 内にウェブページの設定・参照を、body 内に本文を定義します。

ノードツリーとノード間の関係#

HTML では、すべてのタグが定義する内容はノードで、これらは HTML DOM ツリーを構成します。

まず DOM とは何かを見てみましょう。DOM は W3C の標準で、英文正式名称は Document Object Model、すなわち「文書オブジェクトモデル」です。これにより、HTML および XML 文書へのアクセス標準を定義します。

W3C の文書オブジェクトモデル(DOM)は、プラットフォームや言語に依存しないインターフェースで、プログラムやスクリプトが文書の内容、構造、スタイルを動的にアクセス・更新できることを可能にします。

W3C DOM の標準は 3 つの部分に分かれています。

  • Core DOM - どのような構造化文書にも対応する標準モデル
  • XML DOM - XML 文書の標準モデル
  • HTML DOM - HTML 文書の標準モデル

W3C の HTML DOM 標準によれば、HTML 文書のすべての内容はノードです:

  • 文書全体は文書ノード
  • 各 HTML 要素は要素ノード
  • HTML 要素内のテキストはテキストノード
  • 各 HTML 属性は属性ノード
  • コメントはコメントノード

HTML DOM は HTML 文書を木構造として扱います。これがノードツリーと呼ばれる所以です。

20240114040145.png

HTML DOM を通じて、ツリー内のすべてのノードは JavaScript からアクセスでき、すべての HTML ノード要素は変更・作成・削除が可能です。

ノードツリーのノードは階層関係を持ちます。私たちは parent、child、sibling などの用語を使ってこれらの関係を説明します。親ノードは子ノードを持ち、同レベルの子ノードは兄弟ノードと呼ばれます。

ツリーの最上位ノードはルート(root)と呼ばれます。根ノード以外の各ノードは親ノードを持ち、任意の数の子ノードまたは兄弟ノードを持つことができます。

セレクター#

ウェブページはノードの集合であり、CSS セレクターはノードごとに異なるスタイル規則を設定します。ではノードをどうやって特定するのでしょうか?

CSS ではセレクターを用いてノードを特定します。例えば、上の例の div ノードの id が container なら、#container と表現します。# で始まるのは id を選択することを意味します。その後には id の名前が続きます。また、class が wrapper のノードを選択したい場合は .wrapper を使用します。ここでは先頭のドット . は class を選択することを示します。さらに、タグ名で選択する方法もあり、例えば二級見出しを選択したい場合は h2 をそのまま使います。これが最もよく使われる 3 種の表現方法で、id、class、タグ名で選択します。覚えておいてください。

また、CSS セレクターはネストして選択することも支持します。各セレクターの間にスペースを入れるとネスト関係を表します。例えば #container .wrapper p は、まず id が container のノードを選択し、その内部の class が wrapper のノードを選択し、さらにその内部の p ノードを選択します。逆に、スペースを入れなければ並列関係を表します。 div#container .wrapper p.text は、まず id が container の div ノードを選択し、その内部の class が wrapper のノードを選択し、さらに内部の class が text の p ノードを選択します。これが CSS セレクターです。その機能は非常に強力です。

さらに、CSS セレクターには他にもさまざまな文法規則があります。

CSS文法
セレクター例 子説明
.class.introclass=“intro” のすべてのノードを選択
#id#firstnameid=“firstname” のすべてのノードを選択
**すべてのノード
elementpすべての p ノード
element,elementdiv,pすべての div ノードとすべての p ノード
element elementdiv pdiv ノード内部のすべての p ノード
element>elementdiv>p親ノードが div のすべての p ノード
element+elementdiv+pdiv ノードの直後にあるすべての p ノード
[attribute][target]target 属性を持つすべてのノード
[attribute=value][target=blank]target=“blank” のすべてのノード
[attribute~=value][title~=flower]title 属性に flower という単語を含むすべてのノード
a未訪問のリンクを選択
a訪問済みのリンクを選択
aアクティブなリンク
a自マウスカーソルが上にあるリンクを選択
inputフォーカスを得ている input ノードを選択
p各 p ノードの先頭文字を選択
p各 p ノードの先頭行を選択
p親ノードの最初の子ノードを持つすべての p ノード
p各 p ノードの内容の前に内容を挿入
p各 p ノードの内容の後に内容を挿入
(language)plang 属性値が it で始まるすべての p ノードを選択
element1~element2p~ul前に p ノードを持つすべての ul ノードを選択
[attribute^=value]a[src^=“https”]src 属性値が https で始まるすべての a ノードを選択
[attribute$=value]a[src$=“.pdf”]src 属性値が .pdf で終わるすべての a ノードを選択
[attribute*=value]a[src*=“abc”]src 属性値に abc を含むすべての a ノードを選択
p親ノードの最初の p ノードを全て選択
p親ノードの最後の p ノードを全て選択
p親ノードの中で唯一の p ノードを全て選択
p親ノードの唯一の子ノードである p ノードを全て選択
(n)p親ノードの第2子ノードに属するすべての p ノード
(n)p同様、最後の子ノードから数えます
(n)p親ノードの2番目の p ノードに属するすべての p ノード
(n)p同様、最後の子ノードから数えます
p親ノードの最後の子ノードであるすべての p ノード
ドキュメントの根ノード
p子ノードを持たないすべての p ノード(テキストノードを含む)
#news現在アクティブな #news ノード
input有効化されているすべての input ノード
input無効化されているすべての input ノード
inputチェックされているすべての input ノード
(selector)p ノード以外のすべてのノード
::selection::selectionユーザーが選択したノードの一部

クローラーの基本原理#

私たちはインターネットを大きな網と見なすことができます。クローラー(ネットワーク・クローラー)はその網を這い回るクモのようなものです。網のノードを個々のウェブページと見なし、クローラーがそのページに到達すると、それを訪問して情報を取得します。ノード間のリンクをウェブページ同士の結びつきとみなし、あるノードを経由して次のノードへと進み、別のページを取得していくことができるようにします。こうして網全体のノードをクローラーがすべて巡回することで、サイトのデータを取得できるようになります。

クローラーの概要#

要約すると、クローラーはウェブページを取得し、情報を抽出・保存する自動化プログラムです。以下に概要を説明します。

  1. ウェブページの取得

    クローラーが最初に行うべき作業はウェブページを取得することです。ここではウェブページのソースコードを取得します。ソースコードにはウェブページの有用な情報が含まれており、それを取得すれば、欲しい情報を抽出できます。

    先に説明したように、リクエストとレスポンスの概念を用いて、サイトのサーバへリクエストを送信し、レスポンスボディとしてウェブページのソースコードを取得します。したがって、最も重要な部分はリクエストを構築してサーバへ送信し、レスポンスを受け取り、それを解析することです。

    Python にはこの操作を実現する多くのライブラリがあり、urllib、requests などが代表例です。これらのライブラリを用いて HTTP リクエストを実行します。リクエストとレスポンスはライブラリが提供するデータ構造で表現でき、レスポンスを得た後は Body 部分を解析するだけで、ウェブページのソースコードを取得できます。こうして私たちはプログラムを用いてウェブページの取得プロセスを実現します。

  2. 情報の抽出

    ウェブページのソースコードを取得したら、次はそれを分析して欲しいデータを抽出します。まず、最も一般的な方法は正規表現を用いることですが、正規表現の作成は複雑でミスが起きやすい万能な方法です。

    さらに、ウェブページの構造には一定の規則があるため、ウェブページのノード属性、CSS セレクター、または XPath に基づいて情報を抽出するライブラリも存在します。たとえば Beautiful Soup、pyquery、lxml など。これらのライブラリを使うと、ノードの属性やテキスト値など、ウェブページ情報を効率よく抽出できます。

    情報の抽出はクローラーにとって非常に重要な部分で、雑然としたデータを整理して後の処理・分析を容易にします。

  3. データの保存

    抽出した情報を、後で利用するためにどこかへ保存します。保存形式は TXT や JSON などのテキスト形式、データベース(MySQL、MongoDB など)へ保存、さらには遠隔サーバへ保存することも可能です(SFTP などを利用)。

  4. 自動化プログラム

    自動化プログラムとは、クローラーが人間に代わってこれらの作業を実行できるという意味です。手作業で情報を抽出することも可能ですが、規模が大きい場合や大量のデータを素早く取得したい場合にはプログラムの助けが必要です。クローラーはこの収集作業を自動化するプログラムで、収集中にさまざまな例外処理や再試行を行い、収集を継続的かつ高効率で動作させます。

どのようなデータを取得できるか#

ウェブページにはさまざまな情報が表示されます。最も一般的なのは通常のウェブページで、HTML コードに対応します。最も頻繁に取得されるのは HTML のソースコードです。

また、場合によってはウェブページが HTML コードを返さず、JSON 文字列を返すことがあります(API の多くがこの形式を採用します)。この形式のデータは転送と解析が容易で、取得可能です。

さらに、画像・動画・音声などのさまざまなバイナリデータも見ることができます。クローラーを用いてこれらのバイナリデータを取得し、対応するファイル名で保存します。

また、CSS、JavaScript、設定ファイルなど拡張子の異なるファイルも見られます。これらも最も一般的なファイルで、ブラウザでアクセスできれば取得できます。

これらはすべて各自の URL に対応しており、HTTP または HTTPS プロトコルに基づくデータです。こうしたデータはクローラーで取得可能です。

JavaScript でページをレンダリングする#

場合によっては、urllib や requests を使ってウェブページを取得する際、得られるソースコードがブラウザで見えるものと実際には異なることがあります。

これは非常に一般的な問題です。現在のウェブページは Ajax やフロントエンドのモジュール化ツールを用いて構築されることが増え、ページ全体が JavaScript でレンダリングされる場合があり、元の HTML コードは空の shell のようなものです。例えば:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a Demo</title>
</head>
<body>
<div id="container">
</div>
</body>
<script src="app.js"></script>
</html>

body の中には id が container のノードだけがあります。しかし body の後に app.js が読み込まれており、それがサイト全体のレンダリングを担当します。

このページをブラウザで開くと、最初にこの HTML が読み込まれ、次に app.js が読み込まれ、それに含まれる JavaScript が実行され、HTML のノードを変更して内容を追加し、最終的に完全なページを得られます。

しかし、urllib や requests などの基本的な HTTP リクエストライブラリを使って現在のページを取得すると、得られるのはこの HTML コードだけで、JavaScript ファイルの読み込みを継続する手助けにはなりません。そのため、ブラウザで見える内容を得ることはできません。

このことは、取得したソースコードがブラウザのページソースと異なる理由の一つです。

したがって、基本的な HTTP リクエストライブラリを使って得られるソースコードは、ブラウザのページソースと必ずしも同じではありません。このような場合、バックエンドの Ajax API を分析するか、Selenium、Splash のようなライブラリを用いて JavaScript のレンダリングを模倣することができます。

セッションとCookies#

ウェブを閲覧しているとき、しばしばログインが必要な場面に遭遇します。いくつかのページはログイン後にのみ閲覧可能で、ログイン後はサイトを連続して何度も閲覧できます。しかし、しばらくすると再度ログインが必要になることがあります。また、ブラウザを開いた時点で自動的にログインしており、長時間有効な場合もあります。これらはセッション(Session)と Cookies の知識に関わります。

静的ウェブページと動的ウェブページ#

まず、静的ウェブページと動的ウェブページの概念を理解しておく必要があります。以下は前の例のコードです。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h2 class="title">Hello World</h2>
<p class="text">Hello, this is a paragraph.</p>
</div>
</div>
</body>
</html>

これは最も基本的な HTML コードです。これを .html ファイルとして保存し、固定のグローバル IP を持つホストに置き、Apache や Nginx などのサーバをインストールします。こうしてこのホストがサーバとして機能し、他の人がそのサーバへアクセスしてこのページを閲覧できるようになります。これが最も簡単なウェブサイトの構築です。

この種のウェブページの内容は HTML コードで作成され、文字・画像などの内容は HTML コードで指定します。このようなページは静的ウェブページと呼ばれます。読み込み速度が速く、作成が簡単ですが、保守性が低く、URL によって動的にコンテンツを表示することができないなどの欠点があります。例えば、このページの URL に name パラメータを渡して、ページ内に表示させることはできません。

したがって、動的ウェブページが生まれました。URL のパラメータの変化を動的に解析し、データベースと連携して、異なるページ内容を動的に表示することができます。現在出会うほとんどのサイトは動的サイトで、単純な HTML だけではなく、JSP、PHP、Python などの言語で作成される機能があり、静的ウェブページよりもはるかに強力で豊富です。

さらに、動的ウェブサイトはユーザーのログインと登録機能を実現します。冒頭で挙げた問題に戻ると、多くのページはログイン後でなければ表示できません。通常は、ユーザー名とパスワードを入力してログインすると、何らかの証憑のようなものを入手し、それを用いてログイン状態を維持し、ログイン後に閲覧可能なページへアクセスします。

無状態 HTTP#

セッションと Cookies を理解する前に、HTTP の特徴の一つ「無状態」について理解しておく必要があります。

HTTP の無状態とは、HTTP プロトコルが取引処理に記憶能力を持たないことを指します。つまりサーバはクライアントの状態を知らず、リクエストを送信してレスポンスを受け取り、それを完結させます。この過程は完全に独立しており、前後の状態の変化を記録しません。したがって前の情報を処理するためには、再送信が必要となり、前の重複リクエストを送信して後続のレスポンスを取得することになり、これは我々が望む挙動ではありません。前後の状態を維持するためには、前のリクエストをすべて再送信するのは資源の無駄です。ログインが必要なページでは特に困難です。

この時、HTTP 接続状態を維持する技術として、セッションと Cookies の二つが現れます。セッションはサーバ側、すなわちウェブサイトのサーバで、ユーザーのセッション状態を保持するための属性・設定情報を保存します。クライアントがウェブページ間を移動しても、セッション内の変数は失われません。セッションが存在しない場合、Web サーバは自動的にセッションオブジェクトを作成します。セッションが期限切れになるか放棄されると、サーバはそのセッションを終了します。

2. Cookies

Cookies は、いくつかのサイトがユーザーの身元を識別し、セッションを追跡するためにユーザーの端末に保存するデータです。

  • 会話維持 クライアントが初めてサーバにリクエストしたとき、サーバは Set-Cookie を含むレスポンスを返し、どのユーザーかを識別します。ブラウザは Cookies を保存します。次回のリクエスト時にはこの Cookies をリクエストヘッダとともにサーバへ送信します。Cookies にはセッション ID が含まれており、サーバはその Cookies から対応するセッションを特定し、ログイン状態を維持します。ログイン後のページを閲覧するには、サーバはセッション内の状態を確認します。ログイン状態であれば、ログイン後に閲覧可能なページを返します。 逆に、Cookies が無効であったり、セッションが期限切れの場合は、ページへアクセスできなくなる可能性があり、エラーが返されるか、ログインページへリダイレクトされることがあります。

したがって Cookies とセッションは連携して動作します。クライアント側とサーバ側の協調によって、ログインセッションのコントロールが実現します。

  • 属性構造

    Cookies にはさまざまな属性が含まれます。以降は知乎を例に、ブラウザの開発者ツールの Application タブを開き、左の Storage 部分の Cookies を展開して確認します。

    20240114040215.png

    ここには多くのエントリがあり、各エントリを Cookies と呼ぶことができます。主な属性は次のとおりです。

    • Name:Cookie の名称。作成後は変更不可。
    • Value:Cookie の値。Unicode 文字の場合は文字エンコード、二進データの場合は BASE64 エンコードを使用。
    • Max Age:この Cookie の有効期限を秒単位で指定します。Expires と併用され、有効期間を算出します。Max Age が正の値ならこの秒数後に失効します。負の値なら、ブラウザを閉じたときに失効します。
    • Path:この Cookie の使用パス。/path/ と設定するとパスが /path/ のページだけがこの Cookie を使用できます。/ に設定すると同一ドメイン下のすべてのページでこの Cookies にアクセスできます。
    • Domain:この Cookies にアクセスできるドメイン。例として .zhihu.com を設定すると、.zhihu.com で終わるすべてのドメインからこの Cookie にアクセスできます。
    • Size:この Cookie のサイズ。
    • Http(HttpOnly):この Cookie の HttpOnly 属性。true の場合、HTTP ヘッダの情報でのみこの Cookie を参照でき、document.cookie からはアクセスできません。
    • Secure:この Cookies が安全なプロトコル(HTTPS、SSL など)でのみ送信されるべきかどうか。デフォルトは false。
  • セッション Cookies と永続 Cookies

    外観上、セッション Cookies はブラウザのメモリ内に保存され、ブラウザを閉じると失効します。永続 Cookies はクライアントのハードディスクに保存され、次回も使用可能で、長期間のログイン状態を保持します。

    実際には、セッション Cookies と永続 Cookies の区別は Max Age または Expires フィールドによって決まります。

    したがって、永続的なログインを提供するサイトは、Cookie の有効期限とセッションの有効期間を長く設定することで、次回の閲覧時にも以前の Cookies を持っていけば、ログイン状態を維持できます。

よくある誤解#

セッション機構について語る際、よくある誤解として「ブラウザを閉じるとセッションが消える」というものがあります。会員カードの例を考えると、顧客が店舗に解約を申し出ない限り顧客データを削除しません。セッションも同様で、サーバがセッションを削除するよう通知しない限り、サーバはセッションを保持します。例えば、アプリでログアウト操作を行う場合にのみセッションを削除します。

ただし、ブラウザを閉じるとサーバへ通知されず、サーバがセッションを削除する機会がないため、この誤解が生じます。多くのセッション機構はセッションIDを Cookies に保存します。ブラウザを閉じると Cookies が消えてしまい、再接続時に元のセッションを見つけられなくなるのです。もしサーバが Cookies をディスクに保存するよう設定していたり、ブラウザが送信する HTTP リクエストヘッダを変更して元の Cookies を送信できる場合、ブラウザを再起動しても元のセッション ID を見つけてログイン状態を維持できます。

さらに、ブラウザを閉じてもセッションが削除されないことが原因で、サーバは会話を維持します。これを考慮して、サーバはセッションに有効期限を設定します。クライアントが最後にセッションを使用してから一定時間が過ぎると、サーバはクライアントが活動を停止したとみなし、セッションを削除してストレージ空間を節約します。

プロキシの基本原理#

クローラーを実行していると、最初は正常にデータを取得できているにもかかわらず、ある時点で 403 Forbidden などのエラーが発生することがあります。サイトを開くと「あなたの IP のアクセス頻度が高すぎます」といった表示が出ることがあります。これはサイトが対策を施しているためで、サーバは一定時間内に特定の IP からのリクエスト数を検出し、閾値を超えるとサービスを拒否します。これを IP ブロックと呼びます。

サーバが検出するのは特定の IP の一定時間内のリクエスト回数です。したがって、何らかの方法で IP を偽装し、サーバが自機からのリクエストと判断できなくすれば、IP ブロックを回避できるのではないでしょうか。

一つの有効な方法はプロキシの使用です。

基本原理#

プロキシとは、プロキシサーバのことで、英語名は proxy server です。その機能はネットワークユーザーが情報を取得するための中継点になることです。

通常ウェブサイトへアクセスすると、サーバへリクエストを送信します。プロキシサーバを介すると、実際には自分のマシンとサーバの間にブリッジを作ったような状況になり、クライアントは直接 Web サーバへリクエストを送るのではなく、プロキシサーバへリクエストを送ります。リクエストはまずプロキシサーバへ送られ、プロキシサーバが Web サーバへ再送信し、Web サーバからのレスポンスを再びクライアントへ転送します。

このようにして私たちは通常通りウェブページへアクセスできますが、この過程でサーバが認識する実 IP はもはや自分の IP ではなく、プロキシサーバの IP になります。これにより IP の偽装が実現され、プロキシの基本原理が成立します。

プロキシの作用#

プロキシには次のような作用があります。

  • 自身の IP アクセス制限を突破して、通常アクセスできないサイトへアクセスする。
  • 教育ネット内の地址帯など、内部リソースにアクセスするためのプロキシを利用して FTP のダウンロード・アップロード、資料検索・共有などのサービスを利用する。
  • キャッシュ技術を用いて処理の高速化。プロキシサーバは大容量のディスクキャッシュを設定して、外部情報を取得すると同時にキャッシュへ保存します。別の利用者が同じ情報へアクセスした場合、キャッシュから情報を取り出して提供することでアクセス速度を向上させます。
  • 実 IP を隠す。回避策として用い、クローラーの IP がブロックされるのを防ぎます。

クローラー用プロキシ#

クローラーでは、データ取得速度が速すぎると同じ IP からのアクセス頻度が高く見られ、サイト側が CAPTCHA を要求したり IP をブロックしたりします。これを回避するために、プロキシを使って実 IP を隠し、プロキシを頻繁に変更することでブロックを回避できます。

プロキシの分類#

プロキシは、プロトコル別と匿名性の度合い別に分類できます。以下にそれぞれをまとめます。

  1. プロトコル別

    • FTP プロキシサーバ:FTP サーバへアクセスする用途が主で、アップロード・ダウンロード・キャッシュ機能を持ち、ポートは通常 21、2121 など。
    • HTTP プロキシサーバ:ウェブページへのアクセスが主で、コンテンツフィルタリングとキャッシュ機能を持ち、ポートは通常 80、8080、3128 など。
    • SSL/TLS プロキシ:暗号化サイトへのアクセス用。SSL または TLS 暗号化機能を持ち(最大 128 ビットの暗号強度をサポート)、ポートは通常 443。
    • RTSP プロキシ:RealPlayer による Real メディアサーバへのアクセス、キャッシュ機能を持つことが多く、ポートは通常 554。
    • Telnet プロキシ:Telnet によるリモート制御用で、ポートは通常 23。
    • POP3/SMTP プロキシ:POP3/SMTP によるメール送受信、キャッシュ機能を持ち、ポートは通常 110/25。
    • SOCKS プロキシ:データパケットを単純に転送するだけで、プロトコルや用途を特に気にしません。SOCKS は SOCKS4 と SOCKS5 に分かれ、SOCKS4 は TCP のみをサポート、SOCKS5 は TCP と UDP をサポートし、認証機構やサーバ側のドメイン名解決などもサポートします。要するに、SOCKS4 でできることは SOCKS5 でもほぼ可能ですが、SOCKS5 が可能なことが SOCKS4 では必ずしも可能とは限りません。
  2. 匿名性レベル別

    • 高度匿名プロキシはデータパケットをそのまま転送します。サーバから見ると通常のクライアントのアクセスに見え、記録される IP はプロキシサーバの IP となります。
    • 通常匿名プロキシはデータパケットにいくつかの変更を加え、サーバ側でこれはプロキシだと気づく可能性があり、クライアントの実 IP を追跡されることがあります。HTTP_VIA および HTTP_X_FORWARDED_FOR などのヘッダを追加することが多いです。
    • 透明プロキシはデータパケットを改変するだけでなく、クライアントの実 IP をサーバに伝えます。キャッシュによる速度向上やコンテンツフィルタリングによるセキュリティ向上以外には顕著な利点は少なく、最も一般的な例は内部ネットワークのハードウェアファイアウォールです。
    • 间諜プロキシは、組織や個人が作成した、ユーザーの伝送データを記録することを目的としたプロキシサーバです。

よくあるプロキシ設定#

  • ネット上の無料プロキシを使用する場合は、できるだけ高匿名性のものを使用します。使用前に取得して有効なプロキシをフィルタリングするか、プロキシプールを構築します。
  • 有料プロキシサービスを利用します。インターネット上には多くのプロキシ業者があり、料金を支払って利用でき、品質は無料プロキシより高いです。
  • ADSL ダイヤルアップ。1回の接続ごとに IP が変更され、安定性が高く、比較的効果的な解決策の一つです。
共有

この記事が役に立ったときは、ぜひ他の人に共有してください!

クローリングの基礎知識
https://dreaife.tokyo/jp/posts/basic-web-crawling/
著者
dreaife
公開日
2024-01-13
ライセンス
CC BY-NC-SA 4.0

一部の情報は古い可能性があります

関連した投稿 スマート
1
クローラー基礎ライブラリ学習
spider Pythonのurllibやrequestsを中心に、クローラーの基礎ライブラリを学習します。HTTPリクエストの構築、例外処理、URL解析、正規表現の利用、猫眼映画ランキング情報の抽出方法などを紹介します。さらに、リクエストヘッダー、Cookies、プロキシ設定、セッション維持などの発展的な使い方も強調しています。
2
Pythonクローラー環境構築
spider Pythonクローラー環境の構築には、Python 3、リクエストライブラリ(requests、seleniumなど)、解析ライブラリ(lxml、beautifulsoup4など)、データベース(MySQL、MongoDBなど)、保存用ライブラリ(PyMySQL、PyMongoなど)、Webライブラリ(Flask、Tornadoなど)、アプリクローリング用ツール(mitmproxy、appiumなど)、クローラーフレームワーク(pyspider、scrapyなど)の導入が含まれます。各ライブラリのインストールコマンドと注意点も詳しく説明しています。
3
DockerでWin11上のpyspiderを動かす
spider Win11でpyspiderを使う際にインストール問題が発生した場合、Dockerを使って導入できます。Dockerコマンドとdocker-composeの使用例を示し、起動後は http://localhost:5000/ にアクセスしてpyspiderが正常に動作しているか確認できます。
4
Pandas基礎使用
cs-base PandasはPythonベースのオープンソースデータ分析ライブラリで、構造化データの処理に適したDataFrameとSeriesという2つの主要データ構造を提供します。データのクリーニング、変換、分析、可視化をサポートします。Pandasをインストールすると、簡単なコードでSeriesやDataFrameを作成・操作でき、基本操作、データフィルタリング、属性取得などを行えます。さらに、CSVやJSONファイルの読み込みと処理、欠損値や重複データの処理といったデータクレンジング機能も備えています。
5
SciPy基礎使用学習
cs-base SciPyはNumPyを基盤としたオープンソースのPythonライブラリで、数学・科学・工学分野で広く使われ、最適化、線形代数、積分、補間などの機能を提供します。pipでインストールでき、scipy.optimizeやscipy.sparseなどのモジュールで最適化処理や疎行列処理を行えます。SciPyはグラフ構造や空間データ処理もサポートし、多様な距離計算方法を提供し、Matlabとの連携や有意差検定・統計分析も実行できます。

目次