使用Python批量将文件名附加到目录中

时间:2016-05-01 21:03:04

标签: python json regex python-3.x url

我刚刚开始使用Python,这是我的第一个“自己的”程序。我已经(尽我所能)解释了我打算实现的计划。由于我是新手,因此我非常感谢您提供的任何语法/性能改进建议。

   '''
        Search through a target movies directory and filter movie titles
        to search IMDb for movie ratings. After fetching, append ratings
        to corresponding movie files/folders in the directory.

        File names are in one of the following formats:
        1. P.S. I Love You.mkv
        2. P.S. I Love You (2010).mp4
        3. P.S. I Love You (2010) [1080p].avi

        Ideally, this program fetched the movie ratings and adds it to
        the end of the file name (just before the extension). The query,
        in this case, would be http://www.omdbapi.com/?t=P.S.+I+Love+You

        Ideally, the file in the directory would be renamed to one of the
        following:
        1. P.S. I Love You (7.1).mkv
        2. P.S. I Love You (2010) (7.1).mp4
        3. P.S. I Love You (2010) [1080p] (7.1).avi
    '''

    import os, json, urllib.request, re

    # Query related constants
    base_uri = "http://www.omdbapi.com/?"
    query_title = "t="

    basepath = "E:/Movies"

    # Fetch movie rating from omdbapi.com
    # Example JSON response: http://www.omdbapi.com/?t=insurgent
    def getRating(movie_title):
        # json_response = urllib.urlopen(base_uri + query_title + movie_title)
        # movie_data = json.loads(json_response.read())
        with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
            movie_data = url.read()
        return movie_data['imdbRating']

    # Checks if parameter file name already has a rating.
    # Movie ratings are
    def hasRating(filename):
        pattern = re.compile('\([0-9].[0-9]\)')
        if pattern.search(filename) is not None:
            return True
        return False

    # Get the movie title by stripping out excess information such as the
    # year released or video definition
    def getMovieTitle(filename):
        if '(' not in filename is False:
            return filename.split('(')[0]
        elif'[' not in filename is False:
            return filename.split('[')[0]
        return os.path.splitext(basepath + filename)[:-1]


    def main():
        for file in os.listdir(basepath):
            if hasRating(file) is False:
                movie_title = getMovieTitle(file)
                file_ext = os.path.splitext(basepath + file)[-1:]
                movie_rating = getRating(movie_title)
                formatted_rating = ' (' + movie_rating + ')'
                file_no_ext = os.path.splitext(basepath + file)[:-1]

                os.rename(file, file_no_ext + ' ' + formatted_rating + file_ext)

    if __name__ == '__main__':
        main()

到目前为止,我已尝试修复所有内容,但我仍然遇到同样的错误:

Traceback (most recent call last):
  File "renamer.py", line 65, in <module>
    main()
  File "renamer.py", line 58, in main
    movie_rating = getRating(movie_title)
  File "renamer.py", line 33, in getRating
    with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
TypeError: Can't convert 'tuple' object to str implicitly

请让我知道TypeError是什么,为什么会发生,以及我可以做些什么来解决它。

来自Java,Python的简单性是一种压倒性的,但同时又令人耳目一新。无论如何,提前感谢您的意见!

1 个答案:

答案 0 :(得分:2)

如果没有getMovieTitle条件为真,if会返回一个元组。因此movie_title是一个元组而getRating无法处理(&#34;添加&#34;字符串和元组会导致TypeError例外)。

返回列表的最后一个元素是由[-1]完成的。您期望从os.path.splitext使用的是第一部分,因此请使用索引0。

return os.path.splitext(basepath + filename)[:-1]

将此行转为

return os.path.splitext(basepath + filename)[0]

其次,您通过movie_data阅读url.read()后访问movie_data['imdbRating']这是一个字符串。你最想要的是解码结果(这是json),然后访问元素:

with urllib.request.urlopen(base_uri + query_title + movie_title) as url:
    movie_data = json.loads(url.read())['imdbRating']

这可以很长时间内完成&#39;是根词典中的一个关键。