
- GETリクエストを実行するスパイダーを作成し、
- HTMLドキュメントからデータを抽出する
- データの処理とエクスポート。
設置
要件:Python 2.5+(3番目のブランチはサポートされていません)、Twisted、lxmlまたはlibxml2、simplejson、pyopenssl(HTTPSをサポートするため)
Ubuntuをリポジトリから問題なくインストールしました。 インストールガイドページでは、他のLinuxディストリビューションとMac OS XおよびWindowsへのインストールについて説明しています。
挑戦する
おそらく、誰かがオンラインストアを解析し、製品の説明と写真を含むカタログ全体を引き出したいと思うかもしれませんが、私は意図的にそれを行いません。 教育機関のリストなど、いくつかのオープンデータを見てみましょう。 このサイトはかなり典型的であり、いくつかのトリックを示すことができます。
クモを書く前に、ソースサイトを調べる必要があります。 サイトはフレーム(?!)上に構築されていることに注意してください 。フレームセットでは、 開始ページのあるフレームを探しています 。 検索フォームがあります。 モスクワの大学のみが必要なので、適切なフィールドに入力し、[検索]をクリックします。
分析します。 ページごとに15の大学があるページネーションリンクのページがあります。 フィルターパラメーターはGETを介して渡され、ページ値のみが変更されます。
そこで、問題を定式化します。
- abitur.nica.ru/new/www/search.php?region=77&town=0&opf=0&type=0&spec=0&ed_level=0&ed_form=0&qualif=&substr=&page=1に移動します
- 結果のある各ページを移動し、ページの値を変更します
- 大学の説明に移動しますabitur.nica.ru/new/www/vuz_detail.php?code=486®ion=77&town=0&opf=0&type=0&spec=0&ed_level=0&ed_form=0&qualif=&substr=&page=1
- 詳細な大学の説明をCSVファイルに保存する
プロジェクト作成
プロジェクトを配置するフォルダーに移動して作成します。
scrapy startproject abitur cd abitur
プロジェクトのabiturフォルダーには次のファイルがあります。
- items.pyには、収集されるデータのフィールドをリストするクラスが含まれています。
- pipelines.pyを使用すると、スパイダーを開いたり閉じたり、データを保存したり、
- settings.pyには、カスタムスパイダー設定が含まれています。
- スパイダー - スパイダーのクラスを含むファイルが保存されるフォルダー。 通常、各スパイダーは、name_spider.pyという名前の個別のファイルに書き込まれます。
くも
作成されたスパイダー/ abitur_spider.pyファイルで、スパイダーについて説明します
class AbiturSpider(CrawlSpider): name = "abitur" allowed_domains = ["abitur.nica.ru"] start_urls = ["http://abitur.nica.ru/new/www/search.php?region=77&town=0&opf=0&type=0&spec=0&ed_level=0&ed_form=0&qualif=&substr=&page=1"] rules = ( Rule(SgmlLinkExtractor(allow=('search\.php\?.+')), follow=True), Rule(SgmlLinkExtractor(allow=('vuz_detail\.php\?.+')), callback='parse_item'), ) "..."
私たちのクラスはCrawlSpiderから継承されます 。これにより、スパイダーが抽出してそれらをナビゲートするリンクパターンを規定できます。
順番に:
- name-起動に使用されるスパイダーの名前、
- allowed_domains-スパイダーを検索しないサイトのドメイン、
- start_urls-開始アドレスのリスト、
- ルール-リンクを抽出するためのルールのリスト。
お気づきのとおり、ルールの中でパラメーターにはコールバック関数が渡されます。 すぐに彼女に戻ります。
アイテム
前述したように、 items.pyには、収集されるデータのフィールドを列挙するクラスが含まれています。
これは次のように実行できます。
class AbiturItem(Item): name = Field() state = Field() "..."
解析されたデータは、エクスポートの前に処理できます。 たとえば、教育機関は「州」と「非州」であり、この値をブール形式で保存するか、日付「2011年1月1日」を「2011年1月1日」として記述します。
このための入力および出力ハンドラーがあるため、状態フィールドを異なる方法で記述します。
class AbiturItem(Item): name = Field() state = Field(input_processor=MapCompose(lambda s: not re.match(u'\s*', s))) "...."
MapComposeは、状態リストの各要素に適用されます。
ページ上のアイテムを検索する
parse_itemメソッドに戻ります。
アイテムごとに独自のローダーを使用できます。 その目的は、データ処理にも関連しています。
class AbiturLoader(XPathItemLoader): default_input_processor = MapCompose(lambda s: re.sub('\s+', ' ', s.strip())) default_output_processor = TakeFirst() class AbiturSpider(CrawlSpider): "..." def parse_item(self, response): hxs = HtmlXPathSelector(response) l = AbiturLoader(AbiturItem(), hxs) l.add_xpath('name', '//td[@id="content"]/h1/text()') l.add_xpath('state', '//td[@id="content"]/div/span[@class="gray"]/text()') "..." return l.load_item()
この場合、極端で重複したスペースは各フィールドから削除されます。 また、AbiturItemクラスで行った個々のルールをローダーに追加することもできます。
class AbiturLoader(XPathItemLoader): "..." state_in = MapCompose(lambda s: not re.match(u'\s*', s))
だから、あなたが好きなようにしてください。
parse_item()関数はItemオブジェクトを返し、これはPipelineに渡されます(pipelines.pyで説明)。 そこで、標準のScrapy機能では提供されていない形式でデータを保存するための独自のクラスを作成できます。 たとえば、mongodbにエクスポートします。
この要素のフィールドは、 XPathを使用して設定されます。XPathは 、 ここまたはここで読むことができます 。 FirePathを使用する場合、テーブル内にtbodyタグが追加されることに注意してください。 XPathパスを確認するには、組み込みコンソールを使用します。
そしてもう一つの発言。 XPathを使用すると、結果がリストとして返されるため、このリストの最初の要素を取得するTakeFirst出力プロセッサを接続すると便利です。
打ち上げ
ソースコードはここから取得できます。開始するには、プロジェクトフォルダーに移動し、コンソールに入力します。
scrapy crawl abitur --set FEED_URI=scraped_data.csv --set FEED_FORMAT=csv
要するに、私はすべてを説明しましたが、これはScrapyの機能のほんの一部です :
- HTMLおよびXMLデータの取得と取得
- エクスポート前のデータ変換
- JSON、CSV、XML形式にエクスポート
- ファイルのダウンロード
- 独自のミドルウェア、パイプラインを使用したフレームワーク拡張
- POSTリクエストの実行、Cookieおよびセッションのサポート、認証
- ユーザーエージェントのなりすまし
- シェルデバッグコンソール
- ロギングシステム
- ウェブベースの監視
- telnetコンソールを介した管理
1つの記事ですべてを説明することは不可能なので、コメントで質問し、 ドキュメントを読み、Scrapyに関する今後の記事のトピックを提案してください。
GitHubに投稿された実例。