Python爬虫利器二之Beautif

发布时间:2019-10-09 10:38:02编辑:auto阅读(1792)

    上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Beautiful Soup,有了它我们可以很方便地提取出HTML或XML标签中的内容,实在是方便,这一节就让我们一起来感受一下Beautiful Soup的强大吧。

    1. Beautiful Soup的简介

    简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

    Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
    Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
    Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。
    废话不多说,我们来试一下吧~

    2. Beautiful Soup 安装

    Beautiful Soup 3 目前已经停止开发,推荐在现在的项目中使用Beautiful Soup 4,不过它已经被移植到BS4了,也就是说导入时我们需要 import bs4 。所以这里我们用的版本是 Beautiful Soup 4.3.2 (简称BS4),另外据说 BS4 对 Python3 的支持不够好,不过我用的是 Python2.7.7,如果有小伙伴用的是 Python3 版本,可以考虑下载 BS3 版本。

    可以利用 pip 或者 easy_install 来安装,以下两种方法均可

    easy_install beautifulsoup4
    pip install beautifulsoup4

    如果想安装最新的版本,请直接下载安装包来手动安装,也是十分方便的方法。在这里我安装的是 Beautiful Soup 4.3.2

    下载完成之后解压

    运行下面的命令即可完成安装

    sudo python setup.py install

    然后需要安装 lxml

    easy_install lxml
    pip install lxml

    另一个可供选择的解析器是纯Python实现的 html5lib , html5lib的解析方式与浏览器相同,可以选择下列方法来安装html5lib:

    easy_install html5lib
    pip install html5lib

    Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。

    3. 开启Beautiful Soup 之旅

    在这里先分享官方文档链接,不过内容是有些多,也不够条理,在此本文章做一下整理方便大家参考。

    4. 创建 Beautiful Soup 对象

    首先必须要导入 bs4 库

    from bs4 import BeautifulSoup

    我们创建一个字符串,后面的例子我们便会用它来演示

    html = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <p class="story">...</p>
    """

    5. 小试牛刀 爬豆瓣的前250热门电影数据

    在使用该脚本时,需要安装下面用到的库先,如这样:

    easy_install requests
    easy_install codecs
    easy_install bs4
    easy_install openpyxl

    脚本文件

    #!/usr/bin/env python
    # encoding=utf-8
    import requests,re
    import codecs
    from bs4 import BeautifulSoup
    from openpyxl import Workbook
    wb = Workbook()
    dest_filename = '电影.xlsx'
    ws1 = wb.active  
    ws1.title = "电影top250"
    
    DOWNLOAD_URL = 'http://movie.douban.com/top250/'
    
    def download_page(url):
        """获取url地址页面内容"""
        headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'
        }
        data = requests.get(url, headers=headers).content
        return data
    
    
    def get_li(doc):
        soup = BeautifulSoup(doc, 'html.parser')
        ol = soup.find('ol', class_='grid_view')
        name = [] #名字
        star_con = [] #评价人数
        score = []  #评分
        info_list = []  #短评
        for i in ol.find_all('li'):
            detail = i.find('div', attrs={'class': 'hd'})
            movie_name = detail.find('span', attrs={'class': 'title'}).get_text() #电影名字
            level_star = i.find('span',attrs={'class':'rating_num'}).get_text() #评分
            star = i.find('div',attrs={'class':'star'})
            star_num = star.find(text=re.compile('评价'))  #评价
    
            info = i.find('span',attrs={'class':'inq'})  #短评
            if info:     #判断是否有短评
                info_list.append(info.get_text())
            else:
                info_list.append('无')
            score.append(level_star)
            
    
            name.append(movie_name)
            star_con.append(star_num)
        page = soup.find('span', attrs={'class': 'next'}).find('a') #获取下一页
        if page:
            return name,star_con,score,info_list,DOWNLOAD_URL + page['href']
        return name,star_con,score,info_list,None
    
    
    def main():
        url = DOWNLOAD_URL
        name = []
        star_con=[]
        score = []
        info = []
        while url:
            doc = download_page(url)
            movie,star,level_num,info_list,url = get_li(doc)
            name = name + movie
            star_con = star_con + star
            score = score+level_num
            info = info+ info_list
        for (i,m,o,p) in zip(name,star_con,score,info):
            col_A = 'A%s'%(name.index(i)+1)
            col_B = 'B%s'%(name.index(i)+1)
            col_C = 'C%s'%(name.index(i)+1)
            col_D = 'D%s'%(name.index(i)+1)
            ws1[col_A]=i
            ws1[col_B] = m
            ws1[col_C] = o
            ws1[col_D] = p
        wb.save(filename=dest_filename)
    
    if __name__ == '__main__':
        main()
    

    6. pip和easy_install区别

    pip和easy_install安装命令有什么区别?
    请看该博文:Python 包管理工具解惑

    参考博文:
    Beautiful Soup用法
    Python 爬虫-模拟登录知乎-爬取拉勾网职位信息
    Python 包管理工具解惑

关键字