Beautiful Soup 爬虫实战

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

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

1 解析 - 获取目标元素

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

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

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

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

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

  2. 1 肖申克的救赎

    导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...
    1994 / 美国 / 犯罪 剧情

    9.6 1041580人评价

    希望让人自由。

    想看  

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

    1.1 标题、评分、评价解析

    标题是在 肖申克的救赎 里的,我们可以结合上回的 Beautiful Soup 来获取:

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

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

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

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

    1.2 评价人数解析

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

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

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

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

    1.3 下一页解析

    
        
        后页>
    
    

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

    解析方法类似于标题的解析,先解析出 ,然后解析其中的 标签。

    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 资料!

    你的关注是对我最大的鼓励!
    你的关注是对我最大的鼓励!

你可能感兴趣的:(Beautiful Soup 爬虫实战)