最近在学习崔庆才老师著作的《python3 网络爬虫开发实战》,对爬取猫眼排名榜前100电影的讲解案例,产生一些小想法,结合pandas 在数据分析方面的应用,给出以下学习笔记,作为rockyliu学习爬虫成长道路上的one small step.

话不多说,先汇总本次爬取的目标:

  • 1)获取猫眼排名榜前100电影
  • 2)获取前100电影图片存放在本地
  • 3)获取前100电影的英文名称
  • 4)通过百度百科获取电影区域归属
  • 5)展示前100电影的上映时间分布
  • 6)展示参演频率最高的前5位演员及所参演电影

是不是感觉rockyliu有点贪,让我们拭目以待吧。

实现目标1:获取猫眼排名榜前100电影

先上效果图:

如效果图,通过爬虫代码,从猫眼电影排行榜上,获取前100的电影的相关信息(排名/电影海报地址/电影名/主演/上映时间/评分)。接下来上代码,供大家参考学习:

import requests
import re
import time
from requests.exceptions import RequestException
import pandas as pd #先定义一个获取网站源代码的方法
def get_one_page(url):
#使用try方法,防止程序中断报错try:headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}    response = requests.get(url,headers=headers)if response.status_code == 200:return response.textreturn Noneexcept RequestException:return None
#   rockyliu 偏好 写出print('wrong1:获取一个网站源代码出错'),便于快速查找问题#定义一个对源代码解析,并利用正则表达式获取想要的值,再结合pandas库,生成pandas.DataFrame数据
def parse_one_page(html):
#该处的正则表达式,可能会随着时间推移而改变,若报错,请读者自行更新哟pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>',re.S)items = re.findall(pattern,html)pf = pd.DataFrame()   for item in items:a = [item[0],item[1],item[2].strip(),item[3].strip()[3:] if len(item[3])>3 else '',item[4].strip()[5:] if len(item[4])>5 else '',item[5].strip()+item[6].strip()]
#需要注意item[5]代表评分整数,item[6]代表评分小数,因此合计评分要两者相加pf_ = pd.DataFrame(a)pf = pd.concat([pf,pf_.T])   #要注意pf_.T,即转置小细节,否则会报错哟yield pf
'''通过yield函数生成一个汇总的pd.DataFrame数据(小细节,yield 只能存在函数表达式中(def balaba:),否则就会出现outside function报错  )
'''
#定义一个写入文档函数:
def write_to_file(offset):url = 'https://maoyan.com/board/4?offset='+str(offset)html = get_one_page(url)for item in parse_one_page(html):print(item.shape)
#如果是第一个网页,即前10电影,增加一个列表头,其他则不增加,以header = True /False 体现if offset == 0:item.columns = ['index','image_url','title','actor','time','score'] item.to_csv('result.csv',mode='a',encoding='gbk',index=False)else:item.to_csv('result.csv',mode='a',encoding='gbk',index=False,header=False)
'''
小细节,要增加encoding = 'gbk'和mode='a',相信rockyliu没有错
生成的result.csv,就存在python代码所在的文件夹内。rockyliu建议写成绝对路径:r'D:\bala\result.csv'
'''
#定义一个获取前X*10的电影函数
def get_top_movie(top=10):
# if 函数,主要为了防止出现非1-10的值if (not isinstance(top,int)):print('wrong2:输入值不为整数')elif (top>10) | (top<1):print('wrong3:输入值不在1-10内')else:for i in range(top):write_to_file(offset=i*10)time.sleep(1)
#最后一步,调用函数
get_top_movie()

通过上述代码,我们实现了目标1)获取猫眼排名榜前100电影,

实现目标2:获取前100电影图片存放在本地

先上效果图:

满屏幕的图片是不是很赞呢?立刻贴代码:

import requests
import pandas as pd
from requests.exceptions import RequestException
import time #读取前100电影海报图片url地址
pf = pd.read_csv('result.csv',encoding='gbk')
#爬虫的报文头,headers主要就是模拟浏览器登陆,否则可能会获取不到相关图片
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}for i in range(100):url = pf.iloc[i,1]movie_image_name =str(i+1)+'-' + pf.iloc[i,2]
'''
小细节,str(i+1)+'-'就是为了快速辨识电影的排名.
若不加上str(),直接(i+1)+'-'会报错哟
'''try:response = requests.get(url,headers=headers)if response.status_code == 200:content = response.content
'''
小细节,如果写成response.text 不能正常写入哟。会报 'gbk' codec can't encode character '\ufffd' in position 0: illegal multibyte sequence
'movie_image\\',要记得先在代码所在文件夹中新建一个movie_image的文件夹,否则会报错的哟
'\\'多出一个'\'是因为为了转义,不要漏了哟
'''movie_image_path = 'movie_image\\' + movie_image_name +'.jpg'with open(movie_image_path,'wb') as f:f.write(content)else:print('wrong1:获取图片错误')print(response.status_code)except RequestException:print('wrong1:获取图片错误')print(i)  # 要不然,空等着程序跑,看着着急死人time.sleep(1)

实现目标3:获取前100电影的英文名称

通过百度百科获取前100电影的外文名称和制片地区,着实不易。anyway,贴上代码跟大家一起分享:

import requests
import re
import pandas as pd
import time
from requests.exceptions import RequestException
inputfile = 'result.csv'# 利用pandas读取前面从猫眼电影上爬取的数据
pf = pd.read_csv('result.csv',encoding='gbk')
# 新增三列,分别为  name_en - 外文名称,movie_area - 制片地址,movie_base_info- 电影基本信息
title = pf['title']
pf['name_en'] = None
pf['movie_area'] = None
pf['movie_base_info'] = None '''
百科的搜索地址,是rockyliu浏览众多网页中找到的,官网是要进行商务合作且收费的。若读者用于商业用途,则有可能造成侵权
'''
url_ = 'http://baike.baidu.com/search/word?word=''''
定义一个获取百度百科指定电影的网页
模块代码冷知识:爬取到的百科网页编码为ISO-8859-1,需要response.text.encode('ISO-8859-1').decode("utf-8"),进行特殊处理,否则将报错哟。各种编码问题,今后找时间跟大家讲解下
'''
def get_movie_extra(url):try:headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}response = requests.get(url,headers=headers)if response.status_code == 200:return response.text.encode('ISO-8859-1').decode("utf-8")return Noneexcept RequestException:    return None
'''
对获取的网页内容进行关键字提取获取
利用chrome浏览器中开发者工具,可以获取当前网页内容,结合notepad++,非常非常提高对网页的分析。
从中获取关键的字符有:class="basicInfo-item name和class="basicInfo-item value,围绕这两个关键字符,给出正则表达式鉴于name/value组合,创建一个字典,便于今后提取相关字段和值rockyliu的正则表达式玩的还不溜,所以,需要对name和value进行二次处理。读者有好的正则表达式,欢迎在评论区回答。毕竟正则表达式的书写是一门艺术定义函数时,最好是用到return  '''
def parse_movie_extra(html):pattern = re.compile('<dt class="basicInfo-item name">(.*?)</dt>.*?<dd class="basicInfo-item value">(.*?)</d',re.S)match = re.findall(pattern,html)list_keys = []list_values = []for i in match:list_keys.append(i[0])list_values.append(i[1].strip())for i in range(len(list_keys)):list_keys[i] = list_keys[i].replace('&nbsp;','').replace('外文名称','外文名')for i in range(len(list_values)):list_values[i] = re.sub('<.*?>','',list_values[i],re.S).replace('&nbsp;','').replace('\n','')dic = dict(zip(list_keys,list_values))return dic
'''
提取title列,进行for循环,分别给出name_en/movie_area/movie_base_info的值
特别说一句,最新的pandas库,要求赋值,最好利用 .at[index,column]=value的方式,而非pf[column][index]=value增加time.sleep(1),主要担心爬取过快,被对方封IP
增加print('已完成%d个查找'%(i+1)),便于知道当前进度,心里有数'''for i in range(len(title)):url = url_+title[i]html = get_movie_extra(url)dict1 = parse_movie_extra(html)pf.at[i, 'name_en'] = dict1.get('外文名',None)pf.at[i,'movie_area'] = dict1.get('制片地区',None)pf.at[i,'movie_base_info'] = dict1time.sleep(1)print('已完成%d个查找'%(i+1))
pf.to_csv('result1.csv',encoding='utf_8_sig',index=False)#    '''
本次数据格式,有gbk,有utf-8,有ISO-8859-1,用excel打开后,一直报错,网上查了资料,用encoding='utf_8_sig'utf_8_sig,完美解决。
index =False ,一定不要丢了,否则,朋友试下就知道,嘿嘿。'''
print('完成任务')

完成目标1,2,3,4后,基本上想要的数据已经全了。接下来目标5,6,都是数据分析展示了。

目标5)展示前100电影的上映时间分布 效果图(好片于2010-2013扎堆上映)

6)展示参演频率最高的前5位演员及所参演电影  效果图(哥哥是最高产的)

贴代码咯

import pandas as pd
import re'''
读取已经添加百度百科的数据
挑选出我们需要的几个列字段,index/排名,title/名称,actor/主演,time/上映时间,name_en/外文名称,movie_area/上映地区'''
pf = pd.read_csv('result1_1.csv')
pf = pf[['index', 'title', 'actor', 'time', 'name_en', 'movie_area']]# 提取前四个数字,即获得相应的年份func_time = lambda string: re.match('\d{4}',string).group()
pf['time'] = pf['time'].apply(func_time)
# 利用pandas.plot.bar展示上映年份的柱状图
pd.value_counts(pf['time']).plot.bar(figsize=(25,10),yticks=range(11),grid=True,rot=45,alpha=0.5,title='Time Distribution Map of the Top 100 Cat Eye Films',color='g')#将主演列拆分为一个一个演员列表,用于分析
#.replace(',',',').split(','),先更换部分中文逗号,再拆分成列表
func_actor = lambda x: x.replace(',',',').split(',')
pf['actor_'] = pf['actor'].apply(func_actor)#获取拆分出来的主演人员数量,为下一步分析做铺垫。本次分析出来,发现只有3和1
pf['actor_num'] = pf['actor_'].apply(len)#新建列,actor_01/主演1,actor_02/主演2,actor_03/主演3
pf['actor_01'] =None
pf['actor_02'] =None
pf['actor_03'] =None#赋值actor_01/主演1,actor_02/主演2,actor_03/主演3
for i in range(pf['actor_'].shape[0]):if len(pf['actor_'][i])==3:pf.at[i,'actor_01'] = pf['actor_'][i][0]pf.at[i,'actor_02'] = pf['actor_'][i][1]pf.at[i,'actor_03'] = pf['actor_'][i][2]else:pf.at[i,'actor_01'] = pf['actor_'][i][0]
'''
创建演员列表,用于分析每个演员出现的次数
isinstance(pf['actor_'][i],list)担心部分主演仅有一个,就成字符串而非列表,字符串不能直接和列表相加
'''
list_actor = []
for i in range(pf['actor_'].shape[0]): if isinstance(pf['actor_'][i],list):   list_actor = list_actor+pf['actor_'][i]else:list_actor = list_actor + list(pf['actor_'][i])
#使用pd.value_counts(pd.Series),获取排名
list_actor = pd.Series(list_actor)
#创建一个空的pd.DataFrame()数据
# 新增参演电影数/movie_num,演员/actor两列
actor_top10 = pd.DataFrame()
actor_top10['movie_num'] = pd.value_counts(list_actor)[:10]
actor_top10['actor'] = pd.value_counts(list_actor)[:10].index
# 定义一个函数,用于获取参演电影名称
#actor_top10['pactor_top10_movies_list'] = None 创建列:pactor_top10_movies_list/参演电影
# 一定要用上.copy(),避免原始pf数据字段值被覆盖,或错误引用index值
def actor_top10_movies(actor_top10,pf):actor_top10['pactor_top10_movies_list'] = Nonefor i in range(len(actor_top10['actor'])):pf_ = pf[(pf['actor_01']==actor_top10['actor'][i]) | (pf['actor_02']==actor_top10['actor'][i]) |(pf['actor_03']==actor_top10['actor'][i])].copy()actor_top10['actor_top10_movies_list'][i] = list(pf_['title'])#调用函数
actor_top10_movies(actor_top10,pf)
#更改index值和名称
actor_top10.index=range(10)
actor_top10.index.name='order'
#打印出来,完工
print(actor_top10)
print('完工,开心!')

借助演员分布的分析思路,各位读者可以对上映地区进行分布分析,欢迎在评论区展示。

此外,想知道1940年上映的电影,可以在评论区留言哟。

部分爬虫代码来自崔庆才老师的著作《python3网络爬虫开发实战》,若侵权,请联系,rockyliu将第一时间删除,谢谢。

猫眼电影排行榜前100爬取案例学习笔记相关推荐

  1. 爬虫(2)-解析库xpath和beautifulsoup爬取猫眼电影排行榜前100部电影

    解析库爬取猫眼电影前100部电影 认为有用的话请点赞,码字不易,谢谢. 其他爬虫实战请查看:https://blog.csdn.net/qq_42754919/category_10354544.ht ...

  2. 爬虫(1)-正则化表达式爬取猫眼电影排行榜前100部电影

    爬取猫眼电影排行榜前100部电影 文章目录 爬取猫眼电影排行榜前100部电影 1.抓取首页 2.正则化表达式提取信息 3.保存到文件中 4.抓取前100部电影 认为有用的话请点赞,码字不易,谢谢. 其 ...

  3. Python语言实现用requests和正则表达式方法爬取猫眼电影排行榜前100部电影

    #爬取猫眼电影排名前100的电影 import requests #电脑向服务器发送的请求库 from requests.exceptions import RequestException impo ...

  4. 进击的爬虫-003-beautifulsoup实现猫眼电影前100爬取

    BeutifulSoup beautifulsoup是python的一个xml , html解析库, 借助网页的结构和属性等特性来解析网页,只需要简单的几条语句, 就可以用来方便的从网页中提取数据 选 ...

  5. 爬取猫眼电影网前100的电影排名

    爬取猫眼电影网前100的电影排名 猫眼电影网:http://maoyan.com/board/4 确定要爬取的数据: 1:排名 2:电影名称 3:主演 4:上映舌尖 5:评分 构造下一页url 首页: ...

  6. python爬电影排名用os bs4_Pyhton网络爬虫实例_豆瓣电影排行榜_BeautifulSoup4方法爬取...

    -----------------------------------------------------------学无止境------------------------------------- ...

  7. 英雄联盟峡谷之巅前100爬取(动态网页+json格式解析)

    目的是爬取英雄联盟官网的峡谷之巅前100的信息,经观察发现,每一页只有25个玩家的信息. 先看网页源代码 看到前面,结构清晰,很好抓取. 到了中间部分发现只有前25个,后面的数据貌似被隐藏了.在此处可 ...

  8. python xpath爬取电影top100_进击的爬虫-002-xpath实现猫眼电影前100爬取

    nodename : 选取此节点的所有子节点 / : 从当前节点选取直接子节点 // : 从当前节点选取子孙节点 . : 选取当前节点 .. : 选取当前节点的父节点 @ : 选取属性 3. 使用 3 ...

  9. Python爬虫笔记————抓取 猫眼电影排行榜Top100

    注:初学爬虫,本节仅使用requests库和使用正则作为解析工具 最近学习爬虫,找个比较简单的网页练习了一下,作为初入爬虫的小白,不足之处还请大家多多指教. 一.分析url 首先,打开目标站点http ...

  10. 2019-01-18-Python爬取猫眼电影排行榜

    title: Python爬取猫眼电影排行榜 date: 2019-01-18 20:44:16 tags: python lxml requests json categories: python ...

最新文章

  1. python在线-python+在线
  2. 让Dreamweaver支持phtml
  3. flutter 按钮_【Flutter】ButtonBar和ToggleButtons组合按钮
  4. java 错误输入异常_在Java中进行输入验证期间用错误通知替换异常
  5. 瑞德西韦有效吗?专家一句大实话解释清楚了
  6. oom机制分析及对应优化策略
  7. Java入门学习笔记之变量与计算
  8. Linux文件上传下载sz 和 rz 命令
  9. [学习笔记]数据库设计概览
  10. 联想微型计算机 y720,联想拯救者Y720评测:有颜值的实力派
  11. 巧用 selenium 解决验证码,模拟登陆某流行网站
  12. linux拷贝安装包到另一个目录下,把windows下的压缩包放到Linux目录下去
  13. python取出字典重复值_在Python中的字典中查找具有重复值的键
  14. Unix/Linux编程:getcontext、setcontext
  15. softmax回归从零开始实现
  16. 如何下载 TI 公司的官方例程以及为用户写好的标准头/源文件
  17. Android之低功耗蓝牙的基本使用
  18. 365天深度学习训练营-第P6周:好莱坞明星识别
  19. python公众号文章_Python抓取微信公众号文章
  20. C htonl()函数

热门文章

  1. 微信群二维码活码生成管理系统源码
  2. 4针串口线接法图_串口通信RS232的基本接法,原来这么简单,今天终于弄明白了...
  3. 2020.11.14--AE--图层八种形式、图层面板图标、查看器面板
  4. Vue + Spring Boot 项目实战
  5. Pr 音频效果参考:其它
  6. 计算机函数两个表格找相同,wps筛选出两个表格中的重复项(countif 函数简单使用)【已解决】...
  7. 科学计算机使用方法,[转载]科学计算器的使用方法
  8. 读《看见》第一章观后有感
  9. c语言召唤窗口,如何设计出高点击率的行为召唤按钮?
  10. [C/C++]标准MIDI文件格式