【Python网络爬虫笔记】week02

Beautiful Soup库入门

安装
在cmd中输入

pip install beautifulsoup4

BeautifulSoup库的使用

from bs4 import BeautifulSoup
soup=BeauifulSoup('

data

','html.parser')

Beautiful Soup库的基本元素
【Python网络爬虫笔记】week02_第1张图片
Beautiful Soup库是解析、遍历、维护“标签树”的功能库
【Python网络爬虫笔记】week02_第2张图片
Beautiful Soup库,也叫beautifulsoup4 或 bs4
约定引用方式如下,即主要是用BeautifulSoup类

Beautiful Soup类
【Python网络爬虫笔记】week02_第3张图片
简单来说,BeautifulSoup对应一个HTML/XML文档的全部内容

Beautiful Soup库解析器

解析器 使用方法 条件
bs4的HTML解析器 BeautifulSoup(mk, ‘html.parser’) 安装bs4库
lxml的HTML解析器 BeautifulSoup(mk, ‘lxml’) pip install lxml
lxml的XML解析器 BeautifulSoup(mk, ‘lxml’) pip install lxml
html5lib的解析器 BeautifulSoup(mk, ‘html5lib’) pip install html5lib

Beautiful Soup类的基本元素

基本元素 说明
Tag 标签,最基本的信息组织单元,分别用<>和标明开头和结尾
Name 标签的名字,

的名字是’p’,格式:.name
Attributes 标签的属性,字典形式组织,格式:.attrs
NavigableString 标签内非属性字符串,<>…中字符串,格式:.string
Comment 标签内字符串的注释部分,一种特殊的Comment类型

Tag标签

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
print(soup.title)
tag=soup.a
print(tag)

输出结果如下
在这里插入图片描述
任何存在于HTML语法中的标签都可以用soup.访问获得。当HTML文档中存在多个相同对应内容时,soup.返回第一个


Tag的name

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
print(soup.a.name)
print(soup.a.parent.name)
print(soup.a.parent.parent.name)

输出结果
【Python网络爬虫笔记】week02_第4张图片
每个都有自己的名字,通过.name获取,字符串类型


Tag的attrs

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
tag=soup.a
print(tag.attrs)
print(tag.attrs['class'])
print(tag.attrs['href'])
print(type(tag.attrs))
print(type(tag))

输出结果
【Python网络爬虫笔记】week02_第5张图片
*一个可以有0或多个属性,字典类型


Tag的NavigableString

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
print(soup.a)
print(soup.a.string)
print(soup.p)
print(soup.p.string)
print(type(soup.p.string))

输出结果
【Python网络爬虫笔记】week02_第6张图片
NavigableString可以跨越多个层次


Tag的Comment

from bs4 import BeautifulSoup
newsoup=BeautifulSoup("

This is a comment

"
, "html.parser") print(newsoup.b.string) print(type(newsoup.b.string)) print(newsoup.p.string) print(type(newsoup.p.string))

输出结果
【Python网络爬虫笔记】week02_第7张图片


【Python网络爬虫笔记】week02_第8张图片

基于bs4库的HTML内容遍历方法

HTML基本格式
【Python网络爬虫笔记】week02_第9张图片
遍历方法:上行遍历、下行遍历、平行遍历

标签树的下行遍历

属性 说明
.contents 子节点列表,将所有儿子节点存入列表
.children 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点
.descendants 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历

BeautifulSoup类型是标签树的根节点

#遍历儿子节点
for child in soup.body.children:
    print(child)
#遍历子孙节点
for child in soup.body.descendant:
    print(child)

标签树的上行遍历

属性 说明
.parent 节点的父亲标签
.parents 节点先辈标签的迭代类型,用于循环遍历先辈节点

示例:

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
for parent in soup.a.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)

运行结果
【Python网络爬虫笔记】week02_第10张图片
遍历所有先辈节点,包括soup本身,所以要区别判断


标签树的平行遍历

属性 说明
.next_sibling 返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling 返回按照HTML文本顺序的上一个平行节点标签
.next_siblings 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
.previous_siblings 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签

【Python网络爬虫笔记】week02_第11张图片
标签树的平行遍历

#遍历后续节点
for sibling in soup.a.next_sibling:
    print(sibling)
#遍历前续节点
for sibling in soup.a.previous_sibling:
    print(sibling)

基于bs4库的HTML格式输出

bs4库的prettify()方法

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
print(soup.prettify())

输出结果
【Python网络爬虫笔记】week02_第12张图片
.prettify()为HTML文本<>及其内容增加’\n’
.prettufy()可用于标签,方法:.prettify()

标签使用prettify()实例

import requests
from bs4 import BeautifulSoup
r=requests.get("http://python123.io/ws/demo.html")
demo=r.text
soup=BeautifulSoup(demo, 'html.parser')
print(soup.a.prettify())

运行结果
在这里插入图片描述
bs4库的编码
bs4库将任何HTML输入都变成utf‐8编码
Python 3.x默认支持编码是utf‐8,解析无障碍

信息标记与提取

信息标记

HTML通过预定义的<>…标签形式组织不同类型的信息
信息标记的三种形式:XML、JSON、YAML
XML 最早的通用信息标记语言,可扩展性好,但繁琐
JSON 信息有类型,适合程序处理(js),较XML简洁
YAML 信息无类型,文本信息比例最高,可读性好
应用
XML Internet上的信息交互与传递
JSON 移动应用云端和节点的信息通信,无注释
YAML 各类系统的配置文件,有注释易读

信息提取

方法一
完整解析信息的标记形式,再提取关键信息
优点:信息解析准确
缺点:提取过程繁琐,速度慢

方法二
无视标记形式,直接搜索关键信息
优点:提取过程简洁,速度较快
缺点:提取结果准确性与信息内容相关

融合方法
融合方法:结合形式解析与搜索方法,提取关键信息

实例:提取HTML中所有的URL链接

import requests
from bs4 import BeautifulSoup
url="http://python123.io/ws/demo.html"
r=requests.get(url)
demo=r.text
soup=BeautifulSoup(demo, "html.parser")
for link in soup.find_all('a'):
    print(link.get("href"))

输出结果
在这里插入图片描述

基于bs4库的HTML内容查找方法

<>.find_all(name, attrs, recursive, string, **kwargs)
name:对标签名称的检索字符串
attrs:对标签属性值的检索字符串,可标注属性检索
recursive:是否对子孙全部检索,默认Ture
string: <>…中字符串区域的检索字符串

find all()函数使用
(…) 等价于 .find_all(…)
soup(…) 等价于 soup.find_all(…)

扩展方法

方法 说明
<>.find() 搜索且只返回一个结果,同.find_all()参数
<>.find_parents() 在先辈节点中搜索,返回列表类型,同.find_all()参数
<>.find_parent() 在先辈节点中返回一个结果,同.find()参数
<>.find_next_siblings() 在后续平行节点中搜索,返回列表类型,同.find_all()参数
>.find_next_sibling() 在后续平行节点中返回一个结果,同.find()参数
<>.find_previous_siblings() 在前序平行节点中搜索,返回列表类型,同.find_all()参数
<>.find_previous_sibling() 在前序平行节点中返回一个结果,同.find()参数

实例:中国大学排名爬虫

输入:大学排名URL链接
输出:大学排名信息的屏幕输出(排名,大学名称,总分)
定向爬虫可行性:http://www.zuihaodaxue.cn/robots.txt
【网页不存在】

步骤1:从网络上获取大学排名网页内容 getHTMLText()
步骤2:提取网页内容中信息到合适的数据结构 fillUnivList()
步骤3:利用数据结构展示并输出结果 printUnivList()

import requests
import bs4
from bs4 import BeautifulSoup

def getHTMLText(url):
    try:
        r=requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return ""

def fillUnivList(ulist, html):
    soup=BeautifulSoup(html, 'html.parser')
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds=tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[3].string])

def printUnivList(ulist, num):
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称", "总分"))
    for i in range(num):
        u=ulist[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0], u[1], u[2]))

def main():
    uinfo=[]
    url="http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html"
    html=getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20)
main()

输出结果
【Python网络爬虫笔记】week02_第13张图片
修改:中文输出对齐
修改输出函数

def printUnivList(ulist, num):
    tplt="{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称", "总分", chr(12288)))
    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0], u[1], u[2], chr(12288)))

输出结果
【Python网络爬虫笔记】week02_第14张图片

你可能感兴趣的:(python,基础,爬虫)