前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬取猫眼电影TOP100榜单所有信息

爬取猫眼电影TOP100榜单所有信息

作者头像
啃饼思录
发布2018-10-15 17:34:09
1.3K0
发布2018-10-15 17:34:09
举报

实战第二篇:爬取猫眼电影TOP100榜单所有信息

哈哈哈,同志们好久不见,今天来教大家如何爬取猫眼电影TOP100榜单的所有信息。猫眼电影这个网站可以说设计的非常规范,非常适合小白练手去获得自豪感。所以话不多说,我们开始介绍吧,走你~~~

目标:爬取猫眼电影TOP100榜单所有信息

1、分析站点,找规律

猫眼电影的网址为:http://maoyan.com/,但这不是我们此次想爬取的站点,我们爬取的站点是这个:http://maoyan.com/board/4(TOP100榜单)

接着看一下我们需要爬取的内容:

通过观察我们需要爬取的内容有:片名,图片,排名,主演,上映时间和评分这6部分。为防止出现因javascript脚本控制而导致源代码与我们实际看到的不一致这个问题的发送,我们直接在chrome的监听组件里面选择network,然后直接点击查看response,这样就能得到实际的代码(实际上这个榜单是静态加载的,源代码和实际代码是一样的,但是养成好习惯,在这里看就不怕javascript控制的问题了)

2.写代码,开始爬取网页

我们先确定一下影片的详细位置,这里你可以选择采用css选择器或是xpath选择器,但是为了和前面的正则表达式进行一个复习,我就使用正则表达式了。

通过观察,我们发现每一个电影都在一个<dd></dd>标签里面,所以我随便取出一个进行分析,然后根据正则表达式依次写出匹配规则:

```

<dd>.*?board-index.*?>(.*?)</i>.*?<.*?data-src="(.*?)".*?<p.*?name.*?a.*?>(.*?)</a>.*?<p.*?star.*?>(.*?)</p>.*?<p.*?releasetime.*?>(.*?)</p>.*?<p.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i></p>

```

完整的代码如下:

代码语言:javascript
复制
import requests
import re
import json
import time


# 获取单个页面
def get_one_page(url):
    headers = {
        "User-Agent": " Chrome/66.0.3359.139 Safari/537.36"
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


# 解析单个页面
def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?<.*?data-src="(.*?)".*?<p.*?name.*?a.*?>(.*?)</a>.*?<p.*?star.*?>'
                         '(.*?)</p>.*?<p.*?releasetime.*?>(.*?)</p>.*?<p.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i></p>'
                        , re.S)  # re.S表示可以换行匹配
    items = re.findall(pattern, html)
    for item in items:
        yield {
            '排名': item[0],
            '图片': item[1],
            '片名': item[2].strip(),
            '主演': item[3].strip()[3:] if len(item[3]) > 0 else '',
            '上映时间': item[4].strip()[5:] if len(item[4]) > 0 else '',
            '评分': item[5]+item[6].strip(),
        }

        # 注意一下,这里需要用yield,而不是return。yield函数返回的是一个生成器(一种特殊的迭代器,可以用for循环进行遍历)
        # 如果用return,那么在第一轮循环结束就会跳出,只能获取到一部影片的信息


# 将信息进行写入
def write_to_file(content):
    with open('maoyan.txt', 'a', encoding='utf-8')as f:  # 采用append追加模式,字符集为utf8
        f.write(json.dumps(content, ensure_ascii=False)+'\n')   # 采用json的dumps方法来初始化字符串
        # 注意一下,这里的ensure_ascii必须为False,因为son默认是以ASCII来解析code的,而中文不在ASCII编码当中,因此就禁止默认的ASCII生效,这也就是我们前面为啥自己定义字符集的原因


# 主方法
def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        write_to_file(item)


# 获取多个页面
if __name__ == '__main__':
    for i in range(10):
        main(offset=i*10)
        time.sleep(1)

你别看上面的代码很多,这里其实就是构造了HTML下载器、HTML解析器和数据存储器这三个模块而已。采用模块化的思想,各个模块完成各自的任务,从而提高工作效率。当然为了提高爬取的效率,可以开启多进程的模式:

代码语言:javascript
复制
import requests
import re
import json
import time
from multiprocessing import Pool


# 获取单个页面
def get_one_page(url):
    headers = {
        "User-Agent": " Chrome/66.0.3359.139 Safari/537.36"
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


# 解析单个页面
def parse_one_page(html):
    pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?<.*?data-src="(.*?)".*?<p.*?name.*?a.*?>(.*?)</a>.*?<p.*?star.*?>'
                         '(.*?)</p>.*?<p.*?releasetime.*?>(.*?)</p>.*?<p.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i></p>'
                        , re.S)  # re.S表示可以换行匹配
    items = re.findall(pattern, html)
    for item in items:
        yield {
            '排名': item[0],
            '图片': item[1],
            '片名': item[2].strip(),
            '主演': item[3].strip()[3:] if len(item[3]) > 0 else '',
            '上映时间': item[4].strip()[5:] if len(item[4]) > 0 else '',
            '评分': item[5]+item[6].strip(),
        }

        # 注意一下,这里需要用yield,而不是return。yield函数返回的是一个生成器(一种特殊的迭代器,可以用for循环进行遍历)
        # 如果用return,那么在第一轮循环结束就会跳出,只能获取到一部影片的信息


# 将信息进行写入
def write_to_file(content):
    with open('maoyan.txt', 'a', encoding='utf-8')as f:  # 采用append追加模式,字符集为utf8
        f.write(json.dumps(content, ensure_ascii=False)+'\n')   # 采用json的dumps方法来初始化字符串
        # 注意一下,这里的ensure_ascii必须为False,因为son默认是以ASCII来解析code的,而中文不在ASCII编码当中,因此就禁止默认的ASCII生效,这也就是我们前面为啥自己定义字符集的原因


# 主方法
def main(offset):
    url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        write_to_file(item)


# 获取多个页面
if __name__ == '__main__':
    p = Pool(4)
    p.map(main, [i * 10 for i in range(10)])
    time.sleep(1)

3、代码输出结果:

怎么样?是不是觉得自己很厉害!给自己鼓个掌先,撒个花先!

总结一下:

本例采用requests+ re的形式对猫眼电影TOP100榜单的所有信息进行了爬取,对于小白而言这是最容易懂的爬取例子。后面随着学习的不断深入,我们会挑战一些更有趣的,更难的例子。我们这里只爬取了TOP100榜单,那么小伙伴们还等什么,可以去爬取其他的4个榜单吧。

好了本篇关于爬取猫眼电影TOP100榜单的介绍就到此为止了,感谢你的赏阅!

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

本文分享自 啃饼思录 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档