美文网首页
2018-07-04

2018-07-04

作者: 一如既往的小白 | 来源:发表于2018-07-04 10:42 被阅读0次

    一、目的:

    个人比较喜欢看欧美电影,最近刚学了爬虫,所以敲了这个程序 来爬取 电影天堂IMB 评分8.0以上的 欧美电影 跟大家分享一下。

    二、爬取电影天堂需要掌握的基本技能:

    1、熟悉python的基本语法。

    2、会使用 简单的正则表达式。

    3、掌握beautifulsoup4的基本使用,了解网页源代码的组成结构。

    4、了解requests模块的基本使用

    三、过程:

    步骤一:分析网页的基本结构

    首先打开电影天堂 欧美电影 的栏目

    1.png

    1)我们发现 欧美电影栏目 的网址 是有规律的。

    当我们点开 欧美电影的第一页 时网址 是 http://www.ygdy8.net/html/gndy/oumei/list_7_1.html

    当我们点开 欧美电影的第二页 时网址 变为 http://www.ygdy8.net/html/gndy/oumei/list_7_2.html

    也就是说其实 改变 网址页数的 该网址 7_ 之后的数字

    2)接下来我们 点开 开发者工具查看网页源代码(F12)

    image.png

    我们发现 其实 每部电影的 内容 都是包含在一个 class=“tbspan”的table 里

    于是我们可以使用beautiful的find_all函数 去获取 全部 class=“tbspan”的table

    代码为:table = BeautifulSoup(content.text,"lxml").find_all('table',class_='tbspan')

    我们点开 class=“tbspan”的table

    image.png

    我们可以发现 电影 内容简介 包含在一个a标签内

    image.png

    而该a标签的 文本内容(text)里包含了 “《”这个关键符号

    于是我们可以使用正则以及beautifulsoup去找到a标签内的全部内容

    代码为:table.find('a', text=re.compile("《"))

    (table是 class=“tbspan”的table,因为a标签是包含在它之下,所以我们要在他的基础上找)

    同理 电影的 IMB评分 以及详细内容 页 也是一样道理 可以取到

    传入正则表达式,查找所有的td标签文本内容中含有IMB的内容 # td是匹配文本内容到包含“IMB”的内容的整条 td 标签内容

    td = table.find('td', text=re.compile("IMD"))

    3)然后我们点开其中一部电影 比如 《狂暴巨兽》

    拉下来之后 我们 可以发现该电影的下载地址 那我们要怎么去获取呢?

    image.png

    打开开发者工具 查看源代码

    image.png

    我们发现 他的下载地址包含在 一个

    "style": "WORD-WRAP: break-word" 的 td 标签里

    于是我们去获取该标签

    Td = BeautifulSoup(content.text,"lxml").find('td', attrs={"style": "WORD-WRAP: break-word"})

    然后利用正则 获取 到 该电影下载地址

    downloadA = downloadTd.find('a')

    到此处 网页的基本结构分析就清楚 了 下面贴上源代码 ,不懂得可以查看注释

    下面是代码:

    import requests
    from bs4 import BeautifulSoup
    import re
    
    #电影 详情页的的基本前缀
    site = 'http://www.ygdy8.net'
    #构建电影类
    class Movie:
        def __init__(self, name, url, score, link):
            self.name = name
            self.url = url
            self.score = score
            self.link = link
    
        def __str__(self):
            return '%s,\t%s分,\t下载地址:%s' % (self.name, self.score, self.link)
    
        __repr__ = __str__
    
    
    def getSoup(url):
        r = requests.get(url)
        r.encoding = 'gb18030'
        return BeautifulSoup(r.text, "html.parser")
    
    
    def findMovie(url):
        movieList = []
        # 链接网址
        soup = getSoup(url)
        tables = soup.find_all('table', class_='tbspan')
        for table in tables:
            #传入正则表达式,查找所有的a标签文本内容中含有《的内容
            # aContent是匹配到a标签text里面包含《的整个a标签
            aContent = table.find('a', text=re.compile("《"))
            #传入正则表达式,查找所有的td标签文本内容中含有IMB的D内容
            # td是匹配文本内容到包含“IMB”的内容的整条 td 标签内容
            td = table.find('td', text=re.compile("IMD"))
    
            if td is not None:
                # 利用正则找到电影的评分
                # +?匹配一次或更多次的重复,但是在能使整个匹配成功的前提下使用最少的重复
                # 只匹配 +?的值 即如   评分 6.0/10  只输出 【‘6.0’】
                # 因为 有/  为了不为被当成转义符所以需要在前面r
                scoreStr = re.findall(r"评分 (.+?)/10", td.text)
    
                if (len(scoreStr) > 0):
                    try:
                        # 将字符串 转换为 浮点型
                        score = float(scoreStr[0])
                        if (score > 8):
                            name = aContent.text
                            print(name)
                            # 此处的url 是 电影的详情页面
                            url = site + aContent['href']
                            print('url:', url)
                            print('title:', name)
                            print('score:', score)
                            # downloadLink是获得电影的下载地址
                            downloadLink = getDownloadLink(url)
                            movie = Movie(name, url, score, downloadLink)
                            movieList.append(movie)
                    except:
                        print('error !!')
        return movieList
    
    #该方法是用来获取电影下载地址的
    def getDownloadLink(url):
        soup = getSoup(url)
        downloadTd = soup.find('td', attrs={"style": "WORD-WRAP: break-word"})
        downloadA = downloadTd.find('a')
        return downloadA['href']
    
    #该方法是用来保存电影的信息到本地文本文件的
    def saveMovie(movieList):
        #打开文本文件
        fileObj = open('movie.txt', 'a')
        for movie in movieList:
            movie_str = str(movie)
            print('movie info:', movie_str)
            fileObj.write(movie_str)
            fileObj.write('\n')
            fileObj.write(
                '————————————————————————————————————————————————————————————————————————————————————————————————')
            fileObj.write('\n')
    
        fileObj.close()
    
    
    def getPageResource(url):
        resultList = findMovie(url)
        if len(resultList) > 0:
            saveMovie(resultList)
    
    
    if __name__ == '__main__':
        for index in range(156):
            index += 1
            #电影天堂网的欧美电影基本前缀
            #在网页中第一页的地址为http://www.ygdy8.net/html/gndy/oumei/list_7_1.html
            #在网页中第一页的地址为http://www.ygdy8.net/html/gndy/oumei/list_7_2.html
            #容易发现其实网页改变页数 其实是改变 7_之后的数字
            #此处的url 为 欧美电影 的 地址  index 表示页数
            url = 'http://www.ygdy8.net/html/gndy/oumei/list_7_' + \
                  str(index) + '.html'
            getPageResource(url)
    

    运行结果展示:

    image.png image.png

    三:心得体会:

    此次爬虫加深了我对python 基础语法的掌握,也让我发现了python的有趣,在学习爬虫的过程中,我遇到了很多困难,第一个困难是 解析网页的结构,我觉得这是爬虫中很重要的一部分。第二个是,Beautifulsoup的 使用,有些语法不是很清楚。第三个是正则表达式的运用。第四是经常遇到反爬虫无法进行下去。

    相关文章

      网友评论

          本文标题:2018-07-04

          本文链接:https://www.haomeiwen.com/subject/wqxeuftx.html