• 爬虫之Beautifulsoup模块


    一、介绍

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.目前已经开发到4.0以上了

    baautiful soup常用的解析器如下:

    解析器使用方法优势劣势
    Python标准库 BeautifulSoup(markup, "html.parser")
    • Python的内置标准库
    • 执行速度适中
    • 文档容错能力强
    • Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
    lxml HTML 解析器 BeautifulSoup(markup, "lxml")
    • 速度快
    • 文档容错能力强
    • 需要安装C语言库
    lxml XML 解析器

    BeautifulSoup(markup, ["lxml", "xml"])

    BeautifulSoup(markup, "xml")

    • 速度快
    • 唯一支持XML的解析器
    • 需要安装C语言库
    html5lib BeautifulSoup(markup, "html5lib")
    • 最好的容错性
    • 以浏览器的方式解析文档
    • 生成HTML5格式的文档
    • 速度慢
    • 不依赖外部扩展

    二、BeautifulSoup的使用

    1、遍历文档树

    遍历文档树:即直接通过标签名字选择,特点是选择速度快,但如果存在多个相同的标签则只返回第一个

    # 1、用法:
    from bs4 import BeautifulSoup
    soup=BeautifulSoup(html_doc,'lxml')
    head=soup.head
    # print(head)
    
    # 2、获取标签的名字: 重点
    p = soup.p
    print(p.name) #>: p
    
    # 3、获取标签的属性  重点
    p = soup.body.p # 获取body下的p标签
    print(p.attrs) # 结果:{'id': 'my_p', 'class': ['title']}
    # 获取p标签内属性值的三种方法
    p.attrs.get('class')
    p.get('class')
    p['class']
    
    # 4、获取标签的内容  重点
    '''
    text: 取所选标签内下所有的文本内容
    string: 若所选标签下的文本只有一个时,取到,否则为None
    strings: 拿到一个生成器对象,取下所选标签下的所有文本内容
    stripped_strings: 是去掉空白
    get_text():是用来调取内部属性text的方法。
    区别:string获取的是该标签的直系内容,无法获取该标签子标签的直系内容,
         而text/get_text()可以
    注意:如果选标签下包含多个节点,则string输出结果是None,比如:body下有多个p节点
    '''
    p=soup.body.p
    print(p.text)
    print(p.string)
    print(p.strings)  #结果:<generator object _all_strings at 0x0000026619237BF8>
    for line in p.stripped_strings:
        print(line)
    print(p.get_text())
    
    # 5、嵌套选择    重点
    s = soup.body.a
    print(s.get('id'))
    
    # 6、子节点、子孙节点
    print(soup.p.contents) #取出p下的所有子节点
    print(soup.p.children) #取出包含p标签下所有子节点,返回一个迭代器
    print(list(soup.p.children))
    
    # 7、父节点、祖先节点
    print(soup.a.parent) #获取a标签的父节点(只有一个)
    print(soup.p.parent) #获取p标签的父节点
    print(soup.a.parents) #返回生成器,找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
    print(list(soup.a.parents))#找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
    
    # 8、兄弟节点
    print(soup.a.next_sibling) #下一个兄弟
    print(soup.a.previous_sibling) #上一个兄弟
    
    print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
    print(list(soup.a.previous_siblings)) #上面的兄弟们=>生成器对象

     2、搜索文档树

    (1)find()和find_all()

    '''
     find_all(name , attrs , recursive , text , **kwargs)
     用处:找到所有符合要求的标签
     参数:name是标签名,attrs是一个字典参数,用来搜索包含特殊属性的标签,比如:data-*类型的属性
     recursive:True,则会搜索当前标签的子孙节点,如果是False,则只搜索当前标签的子节点。
     text: 可以是字符,列表,True,正则
     注意:按类名查找的时候,关键字是class_
    '''
    soup.find_all('a') #
    soup.find(['a','p']) #找到所有a和p标签
    soup.find_all('a',limit=2) #找到前两个a标签
    soup.find_all('a',attrs={'data-fooo':'value'})
    soup.find_all('p',attrs={'class':'title'})
    soup.find_all('p',recursive=False)
    soup.find_all('a',text='Lacie')
    soup.find_all(text='Lacie')
    soup.find_all(class_='title')
    '''
     find_(name , attrs , recursive , text , **kwargs)
     用处:找到第一个符合要求的标签
     参数:name是标签名,attrs是一个字典参数,用来搜索包含特殊属性的标签,比如:data-*类型的属性
     recursive:True,则会搜索当前标签的子孙节点,如果是False,则只搜索当前标签的子节点。
     text: 可以是字符,列表,True,正则
     注意:按类名查找的时候,关键字是class_
    '''
    print(soup.find('a')) #寻找a标签
    print(soup.find('a',id='link3'))  #寻找id是link3的a标签
    print(soup.find('a',class_='sister2'))
    print(soup.find('a',title='xxx')) #寻找title是xxx的a标签
    
    '''
    区别:find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.
         find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None 
    '''

    (2) 五种过滤器

    '''
    五种过滤器:字符串、正则表达式、列表、True、方法
    '''
    # 1、字符串:也就是标签名
    soup.find_all('b')
    # 2、正则表达式
    import re
    soup.find_all(re.compile('^b')) #找b开头的标签
    # 3、列表
    soup.find_all(['a','p'])
    # 4、True: 匹配任何值
    soup.find_all(True)  #查找所有标签,但是不会返回字符串节点
    # 5、方法:可以是自己定义的方法
    def myfunc(tag):
        return tag.has_attr('class') and not tag.has_attr('id')
    soup.find_all(myfunc())

    (3)css选择器

    '''
    css选择器:返回的是列表
    '''
    # 1、获取标签
    print(soup.select('.element'))
    print(soup.select('#link3'))
    # 2、获取标签的属性
    soup.select('#link3')[0].attrs
    # 3、获取标签的内容
    soup.select('#link3')[0].get_text()

    三国演义小说爬取案例:

    # -*-coding:utf-8 -*-
    import requests
    from bs4 import BeautifulSoup
    import lxml
    headers={
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
    }
    req=requests.get('http://www.shicimingju.com/book/sanguoyanyi.html',headers=headers)
    soup=BeautifulSoup(req.text,'lxml')
    li_list=soup.select('.book-mulu > ul > li > a')
    
    for li in li_list:
        url='http://www.shicimingju.com'+li['href']
        title = li.string
        req_detail=requests.get(url,headers=headers)
        soup_detail=BeautifulSoup(req_detail.text,'lxml')
        detail_text=soup_detail.find('div',class_='chapter_content').text
        file_name=title+'.txt'
        with open(file_name,'w',encoding='utf-8') as f:
            f.write(detail_text)
            print(title+'   加载完毕')

     爬肯德基餐厅信息(ajax请求,是post请求,返回的是数据)

    # -*-coding:utf-8 -*-
    import requests
    import json
    url='http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
    headers={
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
    }
    # word=input(">>:")
    data={
        'cname': '',
        'pid': '',
        'keyword': '普宁',
        'pageIndex': 1,
        'pageSize': 10,
          }
    res=requests.post(url,data=data,headers=headers)
    print(res.json())
  • 相关阅读:
    web.xml配置文件详解
    spring MVC配置文件详解
    路由导航刷新后导致当前选中的导航样式不见的解决办法
    vue input 使用v-model想要改变父属性的写法
    JS 编写一个指定范围内的随机数返回方法
    vue-router 3.1.5报错:vue-router.esm.js?8c4f:2089 Uncaught (in promise)
    Failed to mount component: template or render function not defined. vue
    vscode 操作debugger for chrome的配置文件写法
    JS操作DOM方法总结
    npm 代理配置的方法
  • 原文地址:https://www.cnblogs.com/nq31/p/14148692.html
Copyright © 2020-2023  润新知