前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何抓取猫眼电影Top100的影片信息?

如何抓取猫眼电影Top100的影片信息?

作者头像
测试小兵
发布2019-11-20 10:07:41
4990
发布2019-11-20 10:07:41
举报
文章被收录于专栏:猪圈子

01

进入正文

对于喜好电影的同学来说,猫眼电影和豆瓣电影应该是比较熟悉的电影评分的平台。但是,如何通过Python抓取猫眼电影评分前100的信息呢?

URL获取

我们还是先分析URL。打开猫眼电影TOP100榜,可以看到如下页面:

URL为:http://maoyan.com/board/4。但是,这一页只有排名前10的电影,如何获取下页的URL呢?

点击下方的下一页,可以跳转到第二页:

URL为:http://maoyan.com/board/4?offset=10。由此,可以猜测offset的取值范围为0,10,20,...,90。由此,我们可以构造出10个页面的URL:

代码语言:javascript
复制
for i in range(10):
    offset = 10*i
    url = 'http://maoyan.com/board/4?offset=' + str(offset)

获取到页面后,下一步就是对页面进行解析了。

页面解析

下面看一下具体的页面,在查看网页源码可以看到具体的内容。以排名第一的霸王别姬为例,HTML码如下:

本文是通过正则表达式来获取影片的信息,所以先要生成正则表达式的Pattern。我们想要提前的信息有:排名,影片名称,演员,上映时间,评分。

匹配的表达式的写法很简单,需要找到一些关键的标签,然后在需要的信息处加入(.*?),若匹配到表达式,就会返回相应的项。

另外,还需要对响应的字段进行截取,获取真正需要的信息。具体代码如下:

代码语言:javascript
复制
def parse_one_page(html):
    '''
    通过正则表达式解析html,并格式化数据
    :param html: 
    :return: 
    '''

    pat = re.compile(
        '<dd>.*?board-index.*?">(.*?)</i>.*?"name"><a.*?">(.*?)</a>.*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',
        re.S)

    # 正则表达式找到所有匹配的内容
    items = re.findall(pat, html)

    #格式化数据
    for item in items:
        yield {
            '排名': item[0],
            '影片名称': item[1],
            '演员': item[2].strip()[2:],
            '上映时间': item[3].strip()[5:],
            '评分': item[4] + item[5]
        }

数据存储与保存

接下来需要将抓取的数据进行保存了,可以保存到CSV文件,文本文件,关系型数据库MySQL或者是非关系型数据库MongoDB。这里以存储文本文件为例,打开文件的方式为a即追加写文件。

这里要注意的是,因为写入的内容包括汉字,所以需要设置系统编码,设置为UTF-8,如下代码前三行所示:

代码语言:javascript
复制
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def write_into_file(conrent):
    '''
    将抓取的内容写入文件
    :param conrent: 
    :return: 
    '''
    with open('result', 'a') as f:
        f.write(json.dumps(conrent, ensure_ascii=False) + '\n')
        f.close()

伪装成浏览器

对于猫眼电影,有反爬虫策略,如果不设置header,将无法获取到HTML页面,所以,在进行抓取页面的时候,需要设置header:

代码语言:javascript
复制

def get_response(url):
    '''
    抓取HTML页面
    :param url: 
    :return: 
    '''
    try:
        user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
        referer = 'http://www.baidu.com'
        headers = {"User-Agent": user_agent, 'Referer': referer}
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

文件数据

抓取好的文件的数据如下:

代码语言:javascript
复制
{"上映时间": "1993-01-01(中国香港)", "影片名称": "霸王别姬", "排名": "1", "演员": ":张国荣,张丰毅,巩俐", "评分": "9.6"}
{"上映时间": "1994-10-14(美国)", "影片名称": "肖申克的救赎", "排名": "2", "演员": ":蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿", "评分": "9.5"}
{"上映时间": "1953-09-02(美国)", "影片名称": "罗马假日", "排名": "3", "演员": ":格利高利·派克,奥黛丽·赫本,埃迪·艾伯特", "评分": "9.1"}
{"上映时间": "1994-09-14(法国)", "影片名称": "这个杀手不太冷", "排名": "4", "演员": ":让·雷诺,加里·奥德曼,娜塔莉·波特曼", "评分": "9.5"}
{"上映时间": "1998-04-03", "影片名称": "泰坦尼克号", "排名": "5", "演员": ":莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩", "评分": "9.5"}
{"上映时间": "1972-03-24(美国)", "影片名称": "教父", "排名": "6", "演员": ":马龙·白兰度,阿尔·帕西诺,詹姆斯·凯恩", "评分": "9.3"}
{"上映时间": "1988-04-16(日本)", "影片名称": "龙猫", "排名": "7", "演员": ":日高法子,坂本千夏,糸井重里", "评分": "9.2"}
{"上映时间": "1993-07-01(中国香港)", "影片名称": "唐伯虎点秋香", "排名": "8", "演员": ":周星驰,巩俐,郑佩佩", "评分": "9.2"}
{"上映时间": "2001-07-20(日本)", "影片名称": "千与千寻", "排名": "9", "演员": ":柊瑠美,入野自由,夏木真理", "评分": "9.3"}
{"上映时间": "1940-05-17(美国)", "影片名称": "魂断蓝桥", "排名": "10", "演员": ":费雯·丽,罗伯特·泰勒,露塞尔·沃特森", "评分": "9.2"}

完整代码

代码语言:javascript
复制
# coding:utf-8
import requests
from flask import json
from requests.exceptions import RequestException
import re
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def get_response(url):
    '''
    抓取HTML页面
    :param url:
    :return:
    '''
    try:
        user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
        referer = 'http://www.baidu.com'
        headers = {"User-Agent": user_agent, 'Referer': referer}
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

def parse_one_page(html):
    '''
    通过正则表达式解析html,并格式化数据
    :param html:
    :return:
    '''

    pat = re.compile(
        '<dd>.*?board-index.*?">(.*?)</i>.*?"name"><a.*?">(.*?)</a>.*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',
        re.S)

    # 正则表达式找到所有匹配的内容
    items = re.findall(pat, html)

    #格式化数据
    for item in items:
        yield {
            '排名': item[0],
            '影片名称': item[1],
            '演员': item[2].strip()[2:],
            '上映时间': item[3].strip()[5:],
            '评分': item[4] + item[5]
        }

def write_into_file(conrent):
    '''
    将抓取的内容写入文件
    :param conrent:
    :return:
    '''
    with open('result', 'a') as f:
        f.write(json.dumps(conrent, ensure_ascii=False) + '\n')
        f.close()

def get_and_save_one_page(offset):
    '''
    读取并保存第offset页的数据
    :param offset:
    :return:
    '''
    url = 'http://maoyan.com/board/4?offset=' + str(offset)
    html = get_response(url)
    for item in parse_one_page(html):
        write_into_file(item)

if __name__ == '__main__':

    for i in range(10):
        offset = 10*i
        get_and_save_one_page(offset)

本文来源于:python那些事

文部分来源网络,如有侵权请第一时间联系删除。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python测试社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档