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

实战第二篇:爬取猫眼电影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>

```

完整的代码如下:

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解析器和数据存储器这三个模块而已。采用模块化的思想,各个模块完成各自的任务,从而提高工作效率。当然为了提高爬取的效率,可以开启多进程的模式:

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榜单的介绍就到此为止了,感谢你的赏阅!

原文发布于微信公众号 - 啃饼思录(kbthinking)

原文发表时间:2018-09-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏牛客网

2018秋招面经-后端开发

1863
来自专栏闰土大叔

如何解释vue的生命周期才能令面试官满意?

当面试官问:“谈谈你对vue的生命周期的理解”,听到这句话你是不是心里暗自窃喜:这也太容易了吧,不就是beforeCreate、created、beforeMo...

3685
来自专栏魂祭心

原 Data Access Compone

3486
来自专栏FreeBuf

基于时延的盲道研究:受限环境下的内容回传信道

在一次漏洞赏金活动中,挖到个命令注入的洞,我先以时延作为证明向厂商提交该漏洞,厂商以国内网络环境差为由(的确得翻墙)拒收,几次沟通,告知若我能取回指定文件 se...

1375
来自专栏非著名程序员

常见面试第四题之requestLayout, invalidate和postInvalidate的异同

requestLayout, invalidate和postInvalidate的异同 ? 今天我们来讲讲在面试当中最常见的,最常常被问到的第四题,近期由于小...

2545
来自专栏大数据钻研

献给前端求职路上的你们(下)

真正面试中,面试官往往采用的是由难到易的套路,那js和jQuery就是重中之重了,以及针对项目和所用技术方面的一些问题也就是你的必备储粮啦! JavaScrip...

3036
来自专栏WeTest质量开放平台团队的专栏

低于0.01%的极致Crash率是怎么做到的?

4234
来自专栏CRPER折腾记

CSS-Next : CSS预处理器简单写法的替代者, 想了解下么?

借助相关的插件我们可以把新的特性降级到 css3乃至一些特性降级到css2.1...无缝过渡

1102
来自专栏编程

C语言在嵌入式系统编程时的注意事项

C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程...

6317
来自专栏ZRJ的专栏

spark 写 gp/tpg 效率优化:写入 237w 行数据耗时从 77 分钟到 34 秒

写这个文章的点主要是分享一下spark 写 gp/tpg 效率优化 ,这个过程中的一些思路历程和细节。

1.5K1

扫码关注云+社区

领取腾讯云代金券