投稿者

インターシステムズジャパン
記事 Toshihiko Minamoto · 5月 23, 2023 8m read

Embedded Python による Web スクレイピングの基礎 - Python のお仕事を抽出しよう

Web スクレイピングとは:

簡単に言えば、Web スクレイピングWeb ハーベスティング、または Web データ抽出とは、Web サイトから大量のデータ(非構造化)を収集する自動プロセスです。 ユーザーは特定のサイトのすべてのデータまたは要件に従う特定のデータを抽出できます。 収集されたデータは、さらに分析するために、構造化された形式で保存することができます。

Web スクレイピングとは? — James Le

Web スクレイピングの手順:

  1. スクレイピングする Web ページの URL を見つけます。
  2. 検査により、特定の要素を選択します。
  3. 選択した要素のコンテンツを取得するコードを記述します。
  4. 必要な形式でデータを保存します。

たったそれだけです!!

Web スクレイピングに使用される一般的なライブラリ/ツール

  • Selenium - Web アプリケーションをテストするためのフレームワーク
  • BeautifulSoup – HTML、XML、およびその他のマークアップ言語からデータを取得するための Python ライブラリ
  • Pandas - データ操作と分析用の Python ライブラリ

Beauthiful Soup とは?

Beautiful Soup は、Web サイトから構造化データを抽出するための純粋な Python ライブラリです。 HTML と XML ファイルからデータを解析できます。 これはヘルパーモジュールとして機能し、利用できる他の開発者ツールを使って Web ページを操作する方法と同じ方法かより優れた方法で HTML と対話します。

  • lxmlhtml5lib などの使い慣れたパーサーと連携して、有機的な Python の方法で、解析ツリーを移動操作、検索、および変更できるようにするため、通常、プログラマーは数時間または数日間に及ぶ作業を節約できます。
  • Beautiful Soup のもう 1 つの強力で便利な機能は、フェッチされるドキュメントを Unicode に変換し、送信されるドキュメントを UTF-8 に変換するインテリジェンスです。 ドキュメント自体にエンコーディングが指定されていないか、Beautiful Soup がエンコーディングを検出できない場合を除き、開発者がその操作に注意する必要はありません。
  • 他の一般的な解析またはスクレイピング手法と比較した場合も高速と見なされています。

今日の記事では、Embedded Python と Object Script を使用して、ae.indeed.com にある Python の求人情報と企業をスクレイピングします。

ステップ 1 - スクレイピングする Web ページの URL を見つけます。

Url = https://ae.indeed.com/jobs?q=python&l=Dubai&start=0

スクレイピングするデータのある Web ページは以下のようになります。

  単純化と学習の目的で、"Job Title"(役職)と "Company"(会社)を抽出します。出力は以下のスクリーンショットのようになります。

 

以下の 2 つの Python ライブラリを使用します。

  • requests Requests は、Python プログラミング言語の HTTP ライブラリです。 プロジェクトの目標は、HTTP リクエストを単純化し、人間が読みやすくすることです。  
  • bs4 for BeautifulSoup Beautiful Soup は、HTML と XML ドキュメントを解析するための Python パッケージです。 HTML からデータを抽出するために使用できる解析済みページの解析ツリーを作成します。Web スクレイピングに役立ちます。

以下の Python パッケージをインストールしましょう(Windows)。

irispip install --target C:\InterSystems\IRISHealth\mgr\python bs4

irispip install --target C:\InterSystems\IRISHealth\mgr\python requests

Python ライブラリを ObjectScript にインポートしましょう
 

Class PythonTesting.WebScraper Extends%Persistent
{

// pUrl = https://ae.indeed.com/jobs?q=python&l=Dubai&start=// pPage = 0ClassMethod ScrapeWebPage(pUrl, pPage)
{
    // imports the requests python libraryset requests = ##class(%SYS.Python).Import("requests")
    // import the bs4 python libraryset soup = ##class(%SYS.Python).Import("bs4")
    // import builtins package which contains all of the built-in identifiersset builtins = ##class(%SYS.Python).Import("builtins")
}

Requests を使って HTML データを収集しましょう。

注意: 「my user agent」でグーグル検索し取得した、ユーザーエージェント
URL は "https://ae.indeed.com/jobs?q=python&l=Dubai&start=" で、pPage はページ番号です。

Requests を使って URL に HTTP GET リクエストを行い、そのレスポンスを "req" に格納します。

set headers  = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}
    set url = "https://ae.indeed.com/jobs?q=python&l=Dubai&start="_pPage
    
    set req = requests.get(url,"headers="_headers)

req オブジェクトには、Web ページから返された HTML が含まれます。

これを BeautifulSoup HTML パーサーで実行し、求人データを抽出できるようにします。

set soupData = soup.BeautifulSoup(req.content, "html.parser")
set title = soupData.title.text
W !,title

タイトルは以下のように表示されます

ステップ 2 - 検査し、必要な要素を選択します。

このシナリオでは、通常 <div> タグに含まれる求人リストに注目しています。ブラウザ内で要素を検査すると、その div クラスが見つかります。

ここでは、必要な情報は、「 <div class="cardOutline tapItem ... </div>」 に格納されています。

ステップ 3 - 選択した要素のコンテンツを取得するコードを記述します。

BeautifulSoup の find_all 機能を使用して、クラス名 "cardOutline" を含むすべての <div> タグを検索します。

//parameters to python would be sent as a python dictionaryset divClass = {"class":"cardOutline"}
set divsArr = soupData."find_all"("div",divClass...)

これによりリストが返されます。これをループ処理すると、Job Titles と Company を抽出できます。

###ステップ 4 - 必要なフォーマットでデータを保存/表示します。

以下の例では、データをターミナルに書き出します。

set len = builtins.len(divsArr)
    
W !, "Job Title",$C(9)_" --- "_$C(9),"Company"for i = 1:1:len {
    Set item = divsArr."__getitem__"(i - 1)
    set title = $ZSTRIP(item.find("a").text,"<>W")
    set companyClass = {"class_":"companyName"}
    set company = $ZSTRIP(item.find("span", companyClass...).text,"<>W")
    W !,title,$C(9)," --- ",$C(9),company
}

builtins.len() を使用して、divsArr リストの長さを取得していることに注意してください。

識別子名: ObjectScript と Python の識別子の命名規則は異なります。 たとえば、Python のメソッド名ではアンダースコア(_)を使用でき、_getitem_ や _class_ のようにいわゆる「ダンダー」といわれる特殊なメソッドや属性で実際に広く使用されています(「ダンダー」は「double underscore = 二重アンダースコア」の略です)。 このような識別子を ObjectScript で使用するには、二重引用符で囲みます:

識別子名に関する InterSystems ドキュメント

クラスメソッドの例

ClassMethod ScrapeWebPage(pUrl, pPage)
// pUrl = https://ae.indeed.com/jobs?q=python&l=Dubai&start=// pPage = 0ClassMethod ScrapeWebPage(pUrl, pPage)
{
    set requests = ##class(%SYS.Python).Import("requests")
<span class="hljs-keyword">set</span> soup = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%SYS.Python</span>).Import(<span class="hljs-string">"bs4"</span>)

<span class="hljs-keyword">set</span> builtins = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%SYS.Python</span>).Builtins()

<span class="hljs-keyword">set</span> headers  = {<span class="hljs-string">"User-Agent"</span>: <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"</span>}
<span class="hljs-keyword">set</span> url = pUrl_pPage

<span class="hljs-keyword">set</span> req = requests.get(url,<span class="hljs-string">"headers="</span>_headers)

<span class="hljs-keyword">set</span> soupData = soup.BeautifulSoup(req.content, <span class="hljs-string">"html.parser"</span>)

<span class="hljs-keyword">set</span> title = soupData.title.text

<span class="hljs-keyword">W</span> !,title

<span class="hljs-keyword">set</span> divClass = {<span class="hljs-string">"class_"</span>:<span class="hljs-string">"cardOutline"</span>}
<span class="hljs-keyword">set</span> divsArr = soupData.<span class="hljs-string">"find_all"</span>(<span class="hljs-string">"div"</span>,divClass...)

<span class="hljs-keyword">set</span> len = builtins.len(divsArr)

<span class="hljs-keyword">W</span> !, <span class="hljs-string">"Job Title"</span>,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>)_<span class="hljs-string">" --- "</span>_<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),<span class="hljs-string">"Company"</span>
<span class="hljs-keyword">for</span> i = <span class="hljs-number">1</span>:<span class="hljs-number">1</span>:len {
        <span class="hljs-keyword">Set</span> item = divsArr.<span class="hljs-string">"__getitem__"</span>(i - <span class="hljs-number">1</span>)
        <span class="hljs-keyword">set</span> title = <span class="hljs-built_in">$ZSTRIP</span>(item.find(<span class="hljs-string">"a"</span>).text,<span class="hljs-string">"<>W"</span>)
        <span class="hljs-keyword">set</span> companyClass = {<span class="hljs-string">"class_"</span>:<span class="hljs-string">"companyName"</span>}
        <span class="hljs-keyword">set</span> company = <span class="hljs-built_in">$ZSTRIP</span>(item.find(<span class="hljs-string">"span"</span>, companyClass...).text,<span class="hljs-string">"<>W"</span>)
        <span class="hljs-keyword">W</span> !,title,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),<span class="hljs-string">" --- "</span>,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),company
 }

}

</div>

今後の内容..

ObjectScript とEmbedded Python と数行のコードを使用して、いつも使用する求人サイトのデータをスクレイピングし、求人タイトル、会社、給料、職務内容、メールアドレス/リンクを簡単に収集できます。

たとえば、ページが複数ある場合、ページを使用して簡単にそれらをトラバースできます。 このデータを Pandas データフレームに追加して重複を削除したら、関心のある特定のキーワードに基づいてフィルターを適用できます。 このデータを NumPy で実行してラインチャートを取得します。 または、One-Hot エンコーディングをデータに実行し、ML モデルを作成/トレーニングします。興味のある特定の求人情報がある場合は、自分に通知を送信するようにします。 😉

それではコーディングをお楽しみください!!!

「いいね」ボタンも忘れずに押してください 😃