BeautifulSoup主要介绍与基础爬虫项目实践

强大的BeautifulSoup

1.简要介绍

BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。

2.Beautiful Soup的安装
方法1: pip install bs4
方法2:在Pycharm中,可以在File -> Settings -> Project Interpreter -> 右侧有个加号按钮 -> 在弹出的窗口搜索bs4并安装。

3.BeautifulSoup的使用
[0].bs4库的导入
from bs4 import BeautifulSoup
[1].创建BeautifulSoup对象
以下'lxml'是手动指定的解析器。如果省略,BeautifulSoup一般会选择最合适的解析器来解析这段文档,如果手动指定,那么BeautifulSoup会选择指定的解析器来解析文档。
方式1. 直接通过字符串创建
soup = BeautifulSoup(html_str, 'lxml', from_encoding = 'utf-8')

    Example:
    from bs4 import BeautifulSoup
    import requests
    import chardet

    url = 'http://www.baidu.com'
    response = requests.get(url)
    response.encoding = chardet.detect(response.content)['encoding']
    text = response.text

    soup = BeautifulSoup(text, 'lxml')
    print(soup.prettify())
方式2. 通过html文件来创建
    from bs4 import BeautifulSoup
    import requests
    import chardet


    url = 'http://www.baidu.com'
    response = requests.get(url)
    response.encoding = chardet.detect(response.content)['encoding']
    text = response.text

    with open('hell', 'w') as fout:
        fout.write(text)

    soup = BeautifulSoup(open('hell'), 'lxml')
    print(soup.prettify())
[2].对象种类
BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
a. Tag
b. NavigableString
c. BeautifulSoup
d. Comment

1). Tag
Tag对象与XML或HTML原生文档中的Tag相同,通俗点说就是标记。标记及其里面的内容称为Tag对象。
import requests
import chardet

url = 'http://www.baidu.com'
response = requests.get(url)
response.encoding = chardet.detect(response.content)['encoding']
text = response.text

with open('hell', 'w') as fout:
    fout.write(text)

soup = BeautifulSoup(open('hell'), 'lxml')
# print(soup.prettify())
print(soup.title)
print(soup.a)

Result:
<title>百度一下,你就知道</title>
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>

从栗子中可以看出,利用soup加标记名就可以很容易这些标记的内容,比之前讲的正则表达式简单多了。不过利用这种方式,查找的时所有内容中第一个符合要求的标记。

Tag中有两个最重要的属性:name和atrributes。
.name
每个Tag都有自己的名字,通过.name来获取
print( soup.name )
print( soup.title.name )

Result:
[document]
title
soup对象本身比较特殊,它的name为[document],对于其他内部标记,输出的值便是标记本身的名称。
Tag不仅可以获取name,还可以修改name,改变之后将影响所有通过当前BeautifulSoup对象生成的HTML文档。
soup.title.name = 'mytitle'
print( soup.title )
print( soup.mytitle )

Result:
None
<mytitle>百度一下,你就知道</mytitle>

属性:
Tag的属性的操作方法与字典相同,直接获取; 也可以直接‘点’取属性,.attrs,用于获取Tag中的所有属性。
print( soup.a['href'] )
print( soup.a.attrs['href'] )


2).NavigableString
我们已经得到了标记的内容,要想获取标记内部的文字怎么办呢?需要用到.string
Example:
print( soup.title.string )
print( type(soup.title.string) )

Result:
百度一下,你就知道
<class 'bs4.element.NavigableString'>

注:BeautifulSoup用NavigableString类来包装Tag中的字符串,一个Navigable字符串与Python中的Unicode字符串相同。

3).BeautifulSoup对象表示的是一个文档的全部内容。大部分时候,可以把它当作Tag对象,是一个特殊的Tag对象,因为BeautifulSoup对象并不是真正的HTML或XML的标记,所以它没有name和attribute属性。但为了将BeautifulSoup对象标准化为Tag对象,实现接口的统一,我们依然可以分别获取它的name和attribute属性。

4).Comment
Tag, NavigableString, BeautifulSoup几乎覆盖了HTML和XML中的所有内容,但是还是有些特殊对象。容易让人担心的内容是文档的注释部分:如果不清楚这个标记.string的情况下,可能会造成数据提取混乱。

[3].遍历文档树
×××重中之重
[4].搜索文档树
BeautifulSoup定义了很多搜索方法,这里着重介绍find_all()方法,其他方法的参数和用法类似,请大家举一反三。
find_all方法,用于搜索当前Tag的所有Tag子节点,并判断是否符合过滤器的条件,函数原型如下:
find_all(name, attrs, recursive, text, **kwargs)
1).name参数
name参数可以查找所有名字为name的标记,字符串对象会被自动忽略掉。name参数值可以是字符串,正则表达式,列表,True和方法。
字符串:print( soup.find_all('a') )
正则表达式:print( soup.find_all(re.compile('^b')) )
列表:print( soup.find_all(['a', 'b']) )
True: print( soup.find_all(True) )
2).kwargs参数
kwargs参数在Python里表示为keyword参数。如果一个指定名字的参数不是搜索内置的参数名

[5].CSS选择器
我们也可以利用CSS选择器来筛选元素,在写CSS时,标记名前不加任何修饰,类名前加‘.’, id前加‘#’。用到的方法是soup.select(),返回类型时list。
1).通过标记名称进行查找
# 直接查找title标记
print( soup.select('title') )

# 逐层查找title标记
print( soup.select('html head title') )

# 查找直接子节点
# 查找head下的title标记
print( soup.select('head > title') )
# 查找p下的id="link1"的标记
print( soup.select('p > #link1') )

#查找兄弟节点
#查找id='link1'之后class=sister的所有兄弟标记
print( soup.select('#link1 ~ .sister') )
#查找紧跟id = 'link1' 之后class=sister的子标记
print( soup.select('#link1 + .sister') )

2).通过CSS的类名查找
print( soup.select('.sister') )
print( soup.select('[class~=sister]') )

3).通过tag的id查找
print( soup.select('#link1') )
print( soup.select('a#link2') )

4).通过是否存在某个属性来查找
print( soup.select('a[href]') )

5).通过属性值来查找
Tag[attribute]        用于选取带有指定属性的元素
Tag[attribute=value]    用于选取带有指定属性和值的元素
Tag[attribute~=value]    用于选取属性值中包含指定词汇的元素
Tag[attribute|=value]    用于选取带有以指定值开头的属性值的元素,该值必须是整个单词
Tag[attribute^=value]    匹配属性值以指定值开头的每个元素
Tag[attribute$=value]    匹配属性值以指定值结尾的每个元素
Tag[attribute*=value]    匹配属性值中包含指定值的每个元素    

基础爬虫项目:爬取百度百科100词条

猜你喜欢

转载自blog.csdn.net/qq_37597345/article/details/83781420