Beautiful Soup 爬虫实战

上回我们讲解了 Beautiful Soup 的基本使用方法,这次就带大家使用 Beautiful Soup 进行实战。这次要抓取的目标是豆瓣电影 TOP250,解析出其中的电源名称、评分、简单评价、评价人数等信息,其 base_url 是 https://movie.douban.com/top250

其实简单的网络爬虫无外乎查看网页源码,从源码中获取自己想要的东西,然后对其进行处理。

1 解析 - 获取目标元素

我们首先按下 F12 看下目标远视眼的 HTML 源码:

豆瓣电影 Top 250
豆瓣电影 Top 250

通过查看页面元素代码可以看出:

  1. 电影条目是被 <ol class="grid_view"> 所包围的;
  2. 其中每个电影条目是一个 <li>
  3. 另外,每页有 25 个条目,共 10 页,这意味着需要解析多页数据。

再来看下其中一个条目的源码:

<li>
    <div class="item">
        <div class="pic">
            <em class="">1</em>
            <a href="https://movie.douban.com/subject/1292052/">
                <img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class=""></a>
        </div>
        <div class="info">
            <div class="hd">
                <a href="https://movie.douban.com/subject/1292052/" class="">
                    <span class="title">肖申克的救赎</span>
                    <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
                    <span class="other">&nbsp;/&nbsp;月黑高飞(港) / 刺激1995(台)</span></a>
                <span class="playable">[可播放]</span></div>
            <div class="bd">
                <p class="">导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...
                    <br>1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情</p>
                <div class="star">
                    <span class="rating5-t"></span>
                    <span class="rating_num" property="v:average">9.6</span>
                    <span property="v:best" content="10.0"></span>
                    <span>1041580人评价</span></div>
                <p class="quote">
                    <span class="inq">希望让人自由。</span></p>
                <p>
                    <span class="gact">
                        <a href="https://movie.douban.com/wish/50494322/update?add=1292052" target="_blank" class="j a_collect_btn" name="sbtn-1292052-wish" rel="nofollow">想看</a></span>&nbsp;&nbsp;</p>
            </div>
        </div>
    </div>
</li>

对于每个条目,我们需要解析出其中的 电影名称、评分、评价人数,及一句话点评。

1.1 标题、评分、评价解析

标题是在 <span class="title">肖申克的救赎</span> 里的,我们可以结合上回的 Beautiful Soup 来获取:

title = soup.find("span", attrs={"class": "title"}).getText()

在 HTML 源码里,发现有多个标题:<span class="title">,这里我们就只获取第一个,其他的不关心。

评分和评价的解析和标题类似,用同一种解析方法解析即可。

# 评分
rating_num = soup.find("span", attrs={"class": "rating_num"}).getText()
# 评价
inq = soup.find("span", attrs={"class": "inq"}).getText()

1.2 评价人数解析

评价人数这里是这样的: <span>1041580人评价</span>,明显跟上面的不同,它没有 class 属性,这里只能通过 text 来查找了:

find(text=re.compile('人评价$'))

这里用了正则表达式来进行匹配,即匹配以 人评价 结尾的文本。

或者你有什么其他好的方法,也可以留言交流。

1.3 下一页解析

<span class="next">
    <link rel="next" href="?start=25&amp;filter="/>
    <a href="?start=25&amp;filter=" >后页&gt;</a>
</span>

对照代码,需要从中解析出下一页的连接 ?start=25&amp;filter=

解析方法类似于标题的解析,先解析出 <span class="next">,然后解析其中的 <a> 标签。

next_page = soup.find("span", attrs={"class":"next"}).find("a")

要解析的东西基本上就是这些,最后需要将解析结果整合保存到文本文件中。

2 实现代码

# encoding:utf-8

import requests, re
from bs4 import BeautifulSoup

def download_page(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "lxml")
    return soup

def parse_soup(soup):
    return_list = []
    # 利用 class 属性找到 grid
    grid = soup.find("ol", attrs={"class": "grid_view"})
    # 不加 attrs= 也可以
    # grid = soup.find("ol", {"class": "grid_view"})
    if grid:
        # 利用标签获取 list
        movie_list = grid.find_all("li")

        # 遍历 list
        for movie in movie_list:
            # 一个电影有多个名字,这里只取第一个
            title = movie.find("span", attrs={"class": "title"}).getText()
            rating_num = movie.find("span", attrs={"class": "rating_num"}).getText()
            inq = movie.find("span", attrs={"class": "inq"})
            # 利用 text 配合正则表达式匹配搜索文本
            rating_p = soup.find(text=re.compile('人评价$'))
            # 有些暂时没有一句话评论
            if not inq:
                inq = "暂无"
            else:
                inq = inq.getText()
            return_list.append(title + "," + rating_p + ",评分:" + rating_num + ",一句话评价:" + inq)

        next_page = soup.find("span", attrs={"class":"next"}).find("a")
        if next_page:
            return return_list, next_page["href"]
        else:
            return return_list, None

if __name__ == "__main__":
    url = "https://movie.douban.com/top250"
    next_url = ""
    # 将结果保存到文件
    with open("doubanMoviesTop250.txt","w+") as f: 
        while next_url or next_url == "":
            soup = download_page(url + next_url)
            movie_list, next_url = parse_soup(soup)
            # 将 list 拆分成不同行
            f.write("\n".join(movie_list))

3 运行结果

$ cat doubanMoviesTop250.txt
肖申克的救赎,1041580人评价,评分:9.6,一句话评价:希望让人自由。
霸王别姬,1041580人评价,评分:9.5,一句话评价:风华绝代。
这个杀手不太冷,1041580人评价,评分:9.4,一句话评价:怪蜀黍和小萝莉不得不说的故事。
阿甘正传,1041580人评价,评分:9.4,一句话评价:一部美国近现代史。
美丽人生,1041580人评价,评分:9.5,一句话评价:最美的谎言。
千与千寻,1041580人评价,评分:9.3,一句话评价:最好的宫崎骏,最好的久石让。
泰坦尼克号,1041580人评价,评分:9.3,一句话评价:失去的才是永恒的。
辛德勒的名单,1041580人评价,评分:9.4,一句话评价:拯救一个人,就是拯救整个世界。
...

篇幅有限,这里未展示全部。

4 总结

本文中举得例子虽然简单,但是「麻雀虽小五脏俱全」,涉及到了 Beautiful Soup 的各个方法以及文件的读写。网站的爬虫基本流程答题如此,其他要解决的就是用户认证、反爬的应对等问题,后续再一一讲解。


如果觉得有用,欢迎关注我的微信,有问题可以直接交流,另外提供精品 Python 资料!

你的关注是对我最大的鼓励!
你的关注是对我最大的鼓励!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • Install 2 python packages: $ sudo pip install requests$ s...
    lune819阅读 109评论 0 0
  • 作为一一名记者不仅要追求时效更要追求真实性。比如一起车祸,不仅要报道事件本事还要涉及多各方面,例如对司机的驾...
    17广电_刘志峰_07阅读 204评论 0 0
  • 梦是什么?意念是什么?没有人能完全解释清楚,在真真假假的世界里,分不清楚到底是梦还是现实。 在看电影之前,G反复强...
    海绵宝宝来了阅读 175评论 0 0
  • 做沙龙,遇到了一位母亲。沙龙主题是“读懂孩子”,问学员对收获的期待时,她提出一个问题:我的孩子11岁,我特别想跟他...
    呆蒙323阅读 496评论 2 1
  • 妈妈在养育婴幼儿的头几年,遇到的最头痛的事情,十有八九会有消化上的问题。 兜兜妈妈:兜兜1岁9个月了,我就搞不明白...
    精彩遇见阅读 221评论 0 0