2017-11-05 9 views
2

私はプログラミングが初めてで、初めての小さなWebクローラーをPythonでビルドしようとしています。WebCrawler、値引きされたアイテムはほんのわずかです - インデックスエラー

目標:は、商品一覧ページをクロール -

ステータスCSVファイルに保存 - ブランド名、商品名、元の価格と新価格こする:私はブランド名を取得するために管理してきました、記事を元の価格だけでなく、それらを正しい順序でリスト(例えば、10個の製品)に入れる。すべての商品にブランド名、説明、価格があるので、私のコードは正しい順序でCSVに取り込みます。

コード:

import bs4 
    from urllib.request import urlopen as uReq 
    from bs4 import BeautifulSoup as soup 

    myUrl = 'https://www.zalando.de/rucksaecke-herren/' 

    #open connection, grabbing page, saving in page_html and closing connection 
    uClient = uReq(myUrl) 
    page_html = uClient.read() 
    uClient.close() 

    #Datatype, html paser 
    page_soup = soup(page_html, "html.parser") 

    #grabbing information 
    brand_Names = page_soup.findAll("div",{"class": "z-nvg-cognac_brandName-2XZRz z-nvg-cognac_textFormat-16QFn"}) 
    articale_Names = page_soup.findAll ("div",{"class": "z-nvg-cognac_articleName--arFp z-nvg-cognac_textFormat-16QFn"}) 
    original_Prices = page_soup.findAll("div",{"class": "z-nvg-cognac_originalPrice-2Oy4G"}) 
    new_Prices = page_soup.findAll("div",{"class": "z-nvg-cognac_promotionalPrice-3GRE7"}) 

    #opening a csv file and printing its header 
    filename = "XXX.csv" 
    file = open(filename, "w") 
    headers = "BRAND, ARTICALE NAME, OLD PRICE, NEW PRICE\n" 
    file.write(headers) 

    #How many brands on page? 
    products_on_page = len(brand_Names) 

    #Looping through all brands, atricles, prices and writing the text into the CSV 
    for i in range(products_on_page): 
      brand = brand_Names[i].text 
      articale_Name = articale_Names[i].text 
      price = original_Prices[i].text 
      new_Price = new_Prices[i].text 
      file.write(brand + "," + articale_Name + "," + price.replace(",",".") + new_Price.replace(",",".") +"\n") 

    #closing CSV 
    file.close() 

問題:私は右の場所で私のcsvファイルに割引価格を得ることに苦労しています。必ずしもすべての項目は割引があり、私は現在、自分のコードには2つの問題を参照してください。

  1. 私はウェブサイト上の情報を探すために.findAllを使用 - 少ないし、割引製品合計製品があるように、私のnew_Pricesが少ない含まれてい価格(例えば、10製品の3つの価格)。私はリストにそれらを追加することができるなら、私は彼らが最初の3行に表示されると仮定します。どうすれば正しいprodcutsにnew_Pricesを追加することができますか?

  2. 「インデックスエラー:リストインデックスが範囲外です」というエラーが発生しました。これは、10個の製品をループしていますが、new_Pricesではループしていると思われます。 ?それは理にかなって、私の仮定は正しいのですか?

私は非常に感謝しています。

感謝、

トルステン

+0

コードのスクリーンショットを投稿したり、関連するコードをコードブロックにコピーしたりしないでください。 – bgse

+1

も入力例を投稿してください – Guilherme

+0

@bgseをブロックにコードで更新しました –

答えて

0

いくつかの項目は、あなたが確実にリストインデックスを使用することはできません'div.z-nvg-cognac_promotionalPrice-3GRE7'タグがありませんので。
ただし、すべてのコンテナタグ('div.z-nvg-cognac_infoContainer-MvytX')を選択し、findを使用して各アイテムのタグを選択することができます。

from urllib.request import urlopen 
from bs4 import BeautifulSoup as soup 
import csv 

my_url = 'https://www.zalando.de/sporttaschen-reisetaschen-herren/' 
client = urlopen(my_url) 
page_html = client.read().decode(errors='ignore') 
page_soup = soup(page_html, "html.parser") 

headers = ["BRAND", "ARTICALE NAME", "OLD PRICE", "NEW PRICE"] 
filename = "test.csv" 
with open(filename, 'w', newline='') as f: 
    writer = csv.writer(f) 
    writer.writerow(headers) 

    items = page_soup.find_all(class_='z-nvg-cognac_infoContainer-MvytX') 
    for item in items: 
     brand_names = item.find(class_="z-nvg-cognac_brandName-2XZRz z-nvg-cognac_textFormat-16QFn").text 
     articale_names = item.find(class_="z-nvg-cognac_articleName--arFp z-nvg-cognac_textFormat-16QFn").text 
     original_prices = item.find(class_="z-nvg-cognac_originalPrice-2Oy4G").text 
     new_prices = item.find(class_="z-nvg-cognac_promotionalPrice-3GRE7") 
     if new_prices is not None: 
      new_prices = new_prices.text 
     writer.writerow([brand_names, articale_names, original_prices, new_prices]) 

ページあたり24の以上の項目を取得したい場合はseleniumのように、JSを実行するクライアントを使用する必要があります。

from selenium import webdriver 
from bs4 import BeautifulSoup as soup 
import csv 

my_url = 'https://www.zalando.de/sporttaschen-reisetaschen-herren/' 
driver = webdriver.Firefox() 
driver.get(my_url) 
page_html = driver.page_source 
driver.quit() 
page_soup = soup(page_html, "html.parser") 
... 

脚注:
は、関数や変数のためのnaming conventionsは、アンダースコアと小文字されます。
csvファイルを読み書きするときは、csv libを使用することをお勧めします。
ファイルを処理するときには、withステートメントを使用できます。

+0

こんにちは@ t.m.adam、多くのご意見とご提案をいただきました!私は最終的に自分で取得しましたが、あなたのコードはもっときれいに見えます! 1つは、ページ上に24個以上のアイテムがあるので、ページが変更されている必要があることに気づいたと思います。奇妙なことに、クローラを実行すると、それは24個のアイテムしか選択しません。どんな考え? –

+0

はい、残りのアイテムはjsによって読み込まれます。ブラウザでjsを無効にしてそのページにアクセスすると、これをテストできます。すべてのアイテムを 'selenium 'で取得することも、時にはajax apiで取得することもできます。私は自由な時間があるときに例を掲示します。 –

+0

こんにちは、@ t.m.adam、素晴らしい!ありがとう!興味のないところでは、そのようにページを設定するのはなぜですか(それらの24個のアイテムを読み込み、残りをJS経由で読み込む)?ありがとう、T –

関連する問題