Форум сайта python.su
0
Добрый день.
Целый вечер уже бьюсь над ошибкой. Помогите пожалуйста кто чем может решить ее.
Парсю данные и заливаю их в БД.
### часть кода из 1го метода, который завершается формированием словаря basic_dict[self.country][city.text.lstrip()][name] = dict(detailed_url=detailed_url, place_type = self.place_type) ### тут 2ой метод, который завершается расширением первого словаря extended_dict[self.country][city][cinema].update(dict(address = street1, phone_number = phone1, official_website = website1)) self.showtime(extended_dict) ### тут 3ий метод, который принимает расширенный словарь и начинает уже парсить данные и заливать в БД. def showtime(self, extended_dict): showtime_dict = extended_dict for city in showtime_dict[self.country]: for cinema in showtime_dict[self.country][city]: url = showtime_dict[self.country][city][cinema]['detailed_url'] showtimes_tab_url = '/showtimes/#!=&cinema-section=%2Fshowtimes%2F' tree = prepare_content(url + showtimes_tab_url) for film in tree.xpath('//div[@class="content"]'): film_name = film.xpath('.//a[@class="navi"]/text()')[0] for date in film.xpath('.//li[contains(@class,"showtimes-day sdt")]'): film_date = date.xpath('.//div[@class="date"]/text()')[0] for time in date.xpath('.//ul[@class="showtimes-day-block"]/li'): film_time = time.xpath('string(a/text())') film_buy_ticket_url = time.xpath('string(a/@href)') if len(film_time) == 0: film_time = None is_3d = time.find('span') film_format = '' if film_time is not None: if is_3d is not None: film_format = '3D' else: film_format = '2D' # IMPORT from app_places.models import Place from app_shows_and_times.models import Show, Showtime get_showtime_place = Place.objects.get(place_name = cinema, place_street = showtime_dict[self.country][city][cinema]['address']) get_showtime_show = Show.objects.get(show_name = film_name) showtime = Showtime.objects.create( showtime_dates = film_date, showtime_times = film_time, showtime_format = film_format, showtime_buy_ticket_url = film_buy_ticket_url, showtime_place = get_showtime_place, showtime_show = get_showtime_show)
class Place(models.Model): place_name = models.CharField(max_length = 50, db_index = True) place_street = models.CharField(max_length = 80) place_phone = models.CharField(max_length = 60) place_official_site = models.URLField(max_length = 255, blank = True) place_country = models.ForeignKey(Country) place_city = models.ForeignKey(City) place_type = models.ForeignKey(PlaceType) class Meta: db_table = 'place' unique_together = (('place_name', 'place_street'))
Отредактировано TitanFighter (Авг. 21, 2015 14:08:39)
Офлайн
221
TitanFighter
Всегда указывайте полный traceback ошибки, т.е. полный вывод
В extended_dict в какой то момент нету такого ключа. Если у вас стопориться процесс при 4700 записи, посмотрите что будет происходить при итерации 4701, скорее всего просто одна запись не обрабатывается должным образом.
Офлайн
221
И еще , есть такая штука PEP8, если не слышали - то пролистайте, ознакомьтесь. Я к тому что комментарии у вас какие то странные, да и и импорт принято в начале файла указывать (есть конечно случаи когда можно по другому поступать, но это не тот)
Офлайн
0
Выкладываю трейсбек. Буду знать на следующий раз, что нужно полный. Спасибо.
Traceback (most recent call last): File "<console>", line 1, in <module> File "/home/antonio/projects/idemvdvoem.com/idemvdvoem.com/src/shared/parser_to_db.py", line 23, in __init__ self.basic_cinemas_info() File "/home/antonio/projects/idemvdvoem.com/idemvdvoem.com/src/shared/parser_to_db.py", line 176, in basic_cinemas_info self.detailed_cinemas_info(basic_dict) File "/home/antonio/projects/idemvdvoem.com/idemvdvoem.com/src/shared/parser_to_db.py", line 225, in detailed_cinemas_info self.showtime(extended_dict) File "/home/antonio/projects/idemvdvoem.com/idemvdvoem.com/src/shared/parser_to_db.py", line 271, in showtime get_showtime_place = Place.objects.get(place_name = cinema, place_street = showtime_dict[self.country][city][cinema]['address']) KeyError: 'address'
) Но все равно спасибо за внимание, ведь мог и не знать.
Отредактировано TitanFighter (Авг. 21, 2015 01:52:13)
Офлайн
0
Только лег в кровать, пришло озарение, как можно найти проблему.
У меня есть модель Showtimes, которая связана через FK с Places.
1 кинотеатр с адресом ул. Лаврухина, 4. ТЦ “РайON” вообще не проимпортировался в Places. Подумал, что может скобки. Проверил - .replace('“', “'”).replace('”', “'”).replace('“', ”'") - не помогло.
Может проблема в кириллице+латинице в названии?
Может как то unique_together влияет? У меня postgreSQL
Может теперь будет кому-то легче подсказать, куда мне ковырять?
Отредактировано TitanFighter (Авг. 21, 2015 04:09:14)
Офлайн
568
Да при чем тут unique_together? У вас же не при обращениях к БД ошибка, а в алгоритме, вот тут
showtime_dict[self.country][city][cinema]['address']
showtime_dict[self.country][city][cinema]
Офлайн
5
Чтобы не было ошибок “KeyError” используйте метод словаря get.
Вместо:
showtime_dict[self.country][city][cinema]['address']
showtime_dict[self.country][city][cinema].get('address', ' ')
Офлайн
0
FishHookВ 4 ночи уже ничего не хочется, кроме как обнять подушку
Да при чем тут unique_together? У вас же не при обращениях к БД ошибка, а в алгоритме, вот тут
showtime_dict
KeyError: ‘address’ означает, что в словаре, который вы получили
showtime_dict
нет ключа address.
У тут вообще не при чем ни постгресс, ни индексы в нём, ни количество записей в базе, а имеет значение лишь то, что где-то выше вы неправильно создали словарь.
. Утром прочитав ваши мысли, на свежую голову, я полностью с вами был согласен.i.slepovЯ думал так сделать, но это был бы костыль в том смысле, что данные по нему вообще бы просто пропускались, так как данный кинотеатр даже не заливался в БД (не говоря уже о сеансах, из-за чего и создал этот топик).
Чтобы не было ошибок “KeyError” используйте метод словаря get.
Вместо:
showtime_dict
Нужно:
showtime_dict.get('address', ‘ ’)
). Так как я проверку полей не делал, то в словарь не добавлялись данные cinema_street, cinema_phone, cinema_website для этого одного кинотеатра. Нету данных -> ошибка.for city in extended_dict[country]: for cinema in extended_dict[country][city]: url = extended_dict[country][city][cinema]['detailed_url'] tree = prepare(url) for street in tree.xpath(".//div[@class='address']"): cinema_street = street.xpath("text()")[0].strip() for phone in tree.xpath(".//div[@class='phone']"): cinema_phone = phone.xpath("text()")[0].replace('Телефон:', '').strip() for website in tree.xpath(".//div[@class='website']/a"): cinema_website = website.xpath("@href")[0].strip() extended_dict[country][city][cinema].update(dict(address = cinema_street, phone_number = cinema_phone, official_website = cinema_website))

Отредактировано TitanFighter (Авг. 21, 2015 14:06:46)
Офлайн