マイscrapyクローラは、正しくデバッグ出力が示すように、すべてのフィールドを読み取りますScrapyのCSV出力「ランダム」不足している分野
2017-01-29 02:45:15 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.willhaben.at/iad/immobilien/mietwohnungen/niederoesterreich/krems-an-der-donau/altbauwohnung-wg-geeignet-donaublick-189058451/>
{'Heizung': 'Gasheizung', 'whCode': '189058451', 'Teilmöbliert/Möbliert': True, 'Wohnfläche': '105', 'Objekttyp': 'Zimmer/WG', 'Preis': 1050.0, 'Miete (inkl. MWSt)': 890.0, 'Stockwerk(e)': '2', 'Böden': 'Laminat', 'Bautyp': 'Altbau', 'Zustand': 'Sehr gut/gut', 'Einbauküche': True, 'Zimmer': 3.0, 'Miete (exkl. MWSt)': 810.0, 'Befristung': 'nein', 'Verfügbar': 'ab sofort', 'zipcode': 3500, 'Gesamtbelastung': 1150.0}
が、私はCSV出力をコマンドラインオプション
scrapy crawl mietwohnungen -o mietwohnungen.csv --logfile=mietwohnungen.log
いくつかを使用して出力ファイルの対応する行に次のようなフィールドが表示されます。
Keller,whCode,Garten,Zimmer,Terrasse,Wohnfläche,Parkplatz,Objekttyp,Befristung,zipcode,Preis
,189058451,,3.0,,105,,Zimmer/WG,nein,3500,1050.0
例は次のとおりです。Heizung, Teilmöbliert/Möbliert, Miete (inkl. MWSt), Stockwerk(e), Böden, Bautyp, Zustand, Einbauküche, Miete (exkl. MWSt), Verfügbar, Gesamtbelastung
これは、私が擦ったいくつかの値で起こります。注目すべきは、すべてのページに同じフィールドが含まれているわけではないため、ページに応じてフィールド名が生成されるということです。私は存在するすべてのフィールドと最後にyield
を含む辞書を作成します。これは、DEBUGの出力が示すように機能します。ただし、一部のcsv列は印刷されていないようです。
他のページに明らかにこれらのフィールドがあるため(「Keller」の例のように)、一部の列は空白になっています。
私は(結果では問題のページの一部を維持しながら、例えば私のイニシャルサーチ選択を絞り込む)こすりする小さなリストを使用する場合スクレーパー作品:
Heizung,Zimmer,Bautyp,Gesamtbelastung,Einbauküche,Miete (exkl. MWSt),Zustand,Miete (inkl. MWSt),zipcode,Teilmöbliert/Möbliert,Objekttyp,Stockwerk(e),Böden,Befristung,Wohnfläche,whCode,Preis,Verfügbar
Gasheizung,3.0,Altbau,1150.0,True,810.0,Sehr gut/gut,890.0,3500,True,Zimmer/WG,2,Laminat,nein,105,189058451,1050.0,ab sofort
私はすでに任意のを避けるためのpython3に変更されましたユニコード文字列の問題。
これはバグですか?これはまた、すべてのフィールドがxmlに出力された場合にのみcsv出力に影響するようです。
なぜ完全なリストでは機能しないのかわかりません。本当にCSVエクスポータを手動で作成する唯一のソリューションはありますか?
編集:SOLUTION @ mizhgunのanswerに基づく:
私はCSV出力を書き込み、アイテムのパイプラインを作成しました。すべてのアイテムを反復処理すると、一意のキーのセットが格納され、最後にcsvファイルが書き込まれます。あなたは辞書のようにスクレイプ結果を得た場合
pipelines.py
import csv
import logging
class CsvWriterPipeline(object):
def open_spider(self, spider):
self.file = open('mietwohnungen.csv', 'w', newline='')
#if python < 3 use
#self.file = open('mietwohnungen.csv', 'wb')
self.items = []
self.colnames = []
def close_spider(self, spider):
csvWriter = csv.DictWriter(self.file, fieldnames = self.colnames)#, delimiter=',')
logging.info("HEADER: " + str(self.colnames))
csvWriter.writeheader()
for item in self.items:
csvWriter.writerow(item)
self.file.close()
def process_item(self, item, spider):
# add the new fields
for f in item.keys():
if f not in self.colnames:
self.colnames.append(f)
# add the item itself to the list
self.items.append(item)
return item
settings.py
ITEM_PIPELINES = {
'willhaben.pipelines.CsvWriterPipeline': 300,
}
たとえば、私はデバッグ出力で 'Keller'カラムを見ることができず、逆に'Teilmöbliert/Möbliert'をCSVカラムとして見ることができません。あなたが列とフィールドを混乱させたように見えますが、あなたのプロジェクトで 'FEED_EXPORT_FIELDS'設定を使用していますか? – mizhgun
はい、私は言葉の列とフィールドを同じ意味で使用していますので、同じ意味です。ただし、一部のフィールドは列として出力されません。私が説明したように、csvに 'Keller'カラムがありますが、この特定のエントリのデバッグ出力にはない理由は、他のエントリにはKellerフィールドがありますが、この特定のものはありません。 (私はこの記事の多くのcsv行のうちの1つだけを表示しています) – MoRe
また、フィールドの名前がわからないので、私は 'FEED_EXPORT_FIELDS'を使っていません。ページ)と私は彼らが印刷されている順序には気にしません。 csvの出力に 'Teilmöbliert/Möbliert'という名前の列がないのはまさに私の質問です;-)明らかに小さな同じコードを使用してリスト... – MoRe