02.爬虫---解析数据和提取数据---BeautifulSoup
BeautifulSoup不是Python库,需要单独安装-
pip install BeautifulSoup4 #Mac是pip3
一、解析数据
-
bs对象:bs对象=BeautifulSoup(要解析的文本,'解析器'),
其中,要解析的文本必须是字符串!后面的参数用来标识解析器,现在用的是一个Python内置库:html.parser。(它不是唯一的解析器,但是比较简单的)
import requests
from bs4 import BeautifulSoup
res=requests.get('https://localprod.pandateacher.com/python-manuscript/crawler-html/spider-men5.0.html')
html=res.text
#这里html是str类型
soup=BeautifulSoup(html,'html.parser')
#将html(str类型)转换成soup(被解析过的BeautifulSoup对象)。html和soup打印出来的是一样的文本,是因为BeautifulSoup对象在直接打印它的时候会调用该对象内的str方法,所以直接打印 bs 对象显示字符串是str的返回结果。
#但将str转换成BeautifulSoup对象才能调用相关的属性的方法
print(soup)
print(type(soup))
二、提取数据
提取数据的两大知识点:find()和find_all(),Tag对象。
1)find()和find_all()
是BeautifulSoup对象的两个方法,可以匹配html的标签和属性
find()与find_all()的用法 | |||
方法 | 作用 | 用法 | 结果类型 |
find() | 提取满足要求的首个数据 | BeautifuSoup对象.find(标签,属性) | <class 'bs4.element.Tag'>,说明这是一个Tag类对象。 |
find_all() | 提取满足要求的所有数据 | BeautifuSoup对象.find_all(标签,属性) | <class 'bs4.element.ResultSet>,可以把它当做列表list来看待,遍历它后的每个对象又是Tag类型。 |
- find()方法
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')
item=soup.find('div')
#提取出网页中第一个<div>元素
print(item)
print(type(item))
#打印了它的数据类型:<class 'bs4.element.Tag'>,说明这是一个Tag类对象。
find()方法找到的结果类型是Tag对象,说明他可以接着再调用find()和find_all()方法(Tag对象也有这两个方法)
- find_all()方法
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')
item=soup.find_all(class_='books')
#提取出网页中全部class_='books'的元素
print(item)
print(type(item))
#数据类型是<class 'bs4.element.ResultSet>,可以把它当做列表list来看待。
#取列表中的值可以直接用for i in item: print(i),将列表变为<class 'bs4.element.Tag'>,说明这是一个Tag类对象
find_all()方法找到的结果类型<class 'bs4.element.ResultSet>,可以把它当做列表list来看待,遍历它后的每个对象又是Tag类型,又可以继续调用find()和find_all()方法。
2)Tag对象
Tag对象的三种常用属性与方法 | |||
属性/方法 | 作用 | ||
Tag.find()和Tag.find_all() | 提取Tag中的Tag | ||
Tag.text | 提取Tag之间的文字,str类型 | ||
Tag['属性名'] | 提取Tag中该属性的值,str类型 |
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')
items = soup.find_all(class_='books')
for item in items:
kind = item.find('h2')
title = item.find(class_='title')
brief = item.find(class_='info')
print(kind.text,'\n',title.text,'\n',title['href'],'\n',brief.text)
# 打印书籍的类型、名字、链接和简介的文字
3)总结
(该图来自于www.pypypy.cn)
4)简单的练习(自己写的)
爬取某个书店的分类
import requests
from bs4 import BeautifulSoup
link='http://books.toscrape.com/'
res=requests.get(link)
html=res.text
soup=BeautifulSoup(html,'html.parser')
item=soup.find(class_="nav nav-list").find_all('ul')
#print(type(item))
for i in item:
category=i.find_all('a')
for c in category:
print(c.text.strip())
爬取某个书店的书名、星级、价格
import requests
from bs4 import BeautifulSoup
res=requests.get("http://books.toscrape.com/catalogue/category/books/travel_2/index.html")
html=res.text
soup=BeautifulSoup(html,'html.parser')
li_items=soup.find(class_="col-sm-8 col-md-9").find('section').find('ol').find_all('li')
for li in li_items:
a=li.find('h3').find('a')
name=a['title']
#name是str
print('书名:'+name)
p=li.find('p')
rating=p['class'][1]
#rating是list
print('星级:'+rating)
price=li.find(class_="price_color")
#print(type(price))
#price是Tag
print('价格:'+str(price.text))
print("-------------------------")
豆瓣TOP250电影爬取---不用代理,翻页版
import requests
from bs4 import BeautifulSoup
def movie_name(url):
#获取某页的电影名
res=requests.get(url)
html=res.text
soup=BeautifulSoup(html,'html.parser')
items=soup.find(class_="grid-16-8 clearfix").find(class_="grid_view").find_all('li')
for i in items:
title=i.find(class_="hd").find(class_="title")
print(title.text)
#下一页链接
try:
next=soup.find(class_="paginator").find(class_="next").find('a')['href']
except TypeError:
return 0
else:
return 'https://movie.douban.com/top250'+next
next='https://movie.douban.com/top250?start=0&filter='
count=0
while next!=0:
#movie_name(next)
count+=1
next=movie_name(next)
print('-----------以上是第'+str(count)+'页-----------')