专栏首页Flaneur的文章分享Python爬虫--爬取豆瓣 TOP250 电影排行榜

Python爬虫--爬取豆瓣 TOP250 电影排行榜

前言

本篇讲介绍一个简单的Python爬虫案例–爬取豆瓣 TOP250 电影排行榜。 很多朋友在看一部电影前都喜欢先找一下网友们对该片的评价。

说到电影评分的网站,除了国外的 IMDB 和烂番茄,国内要数豆瓣最为出名。

主要原因是豆瓣有一套完整的评分和防水军机制 。

在这套机制下,豆瓣评分高的电影不一定是所有人都喜欢的,但是豆瓣评分低的电影,一定是实打实的烂片!

虽然每个人的喜好偏爱不同,但通常豆瓣评分 8 分以上的电影,都是值得一看的。

豆瓣还专门提供了一个 TOP250 的电影链接 -> https://movie.douban.com/top250

爬取思路

爬取的过程很好理解,这里只需要两个过程: ① 从服务器上下载所需页面 ② 解析这个页面,得到自己需要有用的内容

①抓取页面

有的人可能会利用 urllib 模块实现网络抓取功能。但在 Python 中,有一个更好地替代者——Requests。Requests 简化了 urllib 的诸多冗杂且无意义的操作,并提供了更强大的功能。 所以在这里我们使用 Requests 模块的 get() 方法从服务器上来下载这个页面。

import requests

url = "https://movie.douban.com/top250"
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0"
    }

res = requests.get(url,headers=headers)

res就是我们需要的这个页面的资源,我们不妨打开来看看是不是

with open("豆瓣电影.txt",'w',encoding='utf-8') as f:
    f.write(res.text)

打开文本如下图

我们可以看出这确实是当前网页的资源,所以我们就抓取成功了。

②解析页面

解析网页内容推荐使用 BeautifulSoup 模块,它可以化腐朽为神奇,将一个复杂的网页结构转化为书籍目录的形式供你浏览。 例如,我们现在需要解析提取出当前页面的电影名字

import bs4
soup = bs4.BeautifulSoup(res.text,"html.parser")
targets = soup.find_all("div",class_="hd")
for each in targets:
    print(each.a.span.text)

可以得到如下结果

肖申克的救赎 霸王别姬 阿甘正传 这个杀手不太冷 美丽人生 泰坦尼克号 千与千寻 辛德勒的名单 盗梦空间 忠犬八公的故事 海上钢琴师 机器人总动员 三傻大闹宝莱坞 楚门的世界 放牛班的春天 星际穿越 大话西游之大圣娶亲 熔炉 疯狂动物城 无间道 龙猫 教父 当幸福来敲门 怦然心动 触不可及

这里你可能就会有疑问,这些数据是怎么得来的呢? 我们先来看下 HTML 源代码:

发现每个电影的标题都是位于 <div class="hd">...</div> 标签中的,它的从属关系是:div -> a -> span

所以我们先调用 find_all() 方法,找到所有 class=”hd” 的 div 标签,然后按照从属关系即可直接取出电影名。 同理,我们借用此发方法来解析提取出电影的评分、介绍等需要的信息。

附加问题

我们刚才解析提取的仅仅是第一页的页面,那么还有第二、第三、第四页……呢?

其实,解决起来也很简单,我们可以使用for循环来对每一页进行上述的两个过程。

但,我们此时又有新的问题,我们不可能每抓取一次,就重新输入下一网页的链接地址,这样很麻烦,效率也不高。

我们可以分析每一页的链接:

第一页:https://movie.douban.com/top250 第二页:https://movie.douban.com/top250?start=25 第三页:https://movie.douban.com/top250?start=50 第四页:https://movie.douban.com/top250?start=75 第五页:https://movie.douban.com/top250?start=100 … … …. …

我们可以发现这样的规律: 每一次的更新的 url = https://movie.douban.com/top250 + '/?start=' + str(25*i)其中i可以表示为页数-1

咦,这个时候,你可能会有疑问,我们怎么知道一共有多少页呢,不能一直for循环无穷吧。

那当然不可能的了,我们可以按第二步解析网页方式来获取页数

depth = soup.find('span',class_='next').previous_sibling.previous_sibling.text

注意,这个返回的depth是给字符串形式,需要int()

这样结合刚才的过程,就可以迭代每一页了

代码清单

感兴趣的话,可以试一试哦

import requests
import bs4

#抓取网页
def open_url(url):
    headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0"}
    res = requests.get(url,headers=headers)
    
    return res

#得到总页数
def find_depth(res):
    soup = bs4.BeautifulSoup(res.text,'html.parser')
    depth = soup.find('span',class_='next').previous_sibling.previous_sibling.text

    return int(depth)

#解析网页,提取内容
def find_movies(res):
    soup = bs4.BeautifulSoup(res.text,'html.parser')

    names = []
    target = soup.find_all('div',class_='hd')
    for i in target:
        names.append(i.a.span.text)

    ranks = []
    target = soup.find_all('span',class_='rating_num')
    for i in target:
        ranks.append(i.text)

    messages = []
    target = soup.find_all('div',class_='bd')
    for i in target:
        try:
            messages.append(i.p.text.split('\n')[1].strip() + i.p.text.split('\n')[2].strip())
        except:
            continue

    result = []
    length = len(names)
    for i in range(length):
        result.append(names[i] + ',' +ranks[i] + ',' + messages[i] + '\n')

    return result

def main():
    host = "https://movie.douban.com/top250"
    res = open_url(host)
    depth = find_depth(res)

    result = []
    for i in range(depth):
        url = host + '/?start=' + str(25*i)
        res = open_url(url)
        result.extend(find_movies(res))

    with open("豆瓣TOP250电影.txt",'w',encoding='utf-8') as f:
        for each in result:
            f.write(each)

if __name__=="__main__":
    main()

嘟嘟

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3c2lknoq16w4k

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python判断离散数学的合式公式

            你没有听错,用python程序来解决离散数学的逻辑推理问题,我当我第一次听老师说的时候也很吃惊(再说上学期的Python学的也不咋地…..?),...

    Flaneur
  • K-means算法及python实现

            K-means(Thek-meansalgorithm)是机器学习十大经典算法之一,同时也是最为经典的无监督聚类(Unsupervised Cl...

    Flaneur
  • 多种相似度计算的python实现

            在机器学习中有很多地方要计算相似度,比如聚类分析和协同过滤。计算相似度的有许多方法,其中有欧几里德距离(欧式距离)、曼哈顿距离、Jaccard系...

    Flaneur
  • hadoop使用(四)

    做一个网络爬虫的程序吧,根据客户的需求,要求把相关的内容爬取到本地 最终选择的是apache nutch,到目前为止最新的版本是1.3 1. Nutch是什么?...

    cloudskyme
  • [译]基于以太坊和USDC搭建去中心化金融系统

    在Coinbase,我们希望可以创建一个开放的金融系统。我们坚信提高金融的自由度可以让世界更美好。去中心化金融,简称DeFi是一个开放,无界限并且可以程序化的金...

    Tiny熊
  • 基于puppeteer的网络拦截工具flyover

    我们知道所有请求,无论是页面请求还是js 发起的各种请求,最终都是通过浏览器软件发起的,服务器响应后,都是响应给浏览器的,那么整个工程可以细分为如下流程(个人理...

    Jerremy
  • 开发者\b都喜欢用mac?必须哒

    很可惜,我的第一台mac不是自己买的,是公司里面的一个ios开发用剩下的。不过机器不算是很老,相反性能还很好,是2015款的mac book pro有16g内存...

    Jean
  • python语言实现mac地址自加

       以配置文件中的mac地址为起始地址(形式为xx:xx:xx:xx:xx:xx),并根据步长设置实现mac自加,然后以该mac为源mac模拟报文。

    py3study
  • 无线安全专题_攻击篇--MAC泛洪攻击

    七夜安全博客
  • 基于python 3 的selenium

    注:可以在cmd下通过命令安装selenium模块:pip install selenium 或者 easy_install selenium。

    py3study

扫码关注云+社区

领取腾讯云代金券