python3.5.4爬取豆瓣中国内地电影票房总排行输出到excel

首先,作为练手,我也是看别人的博客文章学习写爬虫的,过程中遇到很多问题,不过经过自己的努力完成了此项任务,虽然过程波折,但是收获不会少,作为自学可谓加深印象。先说下需求,使用Python3.5版本获取豆瓣950多部电影排行信息,包含电影名称、导演、主演、编剧、类型、时长、上映时间、评分、票房、评分人数等一系列信息。

参考文章:https://blog.csdn.net/Fighting_No1/article/details/50926008?locationNum=8&fps=1

#!/usr/bin/python
#-*- coding: utf-8 -*-
from bs4 import BeautifulSoup
import re
import urllib.request
import xlwt

#得到页面全部内容
def askURL(url):
    fakeHeaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; rv:16.0) (Gecko/20100101 Firefox/16.0)'}#伪装请求头
    request = urllib.request.Request(url, headers=fakeHeaders)#发送请求
    proxy = urllib.request.ProxyHandler({'http': 'http://192.168.1.11:1080'})#设置代理
    opener = urllib.request.build_opener(proxy)#打开代理
    urllib.request.install_opener(opener)#使用代理
    try:
        response = urllib.request.urlopen(request)#取得响应
        html = response.read()#获取网页内容
        return html
    except urllib.request.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)

#获取相关内容
def getData(baseurl):
    #re.M或re.MULTILINE:使用^或$时会匹配每一行的行首或行尾
    #re.S或re.DOTALL:使用.时能匹配换行符
    # 找到片名
    findTitle=re.compile(r'<a .*?>(.*?)</a>', re.S|re.M)
    #找到评分
    findRating=re.compile(r'<span class="rating_nums">(.*)</span>')
    #找到评价人数
    findJudge=re.compile(r'<span>(.*)</span>')
    #找到影片相关内容:导演,主演,类型,制片国家,年份
    findAbstract=re.compile(r'<div class="abstract">(.*)</div>', re.S)
    #找到发行类别、上映时间、总票房
    findQuote=re.compile(r'<blockquote class="comment">(.*)</blockquote>', re.S)
    datalist = []
    for i in range(0,39):
        #url每页显示25条数据,所以需要循环遍历
        url=baseurl+str(i*25)#+'&sort=seq&sub_type='
        html=askURL(url)
        soup = BeautifulSoup(html, "html5lib", from_encoding="utf-8")
        for item in soup.find_all('div', class_='doulist-item'):#找到每一个影片项
            data = []
            item = str(item)#转换成字符串
            titles = re.findall(findTitle, item)#获取电影名称
            newtitles = re.sub('\s', '', titles[1])#去掉\n符和空白
            data.append(newtitles)  # 添加中文片名

            rating = re.findall(findRating, item)#获取评分,评分貌似也有为空的
            if (len(rating) == 1):
                score = rating[0]
                data.append(score)#添加评分
            else:
                data.append(' ')# 留空

            judgeNum=re.findall(findJudge, item)[0]#获取评价数量,评价数量貌似也有为空的
            newJudgeNum = re.findall(r'\d+', judgeNum)#取出数字
            if len(newJudgeNum) != 0:
                peoplenum = newJudgeNum[0]
                data.append(peoplenum)#添加评价数量
            else:
                data.append(' ')# 留空

            a = re.findall(findAbstract, item)
            #这里可能会有空字符串出现
            if len(a) != 0:
                abstract=re.findall(findAbstract, item)[0]
                abstract = re.sub('\s', "", abstract)#替换/
                abstract = re.sub('</div>', "", abstract)  # 去掉<br>
                words=abstract.split("<br/>")
                #测试发现主演有为空值的现象,此处在为空值的位置添加字眼“主演:”,便于切割字符串
                if (len(words) != 5):
                    words.insert(1, '主演: ')  # 留空
                #对字符串进行切割,得到导演、主演、电影类型、制片国家、电影所属年份
                director = words[0].split(':')[1]#导演
                data.append(director)  # 放到列表data中

                mainactor = words[1].split(':')#主演有为空的
                if len(mainactor) != 0:
                    actor = mainactor[1]
                    data.append(actor)#添加主演
                else:
                    data.append(' ')  # 留空

                movietype = words[2].split(':')[1]#电影类型
                data.append(movietype)  # 放到列表data中

                makercountry = words[3].split(':')[1]#制片国家
                data.append(makercountry)  # 存入列表data中

                movieofyear = words[4].split(':')#电影所属年份
                if len(movieofyear) != 0:
                    year = movieofyear[1]
                    data.append(year[:4])
                else:
                    data.append(' ')  # 留空
            else:
                words=['导演: ', '主演: ', '类型: ', '制片国家/地区: ', '年份: ']
                director = words[0].split(':')[1]  # 导演
                data.append(director)  # 放到列表data中

                mainactor = words[1].split(':')
                data.append(mainactor)

                movietype = words[2].split(':')[1]
                data.append(movietype)

                makercountry = words[3].split(':')[1]  # 制片国家
                data.append(makercountry)  # 存入列表data中

                movieofyear = words[4].split(':')  # 电影所属年份
                data.append(movieofyear)

            quote = re.findall(findQuote, item)
            # 处理空列表的情况出现
            if len(quote) != 0:
                info = re.sub('\s', '', quote[0])  # 去掉\n符和空白
            else:
                quote.insert(0, '总票房: | 上映日期: | 发行类别: ')#当发现有空数据时
                info = quote[0]
            #对获取到的字符串进行切割处理,以竖线为分割线进行切割
            separatequote = info.split("|")
            # 对字符串进行切割,得到总票房、上映日期、发行类别
            pricehouse = separatequote[0].split(":")[2:]#总票房
            if len(pricehouse) != 0:
                data.append(pricehouse[0])
            else:
                data.append(' ')

            releasedate = separatequote[1].split(":")[1:]  # 上映日期
            if len(releasedate) != 0:
                data.append(releasedate[0])
            else:
                data.append(' ')

            releasetype = separatequote[2].split(":")[1:]#发行类别
            if len(releasetype) != 0:
                data.append(releasetype[0])
            else:
                data.append(' ')
            #print(data)
            datalist.append(data)  # 放到大列表datalist中
    return datalist

#将相关数据写入excel中
def saveData(datalist, savepath):
    book = xlwt.Workbook(encoding='utf-8', style_compression=0)
    sheet=book.add_sheet(u'豆瓣电影', cell_overwrite_ok=True)
    col = ('影片名', '评分', '评价人数', '导演', '主演', '类型', '制片国家', '年份', '总票房', '上映时间', '发行类别')
    for i in range(0, len(col)):
        sheet.write(0, i, col[i])#列名,表格的第一行开始写。第一列,第二列。。。。
    for i in range(0, 953):#从第零行开始至952行
        data = datalist[i]
        for j in range(0, len(col)):
            sheet.write(i+1, j, data[j])#数据
    book.save(savepath)#保存

if __name__ == '__main__':
    baseurl = 'https://www.douban.com/doulist/1295618/?start='
    datalist = getData(baseurl)
    savepath = u'中国内地电影票房总排行.xls'
    saveData(datalist, savepath)

输出效果:


注意事项:这里输出发现第50条数据有问题,可通过手动删除得到其余952条电影信息,暂时不知道原因无法修正,如果你们发现了告诉我一声,我也好改正。我在程序中写入了953行,这样多余的冗余数据可通过手动删除来规避。


转载请标明原作者出处,谢谢


  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingdiango

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值