私はかなりの量のウェブサイトのスクレイピングを行っています。その方法を紹介します。具体的すぎる場合は飛ばしていただいてもかまいませんが、これはよくリクエストされるテーマであり、具体的にする必要があります。
URL の簡素化
これに使用するライブラリはhtmlagilitypack です(これは dll であり、新しいプロジェクトを作成して参照を追加します)。最初に確認することは、電話番号を使用してページにアクセスするために特別な手順を実行する必要があるかどうかです。ジョン・スミスを検索したところ、かなりの数が見つかりました。これらの結果のうち 2 つを入力したところ、URL のフォーマットが非常に単純であることがわかりました。それらの結果は..
http://www.canada411.ca/res/7056736767/John-Smith/138223109.html
http://www.canada411.ca/res/7052355273/John-Smith/172439951.html
URL から不明な値の一部を削除して、電話番号だけを残すことができるかどうかをテストしました。結果、できる…。
http://www.canada411.ca/search/re/1/7056736767/-
http://www.canada411.ca/search/re/1/7052355273/-
URL と私たちの電話番号にいくつかの静的な領域があることを URL で確認できます。これから、URL の文字列を作成します。
Dim phoneNumber as string = "7056736767" 'this could be TextBox1.Text or whatever
Dim URL as string = "http://www.canada411.ca/search/re/1/" + phoneNumber +"/-"
XPath による値の抽出
ページがダイヤルインされたので、上記で提供した html を調べてみましょう。ページから 6 つの値が必要なので、ここで作成します...
Dim FullName As String
Dim Phone As String
Dim Address As String
Dim Locality As String
Dim Region As String
Dim PostalCode As String
前述のように、 Xpath を使用する htmlagilitypack を使用します。これの優れた点は、html で一意の識別子を見つけたら、Xpath を使用して値を見つけることができることです。混乱するかもしれませんが、より明確になります。
必要な値はすべて、クラス名を持つタグ内にあります。Xpath でクラス名を使用してそれらを見つけてみましょう。
Dim FullNameXPath As String = "//*[@class='fn c411ListedName']"
Dim PhoneXPath As String = "//*[@class='c411Phone']"
Dim AddressXPath As String = "//*[@class='c411Address']"
Dim LocalityXPath As String = "//*[@class='locality']"
Dim RegionXPath As String = "//*[@class='region']"
Dim PostalCodeXPath As String = "//*[@class='postal-code']"
基本的に、私たちが見ているのは、何を探すべきかを htmlagilitypack に知らせる文字列です。この場合、名前を付けたクラスに含まれるテキストです。XPath には多くの機能があり、すべてを説明するには時間がかかる場合があります。余談ですが...Google Chromeを使用してページ上の値を強調表示すると、要素を右クリックして検査できます。以下に表示されるコードでは、値を右クリックして XPath にコピーできます!!! 非常に便利。
基本的な HTMLAgilityPack テンプレート
あとは、ページに接続して、これらの変数を設定するだけです。
Dim Web As New HtmlAgilityPack.HtmlWeb
Dim Doc As New HtmlAgilityPack.HtmlDocument
Doc = Web.Load(URL)
For Each nameResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(FullNameXPath)
Msgbox(nameResult.InnerText)
Next
上記の例では、Web という名前の HtmlWeb オブジェクトを作成します。これが私たちのプロジェクトの実際のクローラーです。次に、変換された検索可能なページ ソースで構成される HtmlDocument を定義します。これらはすべて舞台裏で行われます。次に、Web を送信してページ ソースを取得し、それを作成した Doc オブジェクトに割り当てます。Doc は再利用可能です。ありがたいことに、ページに一度接続するだけで済みます。
for ループは、名前を検索するための XPath 値として以前に定義された FullNameXPath に一致するドキュメント内のノードを探します。ノードが見つかると、nameResult 変数に割り当てられ、ループ内からメッセージ ボックスを呼び出して、ノードの内部テキストを表示します。
ですから、すべてをまとめると
完全な作業コード (2013 年 2 月 17 日現在)
Dim phoneNumber As String = "7056736767" 'this could be TextBox1.Text or whatever
Dim URL As String = "http://www.canada411.ca/search/re/1/" + phoneNumber + "/-"
Dim FullName As String
Dim Phone As String
Dim Address As String
Dim Locality As String
Dim Region As String
Dim PostalCode As String
Dim FullNameXPath As String = "//*[@class='fn c411ListedName']"
Dim PhoneXPath As String = "//*[@class='c411Phone']"
Dim AddressXPath As String = "//*[@class='c411Address']"
Dim LocalityXPath As String = "//*[@class='locality']"
Dim RegionXPath As String = "//*[@class='region']"
Dim PostalCodeXPath As String = "//*[@class='postal-code']"
Dim Web As New HtmlAgilityPack.HtmlWeb
Dim Doc As New HtmlAgilityPack.HtmlDocument
Doc = Web.Load(URL)
For Each nameResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(FullNameXPath)
FullName = nameResult.InnerText
MsgBox(FullName)
Next
For Each PhoneResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(PhoneXPath)
Phone = PhoneResult.InnerText
MsgBox(Phone)
Next
For Each ADDRResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(AddressXPath)
Address = ADDRResult.InnerText
MsgBox(Address)
Next
For Each LocalResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(LocalityXPath)
Locality = LocalResult.InnerText
MsgBox(Locality)
Next
For Each RegionResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(RegionXPath)
Region = RegionResult.InnerText
MsgBox(Region)
Next
For Each postalCodeResult As HtmlAgilityPack.HtmlNode In Doc.DocumentNode.SelectNodes(PostalCodeXPath)
PostalCode = postalCodeResult.InnerText
MsgBox(PostalCode)
Next