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)总结

02.爬虫---解析数据和提取数据---BeautifulSoup

(该图来自于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)+'页-----------')