Scrapyシェル¶
Scrapyシェルは、スパイダーを実行することなく、非常に迅速にスクレイピングコードを試行およびデバッグできる対話型シェルです。これは、データ抽出コードのテストに使用することを目的としていますが、通常のPythonシェルでもあるため、実際にはあらゆる種類のコードのテストに使用できます。
シェルは、XPath式またはCSS式をテストし、それらがどのように機能するか、およびスクレイピングしようとしているWebページからどのようなデータを抽出するかを確認するために使用されます。すべての変更をテストするためにスパイダーを実行する必要なく、スパイダーを作成している間に式をインタラクティブにテストできます。
Scrapyシェルに親しむと、スパイダーを開発およびデバッグするための非常に素晴らしいツールであることがわかります。
シェルの構成(configure)¶
IPython がインストールされている場合、Scrapyシェルは(標準のPythonコンソールの代わりに)それを使用します。 IPython コンソールははるかに強力で、とりわけスマートなオートコンプリートとカラー化された出力を提供します。
特に、( IPython が優れている)Unixシステムで作業している場合は、 IPython をインストールすることを強くお勧めします。 詳細については、 IPython installation guide を参照してください。
Scrapyは bpython もサポートしており、 IPython が利用できない場合はそれを使用しようとします。
Scrapyの設定により、インストールされているかどうかに関係なく、 ipython
または bpython
または、標準の python
シェルのいずれかを使用するように設定できます。 これには SCRAPY_PYTHON_SHELL
環境変数を設定するか、または scrapy.cfg で定義することにより行います。
[settings]
shell = bpython
シェルを起動する¶
Scrapyシェルを起動するには、次のように shell
コマンドを使用します:
scrapy shell <url>
<url>
は、あなたがスクレイプしたいURLです。
shell
はローカルファイルでも機能します。 これは、Webページのローカルコピーで遊んでみたい場合に便利です。 shell
はローカルファイルの次の構文を理解します:
# UNIX-style
scrapy shell ./path/to/file.html
scrapy shell ../other/path/to/file.html
scrapy shell /absolute/path/to/file.html
# File URI
scrapy shell file:///absolute/path/to/file.html
注釈
相対ファイルパスを使用する場合は、明示的に指定し、 ./
(または関連する場合は ../
)を先頭に追加します。 scrapy shell index.html
はあなたの予想どおりに機能しません(これは設計によるものであり、バグではありません)。
なぜなら、 shell
はファイルURIよりもHTTP URLを優先し、 index.html
は構文的に example.com
に似ているため、 shell
は index.html
をドメイン名とみなしてDNSルックアップし、エラーをトリガします:
$ scrapy shell index.html
[ ... scrapy shell starts ... ]
[ ... traceback ... ]
twisted.internet.error.DNSLookupError: DNS lookup failed:
address 'index.html' not found: [Errno -5] No address associated with hostname.
shell
は index.html
というファイルが現在のディレクトリに存在するかどうかを事前にテストしません。繰り返しますが、明示的に指定してください。
シェルの使用¶
Scrapyシェルは、全くもってPythonコンソール(または、使用可能な場合は IPython コンソール)です。そして、便利な追加のショートカット機能を提供します。
利用可能なショートカット¶
shelp()
- 利用可能なオブジェクトとショートカットのリストを含むヘルプを出力しますfetch(url[, redirect=True])
- 指定されたURLから新しいリクエストを取得し、それに応じてすべての関連オブジェクトを更新します。 HTTP 3xxリダイレクトの後にredirect=False
を渡さないようにオプションで要求できますfetch(request)
- 特定のリクエストから新しいレスポンスを取得し、それに応じてすべての関連オブジェクトを更新します。view(response)
- 検査のために、指定されたレスポンスをローカルWebブラウザーで開きます。 これにより、外部リンク(画像やスタイルシートなど)が正しく表示されるように、 <base> tag がレスポンス・ボディに追加されます。 ただし、これによりコンピューターに一時ファイルが作成され、自動的には削除されないことに注意してください。
シェル セッション の例¶
ここで、 https://scrapy.org ページをスクレイピングすることから始めて、 次に、 https://old.reddit.com/ ページのスクレイピングに進む、典型的なシェルセッションの例を以下に示します。 そして最後に、(Reddit)リクエストメソッドをPOSTに変更し、エラーを取得して再フェッチします。セッションを終了するには、Ctrl-D(Unixシステムの場合)、WindowsではCtrl-Zを入力します。
これらのページは静的ではなく、テストするまでに変更されている可能性があるため、ここで抽出したデータは同じではない可能性があることに注意してください。 この例の唯一の目的は、Scrapyシェルの仕組みを理解してもらうことです。
まず、私たちはシェルを起動します:
scrapy shell 'https://scrapy.org' --nolog
注釈
コマンドラインから Scrapy シェルを実行するときは、常に URL を引用符で囲むことを忘れないでください。そうしないと、引数を含む URL (例えば &
文字を含むURL)が機能しません。
Windows では、代わりに二重引用符を使用してください:
scrapy shell "https://scrapy.org" --nolog
次に、シェルは(Scrapyダウンローダーを使用して)URLを取得し、使用可能なオブジェクトと便利なショートカットのリストを出力します(これらの行はすべて [s]
接頭辞で始まることがわかります):
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x7f07395dd690>
[s] item {}
[s] request <GET https://scrapy.org>
[s] response <200 https://scrapy.org/>
[s] settings <scrapy.settings.Settings object at 0x7f07395dd710>
[s] spider <DefaultSpider 'default' at 0x7f0735891690>
[s] Useful shortcuts:
[s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s] fetch(req) Fetch a scrapy.Request and update local objects
[s] shelp() Shell help (print this help)
[s] view(response) View response in a browser
>>>
その後、オブジェクトで遊んでみましょう:
>>> response.xpath('//title/text()').get()
'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'
>>> fetch("https://old.reddit.com/")
>>> response.xpath('//title/text()').get()
'reddit: the front page of the internet'
>>> request = request.replace(method="POST")
>>> fetch(request)
>>> response.status
404
>>> from pprint import pprint
>>> pprint(response.headers)
{'Accept-Ranges': ['bytes'],
'Cache-Control': ['max-age=0, must-revalidate'],
'Content-Type': ['text/html; charset=UTF-8'],
'Date': ['Thu, 08 Dec 2016 16:21:19 GMT'],
'Server': ['snooserv'],
'Set-Cookie': ['loid=KqNLou0V9SKMX4qb4n; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
'loidcreated=2016-12-08T16%3A21%3A19.445Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
'loid=vi0ZVe4NkxNWdlH7r7; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
'loidcreated=2016-12-08T16%3A21%3A19.459Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure'],
'Vary': ['accept-encoding'],
'Via': ['1.1 varnish'],
'X-Cache': ['MISS'],
'X-Cache-Hits': ['0'],
'X-Content-Type-Options': ['nosniff'],
'X-Frame-Options': ['SAMEORIGIN'],
'X-Moose': ['majestic'],
'X-Served-By': ['cache-cdg8730-CDG'],
'X-Timer': ['S1481214079.394283,VS0,VE159'],
'X-Ua-Compatible': ['IE=edge'],
'X-Xss-Protection': ['1; mode=block']}
スパイダーからシェルを呼び出してレスポンスを検査する¶
あなたが期待するレスポンスがそこに到達していることを確認するためだけに、スパイダーの特定のポイントで処理されているレスポンスを検査したい場合があります。
これは scrapy.shell.inspect_response
関数を使用することで実現できます。
スパイダーから呼び出す方法の例を次に示します:
import scrapy
class MySpider(scrapy.Spider):
name = "myspider"
start_urls = [
"http://example.com",
"http://example.org",
"http://example.net",
]
def parse(self, response):
# We want to inspect one specific response.
if ".org" in response.url:
from scrapy.shell import inspect_response
inspect_response(response, self)
# Rest of parsing code.
スパイダーを実行すると、次のようなものが得られます:
2014-01-23 17:48:31-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.com> (referer: None)
2014-01-23 17:48:31-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.org> (referer: None)
[s] Available Scrapy objects:
[s] crawler <scrapy.crawler.Crawler object at 0x1e16b50>
...
>>> response.url
'http://example.org'
そこから、抽出コードが機能しているかどうかを確認できます:
>>> response.xpath('//h1[@class="fn"]')
[]
Orz。期待したとおりではありません。 したがって、あなたはWebブラウザーでレスポンスを開き、それが期待したレスポンスかどうかを確認できます:
>>> view(response)
True
最後に、Ctrl-D(WindowsではCtrl-Z)を押してシェルを終了し、クロールを再開します:
>>> ^D
2014-01-23 17:50:03-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.net> (referer: None)
...
Scrapyエンジンはシェルによってブロックされているため、ここでは fetch
ショートカットを使用できないことに注意してください。 ただし、上記のように、シェルを離れた後、スパイダーは停止した場所からクロールを続けます。