понедельник, 18 февраля 2013 г.

Кинопоиск API для Python

В продолжение поста.
В интернетах на момент написания этого поста API для Кинопоиска не нашлось. Поэтому пришлось написать его самому. Ну не бросать же отечественный кинематограф.
Добрый kinopoisk как будто бы начинал писать более-менее доступный API, но потом бабло победило зло реклама победила открытые источники. А задел был вот такой. По простому URL с ID фильма возвращается приятный XML с данными рейтинга КиноПоиска и IMDB. Дело за малым - нужно научится определять ID фильма. Как правило, названия и года хватает, поэтому будем эмулировать поиск пользователя. Который осуществляется через следующий URL:
http://www.kinopoisk.ru/s/type/film/find/ + movieName + /m_act%5Byear%5D/ + movieYear

Если условий достаточно, kinopoisk сразу перенаправляет на страничку фильма и его ID можно достать из URL перенаправленной страницы. Если совпадений несколько - парсим страницу и выбыраем то, что сам КиноПоиск считает наиболее подходящим (как правило он правильно все находит). Для того, чтобы КиноПоиск не заподозрил неладное, подставляем случайный user-agent (спасибо интернету)
Вот что у меня получилось - Kinopoisk Python API:


import requests, re, sys, lib, os, logging, datetime 
from HTMLParser import HTMLParser 
from xml.dom.minidom import parseString 
 
def getKinopoiskMovieId(movieName, movieYear): 
    try: 
        r = requests.get( 
            'http://www.kinopoisk.ru/s/type/film/find/' + movieName + '/m_act%5Byear%5D/' + movieYear + '/', 
            headers=__set_user_agent__()) 
 
        m = re.search('film\/(\d)+\/$', r.url) 
 
        if m != None: #we have found ID of the film already 
            return m.group(0)[5:-1] 
 
        class MyHTMLParser(HTMLParser): 
            def myinit(self): 
                self.found = None 
                self.filmid = None 
 
            def handle_starttag(self, tag, attrs): 
                if self.found == None and tag == 'div': 
                    for a in attrs: 
                        if a[1] == 'element most_wanted': 
                            self.found = True 
                if self.found == True and tag == 'a': 
                    for a in attrs: 
                        if a[0] == 'href': 
                            m = re.search('\/film\/(\d)+\/', a[1]) 
                            if m != None: 
                                self.filmid = m.group(0)[6:-1] 
                                self.found = False 
 
        parser = MyHTMLParser() 
        parser.myinit() 
        parser.feed(r.content.decode('windows-1251')) 
        if (parser.filmid) == None: 
            logging.getLogger('smogbot').warn( 
                'Could not get Kinopoisk rating for ' + movieName + ", " + movieYear) 
 
        return parser.filmid 
    except BaseException as e: 
        logging.getLogger('smogbot').warn( 
            'Could not get Kinopoisk rating for ' + movieName + ", " + movieYear, exc_info=e) 
        return None 
 
 
def __getKinopoiskRatingVotes__(kpMovieId): 
    try: 
        ratingR = requests.get('http://www.kinopoisk.ru/rating/' + kpMovieId + '.xml', 
            headers=__set_user_agent__()) 
        result = parseString(ratingR.content) 
        if len(result.getElementsByTagName('kp_rating')) > 0: 
            return float(result.getElementsByTagName('kp_rating')[0].childNodes[0].data),\
                   int(result.getElementsByTagName('kp_rating')[0].getAttribute('num_vote')) 
    except BaseException as e: 
        logging.getLogger('smogbot').warn( 
            'Could not get Kinopoisk rating for ' + kpMovieId, exc_info=e) 
    return 0, 0 
 

3 комментария:

  1. не отрабатывает(
    No handlers could be found for logger "smogbot"
    None

    ОтветитьУдалить
    Ответы
    1. Ах да.

      logger = logging.getLogger('smogbot')
      h = logging.StreamHandler(sys.stdout)
      h.setLevel(consoleLevel)
      logger.addHandler(h)

      Удалить