Python【BeautifulSoup解析和提取网页数据】

Posted on 2019-08-31 12:30  CH-TNT  阅读(10762)  评论(0编辑  收藏  举报

 【解析数据】

使用浏览器上网,浏览器会把服务器返回来的HTML源代码翻译为我们能看懂的样子

在爬虫中,也要使用能读懂html的工具,才能提取到想要的数据

 

【提取数据】是指把我们需要的数据从众多数据中挑选出来

 

点击右键-显示网页源代码,在这个页面里去搜索会更加准确

 

安装

pip install BeautifulSoup4(Mac电脑需要输入pip3 install BeautifulSoup4)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

解析数据

 

在括号中,输入两个参数,

第0个参数,必须是字符串类型;

第1个参数是解析器 这里使用用的是一个Python内置库:html.parser

 

 1 import requests
 2 
 3 from bs4 import BeautifulSoup
 4 #引入BS库
 5 
 6 res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')
 7 
 8 html = res.text
 9 
10 soup = BeautifulSoup(html,'html.parser') #把网页解析为BeautifulSoup对象
11 
12 print(type(soup)) #查看soup的类型  soup的数据类型是 <class 'bs4.BeautifulSoup'>  soup是一个BeautifulSoup对象。
13 
14 print(soup)    
15 # 打印soup

response.text和soup 打印出的内容一模一样

它们属于不同的类:<class 'str'> 与<class 'bs4.BeautifulSoup'> 前者是字符串,后者是已经被解析过的BeautifulSoup对象

打印出来一样的原因:BeautifulSoup对象在直接打印的时候会调用对象内的str方法,所以直接打印 bs 对象显示字符串是str的返回结果

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

提取数据

 

find()与find_all()

是BeautifulSoup对象的两个方法

可以匹配html的标签和属性用法一样 

 

区别

find()只提取首个满足要求的数据

find_all()提取出的是所有满足要求的数据

 1 import requests
 2 
 3 from bs4 import BeautifulSoup
 4 
 5 url = 'https://localprod.pandateacher.com/python-manuscript/crawler-html/spder-men0.0.html'
 6 
 7 res = requests.get (url)
 8 
 9 print(res.status_code)
10 
11 soup = BeautifulSoup(res.text,'html.parser')
12 
13 item = soup.find('div') #使用find()方法提取首个<div>元素,并放到变量item里。
14 
15 print(type(item)) #打印item的数据类型
16 
17 print(item)       #打印item
18 
19  
20 200
21 
22 <class 'bs4.element.Tag'>  #是一个Tag类对象
23 
24 <div>大家好,我是一个块</div>
25 
26  
27 
28  
29 
30 items = soup.find_all('div') #用find_all()把所有符合要求的数据提取出来,并放在变量items里
31 
32 print(type(items)) #打印items的数据类型
33 
34 print(items)       #打印items
35  
36 
37 200
38 
39 <class 'bs4.element.ResultSet'>   #是一个ResultSet类的对象
40 
41 [<div>大家好,我是一个块</div>, <div>我也是一个块</div>, <div>我还是一个块</div>]  
42 
43 #列表结构,其实是Tag对象以列表结构储存了起来,可以把它当做列表来处理

 

soup.find('div',class_='books')

class_  和python语法中的类 class区分,避免程序冲突

还可以使用其它属性,比如style属性等

括号中的参数:标签和属性可以任选其一,也可以两个一起使用,这取决于我们要在网页中提取的内容

 

 1 import requests # 调用requests库
 2 
 3 from bs4 import BeautifulSoup # 调用BeautifulSoup库
 4 
 5 res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')# 返回一个Response对象,赋值给res
 6 
 7 html= res.text# 把Response对象的内容以字符串的形式返回
 8 
 9 soup = BeautifulSoup( html,'html.parser') # 把网页解析为BeautifulSoup对象
10 
11 items = soup.find_all(class_='books') # 通过定位标签和属性提取我们想要的数据
12 
13 print(type(items)) #打印items的数据类型 #items数据类型是<class 'bs4.element.ResultSet>, 前面说过可以把它当做列表list
14 
15 #for循环遍历列表
16 
17 for item in items:                     
18 
19     print('想找的数据都包含在这里了:\n',item) # 打印item
20 
21 print(type(item))   #<class 'bs4.element.Tag'> 是Tag对象

#####################################################################

Tag对象

find()和find_all()打印出来的东西还不是目标数据,里面含着HTML标签

xxxxx

items = soup.find_all(class_='books') # 通过定位标签和属性提取我们想要的数据

for item in items:

    print(type(item))

数据类型是<class 'bs4.element.Tag'>,是Tag对象

此时,需要用到Tag对象的三种常用属性与方法

此外,提取Tag对象中的文本,用到Tag对象的另外两种属性——Tag.text,和Tag['属性名']

 

 1 import requests # 调用requests库
 2 
 3 from bs4 import BeautifulSoup # 调用BeautifulSoup库
 4 
 5 res =requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')
 6 
 7 # 返回一个response对象,赋值给res
 8 
 9 html=res.text
10 
11 # 把res解析为字符串
12 
13 soup = BeautifulSoup( html,'html.parser')
14 
15 # 把网页解析为BeautifulSoup对象
16 
17 items = soup.find_all(class_='books')   # 通过匹配属性class='books'提取出我们想要的元素
18 
19 for item in items:                      # 遍历列表items
20 
21     kind = item.find('h2')               # 在列表中的每个元素里,匹配标签<h2>提取出数据
22 
23     title = item.find(class_='title')     #  在列表中的每个元素里,匹配属性class_='title'提取出数据
24 
25     brief = item.find(class_='info')      # 在列表中的每个元素里,匹配属性class_='info'提取出数据
26 
27     print(kind.text,'\n',title.text,'\n',title['href'],'\n',brief.text) # 打印书籍的类型、名字、链接和简介的文字

##################################################################

对象的变化过程 

开始用requests库获取数据,

到用BeautifulSoup库来解析数据,

再继续用BeautifulSoup库提取数据,

不断经历的是我们操作对象的类型转换。

################################################################

提取扩展

嵌套提取好几层: 

find('ul',class_='nav').find('ul').find_all('li')

 

#提取个人理解:

每一个find的属性或者标签都是对应的层