2017-07-16 5 views
1

私はレストランの食品衛生スクレーパーに取り組んでいます。私は郵便番号に基づいてレストランの名前、住所、衛生状態を掻き集めるスクレーパーを手に入れることができました。食品衛生は画像を介してオンラインで表示されるので、スクレーパーは食品衛生スコアの数値を含む「alt =」パラメーターを読むように設定しました。不正な値が出力されています(Python3、Beautiful Soup 4)

私は食品衛生評価のための目標のIMG ALTタグを含むdiv要素を以下に示します。

<div class="rating-image" style="clear: right;"> 
      <a href="/business/abbey-community-college-newtownabbey-antrim-992915.html" title="View Details"> 
       <img src="https://images.scoresonthedoors.org.uk//schemes/735/on_small.png" alt="5 (Very Good)"> 
      </a> 
     </div> 

私は、各レストランの横に出力する食品衛生スコアを取得することができました。

私の問題は、レストランのいくつかに間違った読みが表示されていることに気づいたことです。 3の代わりに、食品衛生評価のための4(これは、IMGのALTタグに格納される)

スクレーパーが最初にこすりするために接続するリンクは、私はそれが何かを持っているかもしれないと思う

https://www.scoresonthedoors.org.uk/search.php?name=&address=&postcode=BT367NG&distance=1&search.x=16&search.y=21&gbt_id=0

です"g_data forループ内のアイテム"内のループの定格の位置で行います。

私は、データが正しい衛生スコアを正しく削られ

for rating in ratings: 
       bleh = rating['alt'] 

以下ループの外側のコードの

appendhygiene(scrape=[name,address,bleh]) 

作品を移動した場合、唯一の問題は、そのすべてではないです、私を発見しましたレコードはスクレーピングされ、この場合は最初の9店舗のみが出力されます。

下記の私のコードを見て、問題を解決するための助けとなる人に感謝します。

PS郵便番号BT367NGを使用してレストランを擦った(スクリプトをテストした場合、適切な衛生値を表示しないレストランがあります。たとえば、Lins Gardenはサイト上で4であり、スクラップデータが表示されますa 3)。

私の完全なコードは以下の通りです:

import requests 
import time 
import csv 
import sys 
from bs4 import BeautifulSoup 

hygiene = [] 

def deletelist(): 
    hygiene.clear() 


def savefile(): 
    filename = input("Please input name of file to be saved")   
    with open (filename + '.csv','w') as file: 
     writer=csv.writer(file) 
     writer.writerow(['Address','Town', 'Price', 'Period']) 
     for row in hygiene: 
      writer.writerow(row) 
    print("File Saved Successfully") 


def appendhygiene(scrape): 
    hygiene.append(scrape) 

def makesoup(url): 
    page=requests.get(url) 
    print(url + " scraped successfully") 
    return BeautifulSoup(page.text,"lxml") 


def hygienescrape(g_data, ratings): 
    for item in g_data: 
     try: 
      name = (item.find_all("a", {"class": "name"})[0].text) 
     except: 
      pass 
     try: 
      address = (item.find_all("span", {"class": "address"})[0].text) 
     except: 
      pass 
     try: 
      for rating in ratings: 
        bleh = rating['alt'] 

     except: 
      pass 

     appendhygiene(scrape=[name,address,bleh]) 








def hygieneratings(): 

    search = input("Please enter postcode") 
    soup=makesoup(url = "https://www.scoresonthedoors.org.uk/search.php?name=&address=&postcode=" + search + "&distance=1&search.x=16&search.y=21&gbt_id=0") 
    hygienescrape(g_data = soup.findAll("div", {"class": "search-result"}), ratings = soup.select('div.rating-image img[alt]')) 

    button_next = soup.find("a", {"rel": "next"}, href=True) 
    while button_next: 
     time.sleep(2)#delay time requests are sent so we don't get kicked by server 
     soup=makesoup(url = "https://www.scoresonthedoors.org.uk/search.php{0}".format(button_next["href"])) 
     hygienescrape(g_data = soup.findAll("div", {"class": "search-result"}), ratings = soup.select('div.rating-image img[alt]')) 

     button_next = soup.find("a", {"rel" : "next"}, href=True) 


def menu(): 
     strs = ('Enter 1 to search Food Hygiene ratings \n' 
      'Enter 2 to Exit\n') 
     choice = input(strs) 
     return int(choice) 

while True:   #use while True 
    choice = menu() 
    if choice == 1: 
     hygieneratings() 
     savefile() 
     deletelist() 
    elif choice == 2: 
     break 
    elif choice == 3: 
     break 

答えて

1

はあなたの問題はここにあるように見える:

try: 
    for rating in ratings: 
     bleh = rating['alt'] 

except: 
    pass 

appendhygiene(scrape=[name,address,bleh]) 

これが何をやって終了すると、各ページの最後の値を付加しています。したがって、最後の値が「免除」の場合、すべての値は免除されます。レーティングが3の場合、そのページのすべての値は3になります。各評価は、むしろ単純に最後の1を追加するよりも、別途追加されるように

try: 
    bleh = item.find_all('img', {'alt': True})[0]['alt'] 
    appendhygiene(scrape=[name,address,bleh]) 

except: 
    pass 

:あなたが欲しい

はこのような何かを書くことです。私はちょうどそれをテストし、それは動作するように見えた:

+0

これは完璧に、説明のおかげで働いた。 :) –

関連する問題