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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

Scrapy

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

Q&A

解決済

1回答

1319閲覧

scrapyで上手くjsonファイルに保存できない問題について

trafalbad

総合スコア303

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

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

Scrapy

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

0グッド

0クリップ

投稿2018/04/08 08:17

scrapyで食べログないのデータを取得しようとして以下のようにItemとspiderを作成し、

scrapy crawl tabelog -o retaurants.jl

をコマンド実行しました。一応、retaurants.jlファイルは作成されるのですが、抽出内容が記述されずに、ファイルのみ作成されます。

何か問題があるのでしょうか?ご教授お願いします。

Item(item.py)

import json import scrapy class Restaurant(scrapy.Item): """ 食べログのレストラン情報 """ name = scrapy.Field() # spaiderのresponse.css()で取得したデータを保存するItemを作成 address = scrapy.Field() latitude= scrapy.Field() logitude = scrapy.Field() station = scrapy.Field() score = scrapy.Field()

spider(spiders/tabelog.py)

python

1from scrapy.spiders import CrawlSpider, Rule 2# CrawlSpider:定期的なウェブサイトをクロールするために最も一般的に使用されるスパイダー. 3# 一連のルールを定義してリンクをたどるための便利なメカニズムを提供. 4# CrawlSpiderの例はhttp://scrapy-ja.readthedocs.io/ja/latest/topics/spiders.html 5import re 6from scrapy.linkextractors import LinkExtractor 7from myproject.items import Restaurant 8 9class TabelogSpider(CrawlSpider): 10 name = "tabelog" # スパイダーの名前(ドメイン名)と同じの名前を付ける 11 allowed_domains = ["tabelog.com"] 12 start_urls =('http://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1',) 13 # ↑クロールを開始するURLのリスト.ダウンロードされる最初のページはここにリストされたページになる 14 15 rules = [ # トピックへのルールをたどり、レスポンスをcallback関数で処理する。 16 # allowで正規表現にマッチしたURL「一覧ページ(P272)」の1~9ページまで抽出。。\dを\d+に変えると10ページ目以降も辿れる。 17 Rule(LinkExtractor(allow=r'/\w+/rstLst/lunch/\d'), follow=True), 18 19 # レストランの「詳細ページ(P272)」をたどり、parse_retaurant()でパース(処理)する] 20 Rule(LinkExtractor(allow=r'/\w+/A\d+/A\d+/\d+/$'), callback='parse_restaurant'),] 21 # リンクをたどるためのルールリスト。各Ruleは, サイトをクロールするための特定の動作を定義 22 23 def parse_restaurant(self, response): 24 """ 25 レストランの詳細ページをパースする 26 """ 27 # Google Static Mapの画像のURLから緯度と軽度を取得 28 latitude, longitude = response.css('img.js-map-lazyload::attr("data-original")').re( 29 r'makers=.*?%7C([\d.]+),([\d.]+)') 30 31 # キー(Itemで作成したscrapy.field())の値を指定して、ItemのclassのRestaurantオブジェクトを作成 32 item = Resraurant( 33 name=renponse.css('.display-name').xpath('string()').extract_first().strip(), 34 adress=renponse.css('[rel="v:address"]').xpath('string()').extract_first().strip(), 35 latitude=latitude, 36 longitude=longitude, 37 station=renponse.css('dt:contains("最寄り駅")+dd span::text').extract_first(), 38 score=renponse.css('[property="v:average"]::text').extract_first(),) 39 40 yield item 41

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

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

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

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

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

guest

回答1

0

ベストアンサー

python

1import scrapy 2 3 4class Restaurant(scrapy.Item): 5 name = scrapy.Field() 6 address = scrapy.Field() 7 latitude = scrapy.Field() 8 longitude = scrapy.Field() 9 station = scrapy.Field() 10 score = scrapy.Field()

python

1from scrapy.spiders import CrawlSpider, Rule 2import re 3from scrapy.linkextractors import LinkExtractor 4from myproject.items import Restaurant 5 6 7class TabelogSpider(CrawlSpider): 8 name = "tabelog" 9 allowed_domains = ["tabelog.com"] 10 start_urls = ( 11 'http://tabelog.com/tokyo/rstLst/lunch/?LstCosT=2&RdoCosTp=1',) 12 13 rules = [ 14 # 9ページ以上抽出してしまうので最後に'/'を追加 15 Rule(LinkExtractor(allow=r'/\w+/rstLst/lunch/\d/'), follow=True), 16 17 Rule(LinkExtractor(allow=r'/\w+/A\d+/A\d+/\d+/$'), callback='parse_restaurant'), ] 18 19 def parse_restaurant(self, response): 20 21 # 取得できていなかったですが単純にtypoでした(makers -> markers) 22 latitude, longitude = response.css('img.js-map-lazyload::attr("data-original")').re( 23 r'markers=.*?%7C([\d.]+),([\d.]+)') 24 25 # addressが取得できていなかったので修正 26 prefectures = response.css( 27 'p.rstinfo-table__address span a::text').extract() 28 street_number = response.css( 29 'p.rstinfo-table__address span::text').extract() 30 31 item = Restaurant( 32 name=response.css( 33 '.display-name').xpath('string()').extract_first().strip(), 34 address=''.join(prefectures + street_number), 35 latitude=latitude, 36 longitude=longitude, 37 station=response.css( 38 'dt:contains("最寄り駅")+dd span::text').extract_first(), 39 40 # scoreもNoneで返ってきたので修正 41 score=response.css('span.rdheader-rating__score-val-dtl::text').extract_first(), 42 ) 43 44 yield item 45

とりあえず修正してみました。
修正箇所と理由はコメントで書いてあります。
他にもtypoが沢山ありましたが、そちらで確認してください。

追記
settings.pyにFEED_EXPORT_ENCODING = 'utf-8'を書かないと日本語で抽出できませんでした。

投稿2018/04/08 15:07

編集2018/04/08 15:15
bluevinyl

総合スコア129

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

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

trafalbad

2018/04/08 20:29

ありがとうございます!教えて頂きたいのですが、scrapyでaddressの項目なのですが、必要と判断したのは何か参考になるサイトや資料等あったのでしょうか?判断材料になったものや理由がありましたら教えて下さい!
bluevinyl

2018/04/08 22:18

プログラムでなにか問題があったとき基本的にエラーログを見ないと修正箇所はわからないです。 今回は怪しいところにprintデバッグを使って値が取得できているか確認。 chromeのデベロッパーツールで検索してCSSの指定という泥臭いやり方で修正しました。 私自身cssやxpath、デベロッパーツールについて薄い知識しかないので、もっとスマートなやり方があると思います。 scrapyは以前、私も食べログで一度だけ使ったことがあるので分かるかなと思い回答に挑戦してみました。 なので、知識は公式のチュートリアルを終えた程度のものです。
trafalbad

2018/04/10 13:56

ありがとうございます。とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問