开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python BeautifulSoup

PythonBeautifulSoup教程是BeautifulSoupPython库的入门教程。示例包括查找标签、遍历文档树、修改文档和抓取网页。

美丽汤

BeautifulSoup是一个用于解析HTML和XML文档的Python库。它通常用于网页抓取。BeautifulSoup将复杂的HTML文档转换为复杂的Python对象树,例如标签、可导航字符串或注释。

安装BeautifulSoup

我们使用pip3命令来安装必要的模块。

$ sudo pip3 install lxml

我们需要安装BeautifulSoup使用的lxml模块。

$ sudo pip3 install bs4

BeautifulSoup使用上述命令安装。

HTML文件

在示例中,我们将使用以下HTML文件:

<!DOCTYPE html>
<html>
    <head>
        <title>Header</title>
        <meta charset="utf-8">
    </head>

    <body>
        <h2>Operating systems</h2>

        <ul id="mylist" style="width:150px">
            <li>Solaris</li>
            <li>FreeBSD</li>
            <li>Debian</li>
            <li>NetBSD</li>
            <li>Windows</li>
        </ul>

        <p>
          FreeBSD is an advanced computer operating system used to
          power modern servers, desktops, and embedded platforms.
        </p>

        <p>
          Debian is a Unix-like computer operating system that is
          composed entirely of free software.
        </p>

    </body>
</html>

简单的PythonBeautifulSoup示例

在第一个示例中,我们使用BeautifulSoup模块获取三个标签。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.h2)
    print(soup.head)
    print(soup.li)

代码示例打印三个标签的HTML代码。

from bs4 import BeautifulSoup

我们从bs4模块导入BeautifulSoup类。BeautifulSoup是执行工作的主要类。

with open('index.html', 'r') as f:

    contents = f.read()

我们打开index.html文件并使用read方法读取它的内容。

soup = BeautifulSoup(contents, 'lxml')

BeautifulSoup对象被创建;HTML数据被传递给构造函数。第二个选项指定解析器。

print(soup.h2)
print(soup.head)

这里我们打印了两个标签的HTML代码:h2head

print(soup.li)

有多个li元素;该行打印第一个。

$ ./simple.py
<h2>Operating systems</h2>
<head>
<title>Header</title>
<meta charset="utf-8"/>
</head>
<li>Solaris</li>

BeautifulSoup标签、名称、文本

标签的name属性给出了它的名字,text属性给出了它的文本内容。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(f'HTML: {soup.h2}, name: {soup.h2.name}, text: {soup.h2.text}')

代码示例打印h2标签的HTML代码、名称和文本。

$ ./tags_names.py
HTML: <h2>Operating systems</h2>, name: h2, text: Operating systems

BeautifulSoup遍历标签

使用recursiveChildGenerator方法我们遍历HTML文档。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for child in soup.recursiveChildGenerator():

        if child.name:

            print(child.name)

该示例遍历文档树并打印所有HTML标记的名称。

$ ./traverse_tree.py
html
head
title
meta
body
h2
ul
li
li
li
li
li
p
p

在HTML文档中我们有这些标签。

BeautifulSoup子元素

通过children属性,我们可以获得标签的子元素。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.html

    root_childs = [e.name for e in root.children if e.name is not None]
    print(root_childs)

该示例检索html标记的子项,将它们放入Python列表并将它们打印到控制台。由于children属性还会返回标签之间的空格,因此我们添加了一个条件以仅包含标签名称。

$ ./get_children.py
['head', 'body']

html标签有两个子标签:headbody

BeautifulSoup元素后代

通过descendants属性,我们可以获得标签的所有后代(所有级别的子代)。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.body

    root_childs = [e.name for e in root.descendants if e.name is not None]
    print(root_childs)

该示例检索body标记的所有后代。

$ ./get_descendants.py
['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p']

这些都是body标签的后代。

BeautifulSoup网页抓取

Requests是一个简单的PythonHTTP库。它提供了通过HTTP访问Web资源的方法。

#!/usr/bin/python

from bs4 import BeautifulSoup
import requests as req

resp = req.get('http://webcode.me')

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.title)
print(soup.title.text)
print(soup.title.parent)

该示例检索一个简单网页的标题。它还打印其父项。

resp = req.get('http://webcode.me')

soup = BeautifulSoup(resp.text, 'lxml')

我们获取页面的HTML数据。

print(soup.title)
print(soup.title.text)
print(soup.title.parent)

我们检索标题的HTML代码、其文本及其父项的HTML代码。

$ ./scraping.py 
<title>My html page</title>
My html page
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>My html page</title>
</head>

BeautifulSoup美化代码

通过prettify方法,我们可以使HTML代码看起来更好。

#!/usr/bin/python

from bs4 import BeautifulSoup
import requests as req

resp = req.get('http://webcode.me')

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.prettify())

我们美化了一个简单网页的HTML代码。

$ ./prettify.py 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
    <title>
      My html page
    </title>
  </head>
  <body>
    <p>
      Today is a beautiful day. We go swimming and fishing.
    </p>
    <p>
      Hello there. How are you?
    </p>
  </body>
</html>

内置网络服务器的BeautifulSoup抓取

我们还可以使用简单的内置HTTP服务器提供HTML页面。

$ mkdir public
$ cp index.html public/

我们创建一个public目录,并将index.html复制到那里。

$ python -m http.server --directory public
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

然后我们启动PythonHTTP服务器。

#!/usr/bin/python

from bs4 import BeautifulSoup
import requests as req

resp = req.get('http://localhost:8000/')

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.title)
print(soup.body)

现在我们从本地运行的服务器获取文档。

BeautifulSoup通过Id查找元素

使用find方法,我们可以通过各种方式查找元素,包括元素id。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    #print(soup.find('ul', attrs={ 'id' : 'mylist'}))
    print(soup.find('ul', id='mylist'))

代码示例找到具有mylistid的ul标记。注释行具有执行相同任务的另一种方法。

BeautifulSoup查找所有标签

使用find_all方法,我们可以找到满足某些条件的所有元素。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for tag in soup.find_all('li'):
        print(f'{tag.name}: {tag.text}')

代码示例查找并打印所有li标签。

$ ./find_all.py 
li: Solaris
li: FreeBSD
li: Debian
li: NetBSD
li: Windows

find_all方法可以获取要搜索的元素列表。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(['h2', 'p'])

    for tag in tags:
        print(' '.join(tag.text.split()))

该示例找到所有h2p元素并打印它们的文本。

find_all方法也可以采用一个函数来确定应返回哪些元素。

#!/usr/bin/python

from bs4 import BeautifulSoup

def myfun(tag):

    return tag.is_empty_element


with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(myfun)
    print(tags)

该示例打印空元素。

$ ./find_by_fun.py
[<meta charset="utf-8"/>]

文档中唯一的空元素是meta

也可以使用正则表达式查找元素。

#!/usr/bin/python

import re

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    strings = soup.find_all(string=re.compile('BSD'))

    for txt in strings:

        print(' '.join(txt.split()))

该示例打印包含“BSD”字符串的元素的内容。

$ ./regex.py
FreeBSD
NetBSD
FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms.

BeautifulSoupCSS选择器

通过selectselect_one方法,我们可以使用一些CSS选择器来查找元素。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select('li:nth-of-type(3)'))

此示例使用CSS选择器打印第三个li元素的HTML代码。

$ ./select_nth_tag.py
<li>Debian</li>

这是第三个li元素。

#字符在CSS中用于根据标签的id属性选择标签。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select_one('#mylist'))

该示例打印具有mylistid的元素。

BeautifulSoup追加元素

append方法将一个新标签附加到HTML文档。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')
    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.append(newtag)

    print(ultag.prettify())

该示例附加了一个新的li标记。

newtag = soup.new_tag('li')
newtag.string='OpenBSD'

首先,我们使用new_tag方法创建一个新标签。

ultag = soup.ul

我们得到了对ul标签的引用。

ultag.append(newtag)

我们将新创建的标签附加到ul标签。

print(ultag.prettify())

我们以整洁的格式打印ul标签。

BeautifulSoup插入元素

insert方法在指定位置插入一个标签。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')
    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.insert(2, newtag)

    print(ultag.prettify())

该示例在ul标记的第三个位置插入一个li标记。

BeautifulSoup替换文本

replace_with替换元素的文本。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tag = soup.find(text='Windows')
    tag.replace_with('OpenBSD')

    print(soup.ul.prettify())

该示例使用find方法查找特定元素,并使用replace_with方法替换其内容。

BeautifulSoup删除元素

decompose方法从树中删除一个标签并将其销毁。

#!/usr/bin/python

from bs4 import BeautifulSoup

with open('index.html', 'r') as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    ptag2 = soup.select_one('p:nth-of-type(2)')

    ptag2.decompose()

    print(soup.body.prettify())

该示例删除了第二个p元素。

在本教程中,我们使用了PythonBeautifulSoup库。

阅读Python教程或列出所有Python教程。

未经允许不得转载:我爱分享网 » Python BeautifulSoup

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏