Heim  >  Artikel  >  Backend-Entwicklung  >  Installation und Einführung der Python BeautifulSoup-Bibliothek

Installation und Einführung der Python BeautifulSoup-Bibliothek

高洛峰
高洛峰Original
2017-03-11 09:49:022979Durchsuche

1. Einführung

In den vorherigen Artikeln habe ich vorgestellt, wie man Python-Quellcode analysiert Crawl-Blogs, Wikipedia-InfoBox und Bilder, der Artikellink lautet wie folgt:
[Python-Lernen] Einfaches Crawlen des Meldungsfelds der Wikipedia-Programmiersprache
[Python-Lernen] Einfacher Webcrawler zum Crawlen von Blogartikeln und Einführung von Ideen
[Python-Lernen] Einfaches Crawlen von Bildern in der Bilder-Website-Galerie
Der Kerncode lautet wie folgt:

# coding=utf-8
import urllib
import re

#下载静态HTML网页
url='http://www.csdn.net/'
content = urllib.urlopen(url).read()
open('csdn.html','w+').write(content)
#获取标题
title_pat=r&#39;(?<=<title>).*?(?=</title>)&#39;
title_ex=re.compile(title_pat,re.M|re.S)
title_obj=re.search(title_ex, content)
title=title_obj.group()
print title
#获取超链接内容 
href = r&#39;<a href=.*?>(.*?)</a>&#39;
m = re.findall(href,content,re.S|re.M)
for text in m:
    print unicode(text,&#39;utf-8&#39;)
    break #只输出一个url

Das Ausgabeergebnis lautet wie folgt:

>>>
CSDN.NET - 全球最大中文IT社区,为IT专业技术人员提供最全面的信息传播和服务平台
登录
>>>

Der Kerncode für das Herunterladen von Bildern lautet wie folgt:

import os
import urllib
class AppURLopener(urllib.FancyURLopener):
    version = "Mozilla/5.0"
urllib._urlopener = AppURLopener()
url = "http://creatim.allyes.com.cn/imedia/csdn/20150228/15_41_49_5B9C9E6A.jpg"
filename = os.path.basename(url)
urllib.urlretrieve(url , filename)

Aber die obige Methode der HTML-Analyse zum Crawlen von Website-Inhalten hat viele Nachteile, wie zum Beispiel:
1. Reguläre Ausdrücke sind durch den HTML-Quellcode eingeschränkt, nicht durch die abstraktere Struktur; kleine Änderungen in der Struktur der Webseite können dazu führen, dass das Programm abstürzt.
2. Das Programm muss den Inhalt basierend auf dem tatsächlichen HTML-Quellcode analysieren. Es kann auf HTML-Funktionen wie Zeichenentitäten wie & stoßen und eine Verarbeitung wie 45a2772a6b6107b401db3c9b82c049c254bdf357c58b8a65c66d7c19c8e4d114 , Symbol-Hyperlinks, Indizes usw. Unterschiedlicher Inhalt.
3. Reguläre Ausdrücke sind nicht vollständig lesbar und komplexere HTML-Codes und Abfrageausdrücke werden unübersichtlich.
Da „Python Basics Tutorial (2. Auflage)“ zwei Lösungen annimmt: Die erste besteht darin, das Tidy-Programm (Python-Bibliothek) und die XHTML-Analyse zu verwenden; die zweite ist um die BeautifulSoup-Bibliothek zu verwenden.


2. Installation und Einführung Beautiful Soup-Bibliothek


Beautiful Soup ist ein in Python geschriebener HTML/XML-Parser, der das kann Behandeln Sie unregelmäßiges Markup gut und generieren Sie einen Parse-Baum. Es bietet einfache und häufig verwendete Vorgänge zum Navigieren, Suchen und Ändern von Analysebäumen. Es kann Ihre Programmierzeit erheblich sparen.
Wie es im Buch heißt: „Du hast diese schlechten Webseiten nicht geschrieben, du hast nur versucht, ein paar Daten daraus zu bekommen. Jetzt ist es dir egal.“ Wie der HTML-Code aussieht, hilft Ihnen der Parser dabei.
 
Download-Adresse:
 http://www .php.cn/
                                                                                                    setup.py install

Es wird empfohlen, sich für bestimmte Verwendungsmethoden auf Chinesisch zu beziehen: http://www.php.cn/
Darunter die Verwendung von BeautifulSoup wird am offiziellen Beispiel von „Alice im Wunderland“ kurz erklärt:



Inhalt ausgeben
#!/usr/bin/python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse&#39;s story</title></head>
<body>
<p class="title"><b>The Dormouse&#39;s story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""

#获取BeautifulSoup对象并按标准缩进格式输出
soup = BeautifulSoup(html_doc)
print(soup.prettify())
Ausgabe gemäß der Standardstruktur des Einrückungsformats

Wie folgt: Folgendes ist eine einfache und schnelle Einführung in die BeautifulSoup-Bibliothek: (Referenz: Offizielle Dokumentation)

<html>
 <head>
  <title>
   The Dormouse&#39;s story
  </title>
 </head>
 <body>
  <p class="title">
   <b>
    The Dormouse&#39;s story
   </b>
  </p>
  <p class="story">
   Once upon a time there were three little sisters; and their names were
   <a class="sister" href="http://example.com/elsie" id="link1">
    Elsie
   </a>
   ,
   <a class="sister" href="http://example.com/lacie" id="link2">
    Lacie
   </a>
   and
   <a class="sister" href="http://example.com/tillie" id="link3">
    Tillie
   </a>
   ;
and they lived at the bottom of a well.
  </p>
  <p class="story">
   ...
  </p>
 </body>
</html>


Wenn Sie den gesamten Textinhalt erhalten möchten Im Artikel lautet der Code wie folgt:

&#39;&#39;&#39;获取title值&#39;&#39;&#39;
print soup.title
# <title>The Dormouse&#39;s story</title>
print soup.title.name
# title
print unicode(soup.title.string)
# The Dormouse&#39;s story

&#39;&#39;&#39;获取<p>值&#39;&#39;&#39;
print soup.p
# <p class="title"><b>The Dormouse&#39;s story</b></p>
print soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

&#39;&#39;&#39;从文档中找到<a>的所有标签链接&#39;&#39;&#39;
print soup.find_all(&#39;a&#39;)
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
for link in soup.find_all(&#39;a&#39;):
    print(link.get(&#39;href&#39;))
    # http://www.php.cn/
    # http://www.php.cn/
    # http://www.php.cn/
print soup.find(id=&#39;link3&#39;)
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>

&#39;&#39;&#39;从文档中获取所有文字内容&#39;&#39;&#39;
print soup.get_text()
# The Dormouse&#39;s story
#
# The Dormouse&#39;s story
#
# Once upon a time there were three little sisters; and their names were
# Elsie,
# Lacie and
# Tillie;
# and they lived at the bottom of a well.
#
# ...

        同时在这过程中你可能会遇到两个典型的错误提示:
        1.ImportError: No module named BeautifulSoup
        当你成功安装BeautifulSoup 4库后,“from BeautifulSoup import BeautifulSoup”可能会遇到该错误。


        其中的原因是BeautifulSoup 4库改名为bs4,需要使用“from bs4 import BeautifulSoup”导入。
        2.TypeError: an integer is required
        当你使用“print soup.title.string”获取title的值时,可能会遇到该错误。如下:


        它应该是IDLE的BUG,当使用命令行Command没有任何错误。参考:stackoverflow。同时可以通过下面的代码解决该问题:
        print unicode(soup.title.string)
        print str(soup.title.string)


三. Beautiful Soup常用方法介绍


       
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:Tag、NavigableString、BeautifulSoup、Comment|
        1.Tag标签
        tag对象与XML或HTML文档中的tag相同,它有很多方法和属性。其中最重要的属性name和attribute。用法如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup

html = """
<html><head><title>The Dormouse&#39;s story</title></head>
<body>
<p class="title" id="start"><b>The Dormouse&#39;s story</b></p>
"""
soup = BeautifulSoup(html)
tag = soup.p
print tag
# <p class="title" id="start"><b>The Dormouse&#39;s story</b></p>
print type(tag)
# <class &#39;bs4.element.Tag&#39;>
print tag.name
# p 标签名字
print tag[&#39;class&#39;]
# [u&#39;title&#39;]
print tag.attrs
# {u&#39;class&#39;: [u&#39;title&#39;], u&#39;id&#39;: u&#39;start&#39;}

        使用BeautifulSoup每个tag都有自己的名字,可以通过.name来获取;同样一个tag可能有很多个属性,属性的操作方法与字典相同,可以直接通过“.attrs”获取属性。至于修改、删除操作请参考文档。
        2.NavigableString
        字符串常被包含在tag内,Beautiful Soup用NavigableString类来包装tag中的字符串。一个NavigableString字符串与Python中的Unicode字符串相同,并且还支持包含在遍历文档树搜索文档树中的一些特性,通过unicode()方法可以直接将NavigableString对象转换成Unicode字符串。

print unicode(tag.string)
# The Dormouse&#39;s story
print type(tag.string)
# <class &#39;bs4.element.NavigableString&#39;>
tag.string.replace_with("No longer bold")
print tag
# <p class="title" id="start"><b>No longer bold</b></p>

        这是获取“6924be786dcb0892a956090fd509f9a5a4b561c25d9afb9ac8dc4d70affff419The Dormouse's story0d36329ec37a2cc24d42c7229b69747a94b3e26ee717c64999d7867364b1b4a3”中tag = soup.p的值,其中tag中包含的字符串不能编辑,但可通过函数replace_with()替换。
        NavigableString 对象支持遍历文档树和搜索文档树 中定义的大部分属性, 并非全部。尤其是一个字符串不能包含其它内容(tag能够包含字符串或是其它tag),字符串不支持 .contents 或 .string 属性或 find() 方法。
        如果想在Beautiful Soup之外使用 NavigableString 对象,需要调用 unicode() 方法,将该对象转换成普通的Unicode字符串,否则就算Beautiful Soup已方法已经执行结束,该对象的输出也会带有对象的引用地址。这样会浪费内存。

        3.Beautiful Soup对象
        该对象表示的是一个文档的全部内容,大部分时候可以把它当做Tag对象,它支持遍历文档树和搜索文档树中的大部分方法。
        注意:因为BeautifulSoup对象并不是真正的HTML或XML的tag,所以它没有name和 attribute属性,但有时查看它的.name属性可以通过BeautifulSoup对象包含的一个值为[document]的特殊实行.name实现——soup.name。
        Beautiful Soup中定义的其它类型都可能会出现在XML的文档中:CData , ProcessingInstruction , Declaration , Doctype 。与 Comment 对象类似,这些类都是 NavigableString 的子类,只是添加了一些额外的方法的字符串独享。
        4.Command注释
        Tag、NavigableString、BeautifulSoup几乎覆盖了html和xml中的所有内容,但是还有些特殊对象容易让人担心——注释。Comment对象是一个特殊类型的NavigableString对象。

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
print type(comment)
# <class &#39;bs4.element.Comment&#39;>
print unicode(comment)
# Hey, buddy. Want to buy a used parser?

        介绍完这四个对象后,下面简单介绍遍历文档树和搜索文档树及常用的函数。
        5.遍历文档树
        一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点。BeautifulSoup提供了许多操作和遍历子节点的属性。引用官方文档中爱丽丝例子:
        操作文档最简单的方法是告诉你想获取tag的name,如下:

soup.head# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1soup.title# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2fsoup.body.b# a4b561c25d9afb9ac8dc4d70affff419The Dormouse's story0d36329ec37a2cc24d42c7229b69747a

        注意:通过点取属性的放是只能获得当前名字的第一个Tag,同时可以在文档树的tag中多次调用该方法如soup.body.b获取6c04bd5ca3fcae76e30b72ad730ca86d标签中第一个a4b561c25d9afb9ac8dc4d70affff419标签。
        如果想得到所有的3499910bf9dac5ae3c52d5ede7383485标签,使用方法find_all(),在前面的Python爬取维基百科等HTML中我们经常用到它+正则表达式的方法。

soup.find_all('a')# [31602ad08f2e88060105421a6fd98432Elsie5db79b134e9f6b82c0b36e0489ee08ed,#  7a2353bc01007f1e0b12a80523342380Lacie5db79b134e9f6b82c0b36e0489ee08ed,#  de05147b7e6ab3a313271cf7987ced2eTillie5db79b134e9f6b82c0b36e0489ee08ed]

        子节点:在分析HTML过程中通常需要分析tag的子节点,而tag的 .contents 属性可以将tag的子节点以列表的方式输出。字符串没有.contents属性,因为字符串没有子节点。

head_tag = soup.head
head_tag
# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1

head_tag.contents
[b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f]

title_tag = head_tag.contents[0]
title_tag
# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f
title_tag.contents
# [u'The Dormouse's story']

        通过tag的 .children 生成器,可以对tag的子节点进行循环:

for child in title_tag.children:
    print(child)
    # The Dormouse's story

        子孙节点:同样 .descendants 属性可以对所有tag的子孙节点进行递归循环:

for child in head_tag.descendants:
    print(child)
    # b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f
    # The Dormouse's story

        父节点:通过 .parent 属性来获取某个元素的父节点.在例子“爱丽丝”的文档中,93f0f5c25f18dab9d176bd4f6de5d30e标签是b2386ffb911b14667cb8f0f91ea547a7标签的父节点,换句话就是增加一层标签。
        注意:文档的顶层节点比如100db36a723c770d327fc0aef2ce13b1的父节点是 BeautifulSoup 对象,BeautifulSoup 对象的 .parent 是None。

title_tag = soup.titletitle_tag# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2ftitle_tag.parent# 93f0f5c25f18dab9d176bd4f6de5d30eb2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f9c3bca370b5104690d9ef395f2c5f8d1title_tag.string.parent# b2386ffb911b14667cb8f0f91ea547a7The Dormouse's story6e916e0f7d1e588d4f442bf645aedb2f

        兄弟节点:因为a4b561c25d9afb9ac8dc4d70affff419标签和f8331b8a817c28418a431fbe6e724755标签是同一层:他们是同一个元素的子节点,所以a4b561c25d9afb9ac8dc4d70affff419和f8331b8a817c28418a431fbe6e724755可以被称为兄弟节点。一段文档以标准格式输出时,兄弟节点有相同的缩进级别.在代码中也可以使用这种关系。

sibling_soup = BeautifulSoup("3499910bf9dac5ae3c52d5ede7383485a4b561c25d9afb9ac8dc4d70affff419text10d36329ec37a2cc24d42c7229b69747af8331b8a817c28418a431fbe6e724755text29058c75f7b5bb1e6daacddf9bb18d9590d36329ec37a2cc24d42c7229b69747a5db79b134e9f6b82c0b36e0489ee08ed")print(sibling_soup.prettify())# 100db36a723c770d327fc0aef2ce13b1#  6c04bd5ca3fcae76e30b72ad730ca86d#   3499910bf9dac5ae3c52d5ede7383485#    a4b561c25d9afb9ac8dc4d70affff419#     text1#    0d36329ec37a2cc24d42c7229b69747a#    f8331b8a817c28418a431fbe6e724755#     text2#    9058c75f7b5bb1e6daacddf9bb18d959#   5db79b134e9f6b82c0b36e0489ee08ed#  36cc49f0c466276486e50c850b7e4956# 73a6ac4ed44ffec12cee46588e518a5e

        在文档树中,使用 .next_sibling 和 .previous_sibling 属性来查询兄弟节点。a4b561c25d9afb9ac8dc4d70affff419标签有.next_sibling 属性,但是没有.previous_sibling 属性,因为a4b561c25d9afb9ac8dc4d70affff419标签在同级节点中是第一个。同理f8331b8a817c28418a431fbe6e724755标签有.previous_sibling 属性,却没有.next_sibling 属性:

sibling_soup.b.next_sibling# f8331b8a817c28418a431fbe6e724755text29058c75f7b5bb1e6daacddf9bb18d959sibling_soup.c.previous_sibling# a4b561c25d9afb9ac8dc4d70affff419text10d36329ec37a2cc24d42c7229b69747a

        介绍到这里基本就可以实现我们的BeautifulSoup库爬取网页内容,而网页修改、删除等内容建议大家阅读文档。下一篇文章就再次爬取维基百科的程序语言的内容吧!希望文章对大家有所帮助,如果有错误或不足之处,还请海涵!建议大家阅读官方文档和《Python基础教程》书。
        (By:Eastmount 2015-3-25 下午6点  http://www.php.cn/)



Das obige ist der detaillierte Inhalt vonInstallation und Einführung der Python BeautifulSoup-Bibliothek. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn