python总结-BeautifulSoup
2019-11-03 本文已影响0人
Zhigang_Han
image.png
image.png
image.png
1、解析数据
bs对象 = BeautifulSoup(要解析的文本,“解析器”)
note:
在括号中,要输入两个参数,第0个参数是要被解析的文本,注意了,它必须必须必须是字符串。
括号中的第1个参数用来标识解析器,我们要用的是一个Python内置库:html.parser。
(它不是唯一的解析器,但是比较简单的)
import requests
#引入BS库
from bs4 import BeautifulSoup
res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')
html = res.text
soup = BeautifulSoup(html,'html.parser') #把网页解析为BeautifulSoup对象
#soup的类型为 <class 'bs4.BeautifulSoup'>
#返回值与 res.text 的值是一样的
那BS的作用或者是区别在哪里呢?
虽然 res.text 和 soup 打印出的内容表面上看长得一模一样,但是它们属于不同的类:
(1)<class 'str'> 与<class 'bs4.BeautifulSoup'>。前者是字符串,后者是已经被解析过的BeautifulSoup对象。
(2)BeautifulSoup对象在直接打印它的时候会调用该对象内的str方法,所以直接打印 bs 对象显示字符串str。
(3)之后BeautifulSoup库会用来提取数据,如果不是 BeautifulSoup 对象,就没办法调用其属性和方法。
2、提取数据
(1)find() 与 find_all()
image.png
上图括号里的class_,这里有一个下划线,是为了和python语法中的类 class区分,避免程序冲突。当然,除了用class属性去匹配,还可以使用其它属性,比如style属性等。
import requests # 调用requests库
from bs4 import BeautifulSoup # 调用BeautifulSoup库
res = requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')# 返回一个Response对象,赋值给res
html= res.text# 把Response对象的内容以字符串的形式返回
soup = BeautifulSoup( html,'html.parser') # 把网页解析为BeautifulSoup对象
items = soup.find_all(class_='books') # 通过定位标签和属性提取我们想要的数据
for item in items:
print('想找的数据都包含在这里了:\n',item) # 打印item
(2) Tag对象
image.png
import requests
from bs4 import BeautifulSoup
res = requests.get("https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html")
html = res.text
soup = BeautifulSoup(html, 'html.parser')#bs对象
items = soup.find_all(class_= "books")#现在就是Tag了,因此换方法喽
for item in items:
#print(item)
kind = item.find('h2')
title = item.find(class_="title")
content = item.find('p')
print(kind.text,"\n",title['href'],"\n",title.text,"\n",content.text,"\n")
注意的是根据属性名提取的时候,必需要在此标签里,不能跨越到上级标签。
从最开始用requests库获取数据,到用BeautifulSoup库来解析数据,再继续用BeautifulSoup库提取数据,不断经历的是我们操作对象的类型转换。其实作用和用力的地方一定是对象!
一张图总结下:
import requests
# 引用requests库
from bs4 import BeautifulSoup
# 引用BeautifulSoup库
res_foods = requests.get('http://www.xiachufang.com/explore/')
# 获取数据
bs_foods = BeautifulSoup(res_foods.text,'html.parser')
# 解析数据
tag_name = bs_foods.find_all('p',class_='name')
# 查找包含菜名和URL的<p>标签
tag_ingredients = bs_foods.find_all('p',class_='ing ellipsis')
# 查找包含食材的<p>标签
list_all = []
# 创建一个空列表,用于存储信息
for x in range(len(tag_name)):
# 启动一个循环,次数等于菜名的数量
list_food = [tag_name[x].text[18:-14],tag_name[x].find('a')['href'],tag_ingredients[x].text[1:-1]]
# 提取信息,封装为列表。注意此处[18:-14]切片和之前不同,是因为此处使用的是<p>标签,而之前是<a>
list_all.append(list_food)
# 将信息添加进list_all
print(list_all)
# 打印
# 以下是另外一种解法
list_foods = bs_foods.find_all('div',class_='info pure-u')
# 查找最小父级标签
list_all = []
# 创建一个空列表,用于存储信息
for food in list_foods:
tag_a = food.find('a')
# 提取第0个父级标签中的<a>标签
name = tag_a.text[17:-13]
# 菜名,使用[17:-13]切掉了多余的信息
URL = 'http://www.xiachufang.com'+tag_a['href']
# 获取URL
tag_p = food.find('p',class_='ing ellipsis')
# 提取第0个父级标签中的<p>标签
ingredients = tag_p.text[1:-1]
# 食材,使用[1:-1]切掉了多余的信息
list_all.append([name,URL,ingredients])
# 将菜名、URL、食材,封装为列表,添加进list_all
print(list_all)
# 打印
···