Python爬虫 | Beautifulsoup解析html页面

时间:2024-01-25 08:59:04

引入

  大多数情况下的需求,我们都会指定去使用聚焦爬虫,也就是爬取页面中指定部分的数据值,而不是整个页面的数据。因此,在聚焦爬虫中使用数据解析。所以,我们的数据爬取的流程为:

  • 指定url
  • 基于requests模块发起请求
  • 获取响应中的数据
  • 数据解析
  • 进行持久化存储

 

数据解析:

  - 被应用在聚焦爬虫。

  - 解析的数据存储在标签之间或者标签对应的属性中

 

BeautifulSoup解析

环境安装

  需要将pip源设置为国内源,阿里源、豆瓣源、网易源等

   - windows

  • (1)打开文件资源管理器(文件夹地址栏中)
  • (2)地址栏上面输入 %appdata%
  • (3)在这里面新建一个文件夹  pip
  • (4)在pip文件夹里面新建一个文件叫做  pip.ini ,内容写如下即可
[global]
timeout = 6000
index-url = https://mirrors.aliyun.com/pypi/simple/
trusted-host = mirrors.aliyun.com

   - linux

  • (1)cd ~
  • (2)mkdir ~/.pip
  • (3)vi ~/.pip/pip.conf
  • (4)编辑内容,和windows一模一样

 

- 需要安装:pip install bs4

     bs4在使用时候需要一个第三方库,把这个库也安装一下

     pip install lxml

    - 环境安装:

        pip install lxml

        pip install bs4

 

 

解析原理

  • 实例化一个BeautifuSoup对象,然后将页面源码数据加载到该对象中;
BeautifulSoup(fp,\'lxml\')
BeautifulSoup(page_text,\'lxml\')
  • 调用该对象相关属性和方法进行标签定位和数据提取;

 

使用流程:       

    - 导包:from bs4 import BeautifulSoup

    - 使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容

       (1)转化本地文件:

             - soup = BeautifulSoup(open(\'本地文件\'), \'lxml\')

       (2)转化网络文件:

             - soup = BeautifulSoup(\'字符串类型或者字节类型\', \'lxml\')

  (3)打印soup对象显示内容为html文件中的内容。打印的是加载到该对象的源码

from bs4 import BeautifulSoup


fp = open(\'./test.html\',\'r\',encoding=\'utf-8\')
soup = BeautifulSoup(fp,\'lxml\')
print(soup)

 

相关属性和方法:

(1)根据标签名查找

  soup.tagName:定位到第一次出现的标签,只能找到第一个符合要求的标签

print(soup.div)

 

print(soup.p)

 

 

(2)获取属性

        - soup.a.attrs       获取a所有的属性和属性值,返回一个字典

        - soup.a.attrs[\'href\']      获取href属性

        - soup.a[\'href\']         也可简写为这种形式

print(soup.a[\'href\'])

 

3)获取内容直接将列表内容转换成字符串,是单数的。不需要join了

        - soup.a.string

        - soup.a.text

        - soup.a.get_text()

    【注意】如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容            

string:                # 直系
text,get_text():       # 所有

 

print(soup.p.string)

 

print(soup.p.text)

 

print(soup.p.get_text)

 

 

(4)find:找到第一个符合要求的标签,加第二个参数是属性定位,如果是class属性需要加一个下划线,否则会被认成关键字。其他的不需要。

soup.find(\'tagName\',attrName="attrValue"):属性定位。返回值是单数

       - soup.find(\'a\')  找到第一个符合要求的

       - soup.find(\'a\', title="xxx")

       - soup.find(\'a\', alt="xxx")

       - soup.find(\'a\', class_="xxx")

       - soup.find(\'a\', id="xxx")

 

print(soup.find(\'div\',class_=\'song\'))

 

(5)find_all:找到所有符合要求的标签

        - soup.find_all(\'a\')

        - soup.find_all([\'a\',\'b\'])       找到所有的a和b标签

        - soup.find_all(\'a\', limit=2)     限制前两个

 

(6)根据选择器选择指定的内容。select选择器返回永远是列表,需要通过下标提取指定的对象          

  常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器

soup.select(\'#feng\')
print(soup.select(\'.song\'))

层级选择器:>表示一个层级,空格表示多个层级

层级选择器是不可以用索引的,而最后返回的列表的基础上是可以用索引的

print(soup.select(\'.tang li > a\')[1])

 

print(soup.select(\'.song > a\'))

 

 

 

案例

案例1:使用bs4实现将诗词名句网站中三国演义小说的每一章的内容爬去到本地磁盘进行存储 

 http://www.shicimingju.com/book/sanguoyanyi.html 

 

import requests
from bs4 import BeautifulSoup

headers={
         \'User-Agent\': \'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\',
     }

def parse_content(url):
    #获取标题正文页数据
    page_text = requests.get(url,headers=headers).text
soup = BeautifulSoup(page_text,\'lxml\')

    #解析获得标签
    ele = soup.find(\'div\',class_=\'chapter_content\')
    content = ele.text                                     #获取标签中的数据值
return content

if __name__ == "__main__":
     url = \'http://www.shicimingju.com/book/sanguoyanyi.html\'
     reponse = requests.get(url=url,headers=headers)
     page_text = reponse.text

     soup = BeautifulSoup(page_text,\'lxml\')                         #创建soup对象
     a_eles = soup.select(\'.book-mulu > ul > li > a\')                     #解析数据
     print(a_eles)
     cap = 1
     for ele in a_eles:
         print(\'开始下载第%d章节\'%cap)
         cap+=1
         title = ele.string
         content_url = \'http://www.shicimingju.com\'+ele[\'href\']
         content = parse_content(content_url)

         with open(\'./sanguo.txt\',\'w\') as fp:
             fp.write(title+":"+content+\'\n\n\n\n\n\')
             print(\'结束下载第%d章节\'%cap)
View Code

 

import requests
from bs4 import BeautifulSoup

headers = {
    \'User-Agent\': \'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'
}
url = \'http://www.shicimingju.com/book/sanguoyanyi.html\'
page_text = requests.get(url=url,headers=headers).text

#数据解析:章节标题,章节内容
soup = BeautifulSoup(page_text,\'lxml\')
a_list = soup.select(\'.book-mulu > ul > li > a\')
fp = open(\'./sanguo.txt\',\'w\',encoding=\'utf-8\')
for a in a_list:                                #把a标签当soup对象使用,因为它也是源码
    title = a.string
    detail_url = \'http://www.shicimingju.com\'+a[\'href\']
    detail_page_text = requests.get(url=detail_url,headers=headers).text
    soup = BeautifulSoup(detail_page_text,\'lxml\')
    content = soup.find(\'div\',class_="chapter_content").text      # bs4中,把text提取出来的列表直接转换成字符串,与xpath不同
    
    fp.write(title+\':\'+content+\'\n\')
    print(title,\'保存成功!\')
fp.close()
print(\'over!\')

 

 

 

 

a_list = soup.select(\'.book-mulu > ul > li > a\')
print(a_list)                            # 一个个a标签

for a in a_list:                                    #把a标签当soup对象使用,因为它也是源码
title = a.string                                # 章节标题
print(title)

for a in a_list:            
    title = a.string
detail_url = \'http://www.shicimingju.com\'+a[\'href\']            # 章节url
print(detail_url)

for a in a_list:            #把a标签当soup对象使用,因为它也是源码
    title = a.string
    detail_url = \'http://www.shicimingju.com\'+a[\'href\']
    detail_page_text = requests.get(url=detail_url,headers=headers).text
    soup = BeautifulSoup(detail_page_text,\'lxml\')
    content = soup.find(\'div\',class_="chapter_content").text

 

 

最终生成文件

 

 

 

 

 

 

 

 

 

 

 

 

 https://blog.csdn.net/qq_36381299/article/details/81000905