質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

Q&A

解決済

3回答

4901閲覧

Pythonクローリング&スクレイピングのサンプルコードを実行したが、エラーが発生する

nozomu.i

総合スコア8

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

0グッド

0クリップ

投稿2017/08/16 07:34

編集2017/08/17 06:30

###前提・実現したいこと
Pythonクローリング&スクレイピング ―データ収集・解析のための実践開発ガイド―
http://gihyo.jp/book/2017/978-4-7741-8367-1/support
上記のサンプルコードをダウンロードし、6-7のtabelogというプログラムを実行しましたが、エラーが発生しました。

###前提・実現したいこと
食べログに掲載されている情報をcsvのリストにしたい。

###発生している問題・エラーメッセージ

(scraping3.4) NozomuI-no-MacBook:6-7 nozomui$ scrapy crawl tabelog -o a.csv 2017-08-17 15:08:56 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: myproject) 2017-08-17 15:08:56 [scrapy.utils.log] INFO: Overridden settings: {'BOT_NAME': 'myproject', 'SPIDER_MODULES': ['myproject.spiders'], 'DOWNLOAD_DELAY': 1, 'FEED_FORMAT': 'csv', 'FEED_URI': 'a.csv', 'ROBOTSTXT_OBEY': True, 'NEWSPIDER_MODULE': 'myproject.spiders'} 2017-08-17 15:08:56 [scrapy.middleware] INFO: Enabled extensions: ['scrapy.extensions.feedexport.FeedExporter', 'scrapy.extensions.memusage.MemoryUsage', 'scrapy.extensions.logstats.LogStats', 'scrapy.extensions.telnet.TelnetConsole', 'scrapy.extensions.corestats.CoreStats'] 2017-08-17 15:08:56 [scrapy.middleware] INFO: Enabled downloader middlewares: ['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware', 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 'scrapy.downloadermiddlewares.retry.RetryMiddleware', 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware', 'scrapy.downloadermiddlewares.stats.DownloaderStats'] 2017-08-17 15:08:56 [scrapy.middleware] INFO: Enabled spider middlewares: ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware', 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware', 'scrapy.spidermiddlewares.referer.RefererMiddleware', 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware', 'scrapy.spidermiddlewares.depth.DepthMiddleware'] 2017-08-17 15:08:56 [scrapy.middleware] INFO: Enabled item pipelines: [] 2017-08-17 15:08:56 [scrapy.core.engine] INFO: Spider opened 2017-08-17 15:08:56 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 2017-08-17 15:08:56 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6026 2017-08-17 15:08:57 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://tabelog.com/robots.txt> (referer: None) 2017-08-17 15:08:58 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1> (referer: None) 2017-08-17 15:09:00 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://tabelog.com/tokyo/rstLst/lunch/2/?LstCosT=2&RdoCosTp=1> (referer: https://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1) 2017-08-17 15:09:00 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET https://tabelog.com/tokyo/rstLst/lunch/2/?LstCosT=2&RdoCosTp=1> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates) 2017-08-17 15:09:01 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://tabelog.com/tokyo/A1309/A130902/13000852/> (referer: https://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1) 2017-08-17 15:09:01 [scrapy.core.scraper] ERROR: Spider error processing <GET https://tabelog.com/tokyo/A1309/A130902/13000852/> (referer: https://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1) Traceback (most recent call last): File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/utils/defer.py", line 102, in iter_errback yield next(it) File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/spidermiddlewares/offsite.py", line 29, in process_spider_output for x in result: File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/spidermiddlewares/referer.py", line 339, in <genexpr> return (_set_referer(r) for r in result or ()) File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/spidermiddlewares/urllength.py", line 37, in <genexpr> return (r for r in result or () if _filter(r)) File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/spidermiddlewares/depth.py", line 58, in <genexpr> return (r for r in result or () if _filter(r)) File "/Users/nozomui/.pyenv/versions/3.4.6/lib/python3.4/site-packages/scrapy/spiders/crawl.py", line 78, in _parse_response for requests_or_item in iterate_spider_output(cb_res): File "/Users/nozomui/scraping3.4/6-7/myproject/spiders/tabelog.py", line 38, in parse_restaurant address=response.css('[rel="address"]').xpath('string()').extract_first().strip(), AttributeError: 'NoneType' object has no attribute 'strip' ^Z [4]+ Stopped scrapy crawl tabelog -o a.csv

###該当のソースコード

python

1from scrapy.spiders import CrawlSpider, Rule 2from scrapy.linkextractors import LinkExtractor 3 4from myproject.items import Restaurant 5 6 7class TabelogSpider(CrawlSpider): 8 name = "tabelog" 9 allowed_domains = ["tabelog.com"] 10 start_urls = ( 11 # 東京の昼のランキングのURL。 12 # 普通にWebサイトを見ていると、もっとパラメーターが多くなるが、 13 # ページャーのリンクを見ると、値が0のパラメーターは省略できることがわかる。 14 'https://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1', 15 ) 16 17 rules = [ 18 # ページャーをたどる(最大9ページまで)。 19 # 正規表現の \d を \d+ に変えると10ページ目以降もたどれる。 20 Rule(LinkExtractor(allow=r'/\w+/rstLst/lunch/\d/')), 21 # レストランの詳細ページをパースする。 22 Rule(LinkExtractor(allow=r'/\w+/A\d+/A\d+/\d+/$'), 23 callback='parse_restaurant'), 24 ] 25 26 def parse_restaurant(self, response): 27 """ 28 レストランの詳細ページをパースする。 29 """ 30 # Google Static Mapsの画像のURLから緯度と経度を取得。 31 latitude, longitude = response.css( 32 'img.js-map-lazyload::attr("data-original")').re( 33 r'markers=.*?%7C([\d.]+),([\d.]+)') 34 35 # キーの値を指定してRestaurantオブジェクトを作成。 36 item = Restaurant( 37 name=response.css('.display-name').xpath('string()').extract_first().strip(), 38 address=response.css('[rel="address"]').xpath('string()').extract_first().strip(), 39 latitude=latitude, 40 longitude=longitude, 41 station=response.css('dt:contains("最寄り駅")+dd span::text').extract_first(), 42 score=response.css('[rel="v:rating"] span::text').extract_first(), 43 ) 44 45 yield item 46

###試したこと
python3.4.6で実行しました。scrapyのバージョンは1.4.0です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nozomu.i

2017/08/17 06:49

書式を改善しました。
guest

回答3

0

AttributeError: 'NoneType' object has no attribute 'strip'`

とエラーがでるのは、addressのスクレイピングに失敗している(結果が0件)ためであると考えられます。
試しに、ブラウザの開発者ツールでaddress取得用のcssセレクタを使ってみたところ
やはり該当件数は0件でした。

おそらくサイト側の仕様変更のためこのようになったのだと思います。
手元に『Pythonクローリング&スクレイピング ―データ収集・解析のための実践開発ガイド―』がないため、
addressが具体的にどんな値をさしているのかわかりませんが、
もし教えていただければ、それを抜き出すための手段をアドバイスできると思います。

投稿2017/08/17 21:23

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nozomu.i

2017/08/18 09:27

丁寧な回答ありがとうございます。 その通りで、scrapyのshellでプログラムのaddress(?)を選択してみたところ、認識していませんでした。 https://tabelog.com/tokyo/A1309/A130902/13000852/ 上記のページをサンプルにプログラムを考えていて、例えば店名を取得したいとします。shellで >>> response.css('#contents-rstdata > div.rstinfo-table > table:nth-child(2) > tbody > tr:nth-child(1) > td').extract_first() とすると取得されず、 >>> response.xpath('//*[@id="contents-rstdata"]/div[3]/table[1]/tbody/tr[1]/td/text()').extract_first(), とすると文字は取得され、プログラムも実行されるのですが、csvには _______________________ <td> すし匠 (すししょう) </td> ____________________________ と表示され、余計な部分まで取得されるようです。cssとxpathどちらを選ぶと良いのか。また、xpathで洗濯した際にテキストの部分だけcsvに保存されるようにするにはどのようにすれば良いのでしょうか。
nozomu.i

2017/08/18 09:35

すみません。cssで「選択」した際もxpathと同様に表示されました。
guest

0

ベストアンサー

返答が長くなってしまったので、回答をわけさせていただきます。

addressに関しては、今回は取得しないということでよろしいのでしょうか?

以下、ご質問への返答。

まず余計な空白を乗り除く方法ですが、

  1. xpath関数の**normalize-space()**を使う
  2. pythonの文字列処理関数(strip,replaceなど)で取り除く

の2通りあると思います。

1の方法を使うと、
例えば、ご質問のxpathでの抽出例は

response.xpath('normalize-space(//*[@id="contents-rstdata"]/div[3]/table[1]/tbody/tr[1]/td)').extract_first()

のように変えればよいです。
なおブラウザの開発者ツールのコンソールではこの関数は正常に動作しなかったので、scrapyを使って確認してみてください。
この**normalize-space()**という関数は、xpathで指定したタグについて、文字列の前後からスペースをとった文字列を返す関数
です。(XPath簡易リファレンスより)
ただし、抽出対象の文字列に全角スペースが混じっていた場合などは、余計な空白がうまく取り除けない場合があります。
その場合、2の方法を使ってください。

ちなみに、サンプルコードはaddress以外に関しては正常に抽出できているようですので、
他のフィールドのxpathを変更する必要は(関数を追加することを除けば)ありません。
私はサンプルのような書き方はしませんが、店名の取得部分は、サンプルのままで構わないと思います。

もう一点、cssセレクタとxpathどちらを選ぶべきかという点に関してですが、
一部xpathを使わないとできない指定の方法があるという点、
またxpath関数など機能が豊富であるという点から、
私はxpathを選ぶことをおすすめします。

最後の質問の、

xpathで洗濯(選択?)した際にテキストの部分だけcsvに保存されるようにするにはどのようにすれば良いのでしょうか

については、質問の意味がよくわからなかったので、もう少し敷衍して説明していただけますか?
もし店名(サンプルコードのnameに対応)のことをいっているのでしたら、
上述の通り抜き出せば、そのまま他のフィールドの値も含めcsvに書き出されるはずです。
addressの部分を放っておくとスクレイピング自体に失敗してしまうので、書き出されませんが。

投稿2017/08/18 14:56

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nozomu.i

2017/08/19 07:55

一つでもパスを間違えているとスクレイピングに失敗してしまうのですね。ひとまず、 address=response.css('.rstinfo-table__address').xpath('string()').extract_first().strip(), とする事スクレイピングはうまく行きました。 xpathだけを指定してスクレイピングする方法として、 address=response.xpath('normalize-space(//*[@id="contents-rstdata"]/div[3]/table[1]/tbody/tr[5]/td/p)').extract_first(), とするとほぼうまくいくのですが、なぜか取得されない住所がいくつかあって、原因は不明です。。 ひとまず、スクレイピンングには成功したのでTkatayamaさんをベストアンサーとさせていただきます。ありがとうございました。
guest

0

サンプルプロジェクトダウンロードしてみましたが、README.mdに「動作環境: Python 3.4および3.5で動作確認を行っています。」と記載されています。
ただエラー内容を見る限り、pyenvでPython3.6.1をご使用されているみたいなので、Python3.4を入れ直して実行されてみてはいかがでしょうか??

投稿2017/08/16 09:23

k.takeuchi

総合スコア92

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nozomu.i

2017/08/17 06:50

python3.4.6で実行してみましたが、AttributeError: 'NoneType' object has no attribute 'strip' と表示されて何も情報がないcsvが作成されただけでした。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問