[編集者注] この記事の著者は、Blog Bowl の共同創設者である Shaumik Daityari です。この記事では、主に Web クローリング テクノロジーの基本的な実装原理と手法を紹介しています。この記事は、国内のITOM管理プラットフォームOneAPMによって編集され、提供されています 以下は本文です。
電子商取引の急速な発展に伴い、著者は近年ますます価格比較アプリケーションに魅了されています。私がオンライン (オフラインでも) で行うすべての購入は、主要な電子商取引 Web サイトでの綿密な調査の結果です。
著者がよく使用する価格比較アプリケーションには、RedLaser、ShopSavvy、BuyHatke があります。これらのアプリケーションは価格の透明性を効果的に高め、消費者の時間を大幅に節約します。
しかし、これらのアプリケーションが重要なデータをどのように取得するかについて考えたことがありますか?通常、このタスクは、Web スクレイピング テクノロジーを利用して実行されます。
Webスクレイピングは、Webからデータを抽出するプロセスです。適切なツールを使用すれば、目に見えるあらゆるデータを抽出できます。この記事では、抽出プロセスを自動化し、短期間で大量のデータを収集できるようにするプログラムに焦点を当てます。先ほど述べた使用例に加えて、スクレイピング テクノロジーの用途には、SEO 追跡、求人追跡、ニュース分析、そして私のお気に入りであるソーシャル メディア感情分析が含まれます。
Web スクレイピングの冒険に乗り出す前に、関連する法的問題を必ず理解してください。多くの Web サイトでは、サービス利用規約でコンテンツのクロールを明示的に禁止しています。たとえば、Medium Web サイトには、「Web サイトの robots.txt ファイルの規制に従ってクロールすることは許容されますが、スクレイピングは禁止されています。」と書かれています。クロールを許可していない Web サイトの場合、スクレイピングはブラックリストに登録される可能性があります。他のツールと同様に、Web スクレイピングは Web サイトのコンテンツをコピーするなどの不正な目的に使用される可能性があります。さらに、Web スクレイピングに起因する法的措置も数多くあります。
慎重に作業を進める必要があることを十分に理解したので、Web スクレイピングについて学び始めましょう。実際、Web スクレイピングはどのプログラミング言語でも実装できます。少し前までは、Node.js を使用して実装しました。この記事では、そのシンプルさと豊富なパッケージのサポートを考慮して、Python を使用してクローラーを実装します。
ネットワーク上でサイトを開くと、そのHTMLコードがダウンロードされ、Webブラウザーで解析されて表示されます。この HTML コードには、表示されるすべての情報が含まれています。したがって、HTMLコードを解析することで必要な情報(価格など)を取得することができます。正規表現を使用してデータの海から必要な情報を検索したり、関数ライブラリを使用して HTML を解釈したりすることで、必要なデータを取得することもできます。
Python では、Beautiful Soup というモジュールを使用して HTML データを分析します。 pip などのインストーラーを使用してインストールし、次のコードを実行できます:
pip install beautifulsoup4
または、ソース コードに基づいてビルドすることもできます。詳細なインストール手順は、モジュールのドキュメント ページで確認できます。
インストールが完了したら、大まかに次の手順に従って Web クローリングを実装します:
URL にリクエストを送信します
レスポンスを受信します
レスポンスを分析して必要なデータを見つけます
デモとして、著者のブログ http://dada.theblogbowl.in/ をターゲット URL として使用します。
最初の 2 つのステップは比較的単純で、次のように実行できます:
from urllib import urlopen#Sending the http requestwebpage = urlopen('http://my_website.com/').read()
次に、以前にインストールしたモジュールに応答を渡します:
from bs4 import BeautifulSoup#making the soup! yummy ;)soup = BeautifulSoup(webpage, "html5lib")
ここではパーサーとして html5lib を選択していることに注意してください。 BeautifulSoup のドキュメントによると、別のパーサーを選択することもできます。
HTML を BeautifulSoup に渡した後、いくつかのコマンドを試すことができます。たとえば、HTML マークアップ コードが正しいことを確認して、ページのタイトルを (Python インタープリターで) 検証できます。
>>> soup.title<title>Transcendental Tech Talk</title>>>> soup.title.textu'Transcendental Tech Talk'>>>
次に、ページ内の特定の要素の抽出を開始します。たとえば、ブログの記事タイトルのリストを抽出したいとします。これを行うには、HTML の構造を分析する必要があります。これは Chrome インスペクターを使用して行うことができます。他のブラウザでも同様のツールが提供されています。
Chrome インスペクターを使用してページの HTML 構造をチェックします
ご覧のとおり、すべての投稿タイトルには h3 タグと 2 つのクラス属性 (post-title クラスとentry-title クラス) があります。したがって、post-title クラスを使用してすべての h3 要素を検索すると、そのページの記事タイトルのリストが取得されます。この例では、BeautifulSoup が提供する find_all 関数を使用し、class_ パラメーターを通じて必要なクラスを決定します:
>>> titles = soup.find_all('h3', class_ = 'post-title') #Getting all titles>>> titles[0].textu'\nKolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>
post-title クラスによってのみエントリを検索すると、同じ結果が得られます:
>>> titles = soup.find_all(class_ = 'post-title') #Getting all items with class post-title>>> titles[0].textu'\nKolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips\n'>>>
さらに知りたい場合エントリが指すリンクでは、次のコードを実行できます:
>>> for title in titles:... # Each title is in the form of <h3 ...><a href=...>Post Title<a/></h3>... print title.find("a").get("href")...http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.htmlhttp://dada.theblogbowl.in/2015/09/i-got-published.htmlhttp://dada.theblogbowl.in/2014/12/how-to-use-requestput-or-requestdelete.htmlhttp://dada.theblogbowl.in/2014/12/zico-isl-and-atk.html...>>>
BeautifulSoup には、HTML を操作するのに役立つ多くの組み込みメソッドがあります。これらの方法のいくつかを以下に示します:
>>> titles[0].contents[u'\n', <a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger meet, Marketing Insights, and some Blogging Tips</a>, u'\n']>>>
请注意,你也可以使用 children 属性,不过它有点像 生成器 :
>>> titles[0].parent<div class="post hentry uncustomized-post-template">\n<a name="6501973351448547458"></a>\n<h3 class="post-title entry-title">\n<a href="http://dada.theblogbowl.in/2015/09/kolkata-bergerxp-indiblogger-meet.html">Kolkata #BergerXP IndiBlogger ...>>>
你也可以使用正则表达式搜索 CSS 类,对此, 本文档有详细的介绍 。
目前为止,我们做的只是下载一个页面进而分析其内容。然而,web 开发者可能屏蔽了非浏览器发出的请求,或者有些网站内容只能在登录之后读取。那么,我们该如何处理这些情况呢?
对于第一种情况,我们需要在向页面发送请求时模拟一个浏览器。每个 HTTP 请求都包含一些相关的数据头(header),其中包含了访客浏览器、操作系统以及屏幕大小之类的信息。我们可以改变这些数据头,伪装为浏览器发送请求。
至于第二种情况,为了访问带有访客限制的内容,我们需要登录该网站,使用 cookie 保持会话。下面,让我们来看看在伪装成浏览器的同时,如何完成这一点。
我们将借助 cookielib 模块使用 cookie 管理会话。此外,我们还将用到 mechanize ,后者可以使用 pip 之类的安装程序进行安装。
我们会通过 Blog Bowl 这个页面进行登录,并访问 通知页面 。下面的代码通过行内注释进行了解释:
import mechanizeimport cookielibfrom urllib import urlopenfrom bs4 import BeautifulSoup# Cookie Jarcj = cookielib.LWPCookieJar()browser = mechanize.Browser()browser.set_cookiejar(cj)browser.set_handle_robots(False)browser.set_handle_redirect(True)# Solving issue #1 by emulating a browser by adding HTTP headersbrowser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]# Open Login Pagebrowser.open("http://theblogbowl.in/login/")# Select Login form (1st form of the page)browser.select_form(nr = 0)# Alternate syntax - browser.select_form(name = "form_name")# The first <input> tag of the form is a CSRF token# Setting the 2nd and 3rd tags to email and passwordbrowser.form.set_value("email@example.com", nr=1)browser.form.set_value("password", nr=2)# Logging inresponse = browser.submit()# Opening new page after loginsoup = BeautifulSoup(browser.open('http://theblogbowl.in/notifications/').read(), "html5lib")
通知页面的结构
# Print notificationsprint soup.find(class_ = "search_results").text
登录进通知页面后的结果
许多开发者会告诉你:你在网络上看到的任何信息都可以被抓取。通过这篇文章,你学会了如何轻松抽取登录后才能看到的内容。此外,如果你的 IP 遭到了屏蔽,你可以掩盖自己的 IP 地址(或选用其他地址)。同时,为了看起来像是人类在访问,你应该在请求之间保留一定的时间间隔。
随着人们对数据的需求不断增长,web 抓取(不论原因好坏)技术在未来的应用只会更加广泛。也因此,理解其原理是相当重要的,不管你是为了有效利用该技术,还是为了免受其坑害。
OneAPM 能帮您查看Python 应用程序的方方面面,不仅能够监控终端的用户体验,还能监控服务器性能,同时还支持追踪数据库、第三方 API 和 Web 服务器的各种问题。想阅读更多技术文章,请访问OneAPM 官方技术博客。
原文地址: https://www.sitepoint.com/web-scraping-for-beginners/