数据解析之bs4

选择器bs4进行数据解析:

  • 数据解析的原理:首先进行标签定位,然后进行提取标签以及标签属性中存储的数据
  • bs4数据解析的原理:首先实例化一个BeautifulSoup对象,并将页面源码数据加载到该对象中,然后通过调用BeautifulSoup对象中相关的属性和方法进行标签定位和数据提取
  • 环境安装:bs4与lxml
  • 实例化BeautifulSoup对象:

    1、导包:from bs4 import BeautifulSoup

    2、对象的实例化,有两种方法:

      方法一:将本地的html文档中的数据加载到该对象中

        fp = open('./test.html','r',encoding='utf-8')

        soup = BeautifulSoup(fp,'lxml')             # 参数二是固定的,参数一是本地的html的文件指针fp

      方法二:将互联网上获取的源码页面加载到该对象中 

        page_text = response.text

        soup = BeautifulSoup(page_text,'lxml')

    3、提供的用于数据解析的方法和属性:

      soup.tagName(标签名):返回的是文档中第一次出现的tagName对应的标签

 

 

 

 

 

      soup.find():返回一个单数,只能找到符合要求的第一个标签的内容

        (1)find('tagName'):等同于soup.tagName

        (2)属性定位:soup.find('tagName',属性名='属性值')  ------------------------------------------------------------- 【若属性名为特殊的class等,加个下划线即可】

 

 

      soup.find_all('tagName'):返回一个复数(列表),可以找到符合要求的所有标签内容

      soup.select():

        soup.select('某种选择器(id、class、标签等)'),返回一个列表  ------------------------------------------------------------- 【类选择器写法 .value值】

 

 

        层级选择器soup.select('选择器1 > 选择器2 > 选择器3')[Num]: > 表示一个层级,因为返回的是一个列表,所以用[Num]表示选取列表中的第Num个内容     

 

 

        层级选择器soup.select('选择器1 > 选择器2 选择器3'):空格表示多个层级

    4、获取标签之间的文本数据:

      在定位到某个标签后,还需要获取,比如:soup.a.text、soup.a.string、soup.a.get_text()

      区别:.text与.get_text()可以获取某一标签中所有的文本内容;.string只可以获取该标签下直系的文本内容

    5、获取标签中的属性值:

      soup.a['属性名称']

  • 实际案例:爬取某小说的标题与章节内容

    首先,对首页数据进行爬取,按照之前的代码会存在抓取到的数据乱码的问题,于是对代码进行了改进:

    # 对首页页面数据进行爬取
    url = 'https://www.shicimingju.com/book/sanguoyanyi.html'

    # 解决标题乱码
    html = requests.get(url=url,headers=headers)
    html.encoding = 'utf-8'
    page_text = html.text

  然后通过分析可知,我们要找的章节标题和详情页的超链,在class为book_mulu的div中:

 

   那么就可以开始编写代码了,通过select解析,初步解析出一个存放<li>标签内容的列表,然后对该列表进行遍历,每次要通过string获取单个<li>标签中的<a>标签的内容,即为标题;再获取标签属性值href,即为每章节详情页的url,接下来模拟对每章详情页发送请求,然后解析出小说正文内容,最后获取到并进行持久化存储,over!!!

    for li in li_list:
        # 获取li标签中的a标签的数据,因为string只能获取直系数据
        title = li.a.string
        detail_url = 'https://www.shicimingju.com/' + li.a['href']

        # 对详情页发起请求,解析出章节内容
        # 解决文本乱码
        html_detail = requests.get(url=detail_url,headers=headers)
        html_detail.encoding = 'utf-8'
        detail_page_text = html_detail.text

        # 解析出详情页中的章节内容
        detail_soup = BeautifulSoup(detail_page_text,'lxml')
        div_tag = detail_soup.find('div',class_='chapter_content')

        # 获取章节内容
        content = div_tag.text

        # 持久化存储
        fp.write(title + ':' + content + '\n')
        print(title,'爬取成功!!!')

 

posted @ 2022-01-17 20:06  Sunshine_y  阅读(879)  评论(0编辑  收藏  举报