を使用してWEBサイトをマップするURLクローラーを構築する方法Ahad Sheriff
webスクレイピングの基礎を学ぶための簡単なプロジェクト
始める前に、ウェブスクレイピングとは何かを理解しておきましょう:
ウェブスクレイピングとは、ウェブサイトからデータを抽出して、ユーザーが簡単に理解できる形式で提示するプロセスです。
このチュートリアルでは、Webサイトをマップするために使用できる単純なURLクローラーをPythonで構築するのがいかに簡単かを示したいと思います。 このプログラムは比較的簡単ですが、webスクレイピングと自動化の基礎を紹介することができます。 Webページから再帰的にリンクを抽出することに焦点を当てますが、同じアイデアを他の無数の解決策に適用することができます。
私たちのプログラムは次のように動作します:
- webページにアクセスする
- webページで見つかったすべての一意のURLをスクレープし、キューに追加する
- キューを使い果たすまでURLを再帰的に処理する
- 結果を印刷する
最初に最初に
最初に行うべきことは、インポートですすべての必要なライブラリ。 WebスクレイピングにはBeautifulSoup、requests、およびurllibを使用します。
from bs4 import BeautifulSoupimport requestsimport requests.exceptionsfrom urllib.parse import urlsplitfrom urllib.parse import urlparsefrom collections import deque
次に、クロールを開始するURLを選択する必要があります。 HTMLリンクが付いているwebページを選ぶことができる間、私はScrapeThisSiteを使用することを推薦する。 トラブルに巻き込まれることなく這うことができる安全な砂場です。
url = "https://scrapethissite.com"
次に、新しく見つかったリンクを簡単に追加し、処理が完了したら削除できるように、新しいdequeオブジェクトを作成する必要があります。 Dequeにurl
変数を事前に入力します:
# a queue of urls to be crawled nextnew_urls = deque()
その後、処理された一意のURLを格納するためにセットを使用できます:
# a set of urls that we have already processed processed_urls = set()
また、ローカル(ターゲットと同じドメイン)、外部(ターゲットと異なるドメイン)、および壊れたUrlを追跡したいと考えています:
# a set of domains inside the target websitelocal_urls = set()
# a set of domains outside the target websiteforeign_urls = set()
# a set of broken urlsbroken_urls = set()
クロールする時間
すべてのことが整ったら、ウェブサイトをクロールするための実際のコードの記述を開始できます。
キュー内の各URLを見て、そのページ内に追加のURLがあるかどうかを確認し、残っていないまでキューの最後にそれぞれを追加します。 URLのスクレイピングが終了するとすぐに、それをキューから削除し、後で使用するためにprocessed_urls
セットに追加します。
# process urls one by one until we exhaust the queuewhile len(new_urls): # move url from the queue to processed url set url = new_urls.popleft() processed_urls.add(url) # print the current url print("Processing %s" % url)
次に、壊れたウェブページをキャッチするための例外を追加し、後で使用するためにそれらをbroken_urls
セットに追加します:
try: response = requests.get(url)
except(requests.exceptions.MissingSchema, requests.exceptions.ConnectionError, requests.exceptions.InvalidURL, requests.exceptions.InvalidSchema): # add broken urls to it's own set, then continue broken_urls.add(url) continue
次に、ローカルアドレスと外部アドレスを簡単に区別できるように、webページのベースURLを取得する必要があります:
# extract base url to resolve relative linksparts = urlsplit(url)base = "{0.netloc}".format(parts)strip_base = base.replace("www.", "")base_url = "{0.scheme}://{0.netloc}".format(parts)path = url if '/' in parts.path else url
BeautifulSoupを初期化してHTML文書を処理します:
soup = BeautifulSoup(response.text, "lxml")
今すぐすべてのリンクのためのwebページをこすり、ソートは、対応するセットに追加します:
for link in soup.find_all('a'): # extract link url from the anchor anchor = link.attrs if "href" in link.attrs else ''
if anchor.startswith('/'): local_link = base_url + anchor local_urls.add(local_link) elif strip_base in anchor: local_urls.add(anchor) elif not anchor.startswith('http'): local_link = path + anchor local_urls.add(local_link) else: foreign_urls.add(anchor)
クローラーをローカルアドレスのみに制限したいので、キューに新しいUrlを追加するために次のように追加します:
for i in local_urls: if not i in new_urls and not i in processed_urls: new_urls.append(i)
すべてのUrlをクロールする場合は、次を使用します:
if not link in new_urls and not link in processed_urls: new_urls.append(link)
警告: プログラムが現在動作する方法では、外国のURLをクロールするには非常に長い時間がかかります。 あなたはおそらく許可なしにウェブサイトをこするためのトラブルに入る可能性があります。 ご自身の責任で使用してください!
ここにすべての私のコードがあります:
それはそれでなければなりません。 あなただけのウェブサイトをクロールし、見つかったすべてのUrlをマップするための簡単なツールを作成しました!
結論として
このコードの上に構築し、改善すること自由に感じなさい。 たとえば、クロール時に電子メールアドレスや電話番号をwebページで検索するようにプログラムを変更することができます。 コマンドライン引数を追加して、出力ファイルを定義したり、検索を深さに制限したりするオプションを提供したりすることで、機能を拡張するこ 引数を受け入れるコマンドラインインターフェイスを作成する方法については、こちらを参照してください。