2017-10-07 36 views
0

タイトルのようなエラーが表示されます。AttributeError: 'NoneType'オブジェクトに属性 'div'がありません

おそらく間違った要素を入力したようです。

私はコードを一から書きませんでした。他のサイトを以前にクロールしていたコードに適用しました。

要素を変更してそれを変更するにはどうすればよいですか? 私はよく書いたと思います。しかし、エラーがあります。

ps私はapiを使用するコメントがあるのでしょうか?しかし、これは限られているので、これを使う方法です。あなたがループのために、あなたはすでにreviews_infoに「レビュー・コンテンツ」のクラス属性を持つdiv要素を渡しているに

import sys 
from bs4 import BeautifulSoup 
import urllib.request 
import requests 
from urllib.parse import quote 

import os 
import xlwt 

import re 
import time 
import random 
import re, requests, csv 
from bs4 import BeautifulSoup 
from time import sleep 

# CMD chcp 65001 


def reviews_info(div): 
    review_text = div.find("div", "review-content").div.text 
    review_stars = div.find("div", "i-stars i-stars--regular-1 rating-large").a.text 
    return { 
     "review_text" : review_text, 
     "review_stars" : review_stars, 
    } 

base_url = "https://www.yelp.com/biz/founding-farmers-d-c-washington-2?start=" 
reviews = [] 
NUM_PAGES = 36 

for page_num in range(1, NUM_PAGES + 20): 
    print("souping page", page_num, ",", len(reviews), "data") 
    url = base_url + str(page_num) 
    soup = BeautifulSoup(requests.get(url).text, 'lxml') 

    for div in soup('div', 'review-content'): 
     reviews.append(reviews_info(div)) 
    sleep(5)############################################# 
    # Save dict data 
keys = reviews[0].keys() 
with open('testtest.csv', 'w', encoding="utf-8") as f: 
    dict_writer = csv.DictWriter(f, delimiter=',', lineterminator='\n', fieldnames=keys) 
    dict_writer.writeheader() 
    dict_writer.writerows(reviews) 
+0

あなたのスクレーパーと予定リストについて記述した方法は完全に曖昧です。あなたがスクレーパーの提供されたリンクから解析したいフィールドを指定すると良いでしょう。 – SIM

答えて

0

。したがって、おそらく.find("div", "review-content")の部分を削除する方が良いでしょう。これはエラーの原因になる可能性があります。

明らかに、レビューの日付と星が必要です。

review_date = div.span.next_element.strip() 

あなたは別のエラーが発生します評価を抽出するために使用の式:代わりに日付を抽出するためにdiv.div.textを使用しての

は、次のような日付が含まれていspanタグを利用することができます。

「i-stars i-stars - 通常1 rating-large」は、1つ星の評価に適用されます。したがって、4つ星の評価にはdivclass="i-stars i-stars--regular-4 rating-large"が続きます。

だから、あなたがレーティングを含むdivをフィルタリングするために正規表現を利用することができます:

review_stars = div.find('div', {'class': re.compile(r'i-stars')}).img['alt'] 

が一緒に、これらの二つの部分を置く、あなたのreviews_info機能で変更する必要がある2つの行は、次のとおりです。

review_date = div.span.next_element.strip() 
review_stars = div.find('div', {'class': re.compile(r'i-stars')}).img['alt'] 

これらの変更を加えれば、良い結果が得られます。

追加情報:

私はテキストを抽出するためにdiv.span.text.strip()を使用しなかった理由は、審査がその投稿後に更新された場合、spanタグは、あまりにも、その詳細が含まれていることです。そして、その情報を抽出したspan.textも使用します。したがって、next_elementを選択しました。

免責事項:私は3ページ目だけでテストしてくれました。他のページが問題なく動作するかどうかはわかりません。

関連する問題