2017-10-07 99 views
0

我得到一个像标题一样的错误。AttributeError:'NoneType'对象没有属性'div'

Traceback (most recent call last): 
    File "C:/2.py", line 40, in <module> 
reviews.append(reviews_info(div)) 
    File "C:/2.py", line 21, in reviews_info 
    review_text = div.find("div", "review-content").div.text 
AttributeError: 'NoneType' object has no attribute 'div' 

我想我可能输入了错误的元素。

我没有从零开始编写代码。我已经申请了以前爬行其他网站的代码。

如何更改元素并将其打开? 我想我写得很好。但是有一个错误。

ps我恐怕会有使用api的评论。但这是使用它的方式,因为它是有限的。

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

在你的循环,你已经传递给reviews_info拥有的“审查内容”一类属性的股利。所以你可能最好删除.find("div", "review-content")部分。这可能是导致错误的原因。

显然,你需要检查日期和星星。

而不是使用div.div.text提取之日起,您可以利用包含日期,这样的span标签:

review_date = div.span.next_element.strip() 

您使用提取的收视率会提高另一个错误的表达。

“i-stars i-stars-regular-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功能改变需要两条线:

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

声明:我在第三页单独测试了它,它对我很有用。我不确定其他网页是否可以正常工作。