BeautifulSoup

是一个非常优秀的Python扩展库,可以用来从HTML或XML文件中提取我们感兴趣的数据,并且允许指定使用不同的解析器。

一、安装BeautifulSoup

1.1 mac安装bs4

完成安装python3后,直接在命令行使用pip3或者easy_install来安装

1.pip3安装

pip3 install beautifulsoup4

2.easy_install安装

easy_install beautifulsoup4

1.2 win下安装bs4

需要先下载bs4安装包到本地python目录,再执行命令

借鉴网上方法

    python3.4.3 对BeautifulSoup的支持不太好,大多网上都是python2.7 的安装教程,而按那个真是颇费周折。最后,在[https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/](https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/) 找到了解决方案

     1.下载
        [https://www.crummy.com/software/BeautifulSoup/bs4/download/ ](https://www.crummy.com/software/BeautifulSoup/bs4/download/)
     2.解压至D:python34   即python安装目录
     3.打开cmd,进入D:python34beautifulsoup4-4.4.1  ,这是我的安装路径,这里面有setup.py  文件
     4.cmd中输入 ```Python setup.py install```
     如果行不通,Beautiful Soup的发布协议允许你将BS4的代码打包在你的项目中,这样无须安装即可使用.
     5.测试是否安装好
         5.1输入python,进入python模块
         5.2输入from bs4 import BeautifulSoup检测是否成功。
      另附BeautifulSoup中文文档链接,接下来好好享受爬虫旅程。[https://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#Quick%20Start](https://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#Quick%20Start)


根据方法执行

1.下载和安装

下载bs4包后,解压至本地python目录

备注:cmd中可通过where python获得本地python路径

2.使用Python setup.py install安装

使用Python setup.py install安装报错,是因为进入当下路径文件夹后,无steup.py文件可供安装。调整1和2步骤,下载最新bs4包4.6版本,进入steup.py文件夹中

下载bs4包后,解压至本地python目录.png

执行命令python setup.py install,正常进入安装流程

安装bs4_1.png

安装bs4_2.png

3.进入python,使用from bs4 import BeautifulSoup查看是否正常

from bs4 import BeautifulSoup_报错.png

查找上述报错解决方法,因为使用python3.6版本,需更换库,把python2的库升级为python3的库
具体:将bs4文件夹和2to3.py同时放到lib中,然后在cmd中定位到lib,运行:2to3.py bs4 -w就好了

2to3.py bs4 -w.png

之后运行报错,操作异常,确认后发现,将bs4文件夹放入lib文件夹中执行错误

–1.beautifulSoup4解压目录中的bs4文件夹C:UsersxxAppDataLocalProgramsPythonPython36beautifulsoup4-4.6.0beautifulsoup4-4.6.0bs4
–2. 2to3.pyC:UsersxxAppDataLocalProgramsPythonPython36Toolsscripts
都复制到python的安装目录下的LibC:UsersxxAppDataLocalProgramsPythonPython36Lib文件夹下
进入D:Python37-32Lib 目录,并执行2to3.py bs4 -w命令

bs4安装包下bs4文件夹.png
2to3.py文件.png

进入python,使用from bs4 import BeautifulSoup查看是否正常

完成安装,并可正常使用bs4.png

二、BeautifulSoup语法

1.学习基本够用的即可
2.学习2,已完成
3.学习3,待学习搜索文档树、find_all
4.学习4,好的实践

2.1. BeautifulSoup类的基本元素

Tag
Tag 对象与 XML 或 HTML 原生文档中的 tag 相同,表示标签,是最基本的信息组织单元,分别用和>开头和结尾

.name : Name 表示标签的名字
.attrs: Attributes 表示标签的属性,返回字典形式组织,
.string : NavigableString 表示标签内非属性字符串
.string: Comment 表示标签内的注释部分

1.tag实例
如上之前已经学过,soup.标签a/p,代表遍历到第一个a标签或者p标签

>>> tag1 = soup.a
>>> print(tag1)
Elsie
>>> tag2 = soup.p
>>> print(tag2)

The Dormouse's story

2.Name实例
类似:当我们通过soup.title.name的时候就可以获得该title标签的名称,即
括号中的title</p> <pre><code>>>> tag1.name 'a' >>> tag2.name 'p' </code></pre> <p>3.Attributes 实例</p> <pre><code> >>> tag1.attrs {'href': 'http://example.com/elsie', 'class': ['sister'], 'id': 'link1'} #在这里,我们把 tag1即a标签的所有属性打印输出了出来,得到的类型是一个字典。 >>> tag2.attrs {'class': ['title']} </code></pre> <p>如果我们想要单独获取某个属性,可以这样,例如我们获取它的 class 叫什么</p> <pre><code>>>> tag2.attrs.get('class') ['title'] </code></pre> <p>我们也可以通过这个attrs去更加详细地过滤标签–find_all<br /> 如果想要通过名字得到比一个 tag 更多的内容的时候就需要用 Searching the tree 中描述的方法, 比如 : find_all()</p> <pre><code>>>> soup.find_all('p') [<p class="title"><b>The Dormouse's story</b></p>, <p class="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.</p>, <p class="story">...</p>] </code></pre> <p>4.NavigableString<br /> NavigableString按照字面意义上理解为可遍历字符串,<br /> 是BeautifulSoup对象四种类型<code>tag|NavigableString|BeautifulSoap|Comment</code>中的一种</p> <pre><code>>>> tag1.string 'Elsie' # tag1即a标签的内容 # >>> type(tag1.string) # 知道是一种类型,写明对象类型 NavigableString # >>> tag2.string "The Dormouse's story" >>> type(tag2.string) </code></pre> <p>5.Comment 实例 (与 NavigableString 的区别)<br /> Comment 对象是一个特殊类型的 NavigableString 对象??还是不太懂</p> <h3>2.2 学习属性和打印语句</h3> <h3>2.2.1 学习属性</h3> <h4>1.标签选择器</h4> <p>在快速使用中我们添加如下代码</p> <pre><code>print(soup.title) print(type(soup.title)) print(soup.head) print(soup.p) </code></pre> <p>作用:通过这种soup.标签名 我们就可以获得这个标签的内容<br /> 备注:这里有个问题需要注意,通过这种方式获取标签,如果文档中有<strong>多个</strong>这样的标签,返回的结果是<strong>第一个标签的内容</strong>,如上面我们通过soup.p获取p标签,而文档中有多个p标签,但是只返回了第一个p标签内容,见2.1.2 打印语句6.属性print(soup.p)打印结果</p> <h4>2.获取名称</h4> <p>当我们通过soup.title.name的时候就可以获得该title标签的名称,即title<br /> <code>print(soup.title.name)</code></p> <h4>3.获取属性</h4> <pre><code>print(soup.p.attrs['name']) print(soup.p['name']) </code></pre> <h4>4.获取内容</h4> <pre><code>print(soup.p.string) </code></pre> <p>结果就可以获取第一个p标签的内容:</p> <pre><code>The Dormouse's story </code></pre> <h4>5.嵌套选择</h4> <p>见下方 5.属性<code>print(soup.title.parent.name)</code>打印结果<br /> 嵌套有 父子节点的概念,通过子.parent=父状态,来嵌套获得父的信息</p> <h4>6.标准选择器</h4> <p>find_all:可以根据标签名,属性,内容查找文档<br /> find_all() 方法搜索当前 tag 的所有 tag 子节点, 并判断是否符合过滤器的条件??</p> <p>待学习find_all示例</p> <pre><code>find_all(name,attrs,recursive,text,**kwargs) </code></pre> <p>其余属性目前未涉及,暂时未关注,可继续回溯‘https://www.cnblogs.com/zhaof/p/6930955.html’</p> <h3>2.2.2 打印语句</h3> <pre><code>#-*- coding:utf-8 -*- from bs4 import BeautifulSoup html_doc = """ <title>The Dormouse's story

The Dormouse'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.

...

""" soup = BeautifulSoup(html_doc, 'html5lib') print(soup.prettify()) print(soup.title) print(soup.title.name) print(soup.title.string) print(soup.title.parent.name) print(soup.p) print(soup.p["class"]) print(soup.a) print(soup.find_all('a')) print(soup.find(id='link3'))
  1. 属性print(soup.prettify())打印结果
    prettify()函数,实现格式化输出:把代码格式给搞的标准一些,符合html代码格式(从.py文件中发现,相关html格式并不规范),使用prettify规范格式,更清楚
C:Userssylvia.liPycharmProjectsuntitledvenvScriptspython.exe F:/01_python/01_testsamples/bs4_04.py

 
  
   The Dormouse's story
  
 
 
  

The Dormouse'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.

...

Process finished with exit code 0

2.属性print(soup.title)打印结果
head标签中的起始于
完结于的内容

The Dormouse's story

属性print(soup.head)打印结果
html中起始于

完结于的内容

The Dormouse's story

3.属性print(soup.title.name)打印结果
当我们通过soup.title.name的时候就可以获得该title标签的名称,即
括号中的title</p> <pre><code>title </code></pre> <p>4.属性<code>print(soup.title.string)</code>打印结果<br /> title标签中string,即<code><title>The Dormouse's story>中间string部分

The Dormouse's story

5.属性print(soup.title.parent.name)打印结果
title.parent 是指title标签的父标签,是指 head 标签
head.name 可以获得该head标签的名称,即

括号中的head

head

6.属性print(soup.p)打印结果
如果文档中有多个这样的标签,返回的结果是第一个标签的内容,如上面我们通过soup.p获取p标签,而文档中有多个p标签,但是只返回了第一个p标签内容起始于

为止

The Dormouse's story

7.属性print(soup.p["class"])打印结果
第一个P标签中’class’的内容,把class=‘title’中赋给class的内容,字符串‘title’

['title']

8.属性print(soup.a)打印结果
第一个a标签内容起始于为止

Elsie

9.属性print(soup.find_all('a'))打印结果
找到所有a标签并打印相关内容

[Elsie, Lacie, Tillie]

10.属性print(soup.find(id='link3'))打印结果
打印id=link3的标签结果

Tillie
  1. 属性soup.select()

练习示例bs4_04.py,学习地址
【目标】
通过采用soup.select()方法,遍历html后获得目标内容。
其中关键点在于,对于所需内容的精准定位,通过()内的语句来实现:

11.1 关键字class
对于html内的内容,可以通过class(赋值给关键字class的类名)来进行定位
soup.select('.class的类名')

直接写成soup.select('.class')报错,因为找不到目标内容

报错TypeError: ‘NoneType’ object is not callable.png
head
class:*************************
Traceback (most recent call last):
  File "F:/01_python/01_testsamples/bs4_04.py", line 31, in 
    print(soup.selecet('.class'))
TypeError: 'NoneType' object is not callable

Process finished with exit code 1

理解格式含义,使用select()遍历和定位的目标是定位到类class对应名称中的内容:上面html中 class=‘sister’目标类名称是sister格式,按照类名查找 sister

print(soup.select(".目标类名称"))

示例见下

#按照类名查找 sister 上面html中 class=‘sister’目标类名称是sister,格式是print(soup.select(".目标类名称"))
print('sister:*************************')
print(soup.select(".sister"))

比如上述例子 会打印处类=sister的内容

sister:*************************
[Elsie, Lacie, Tillie]

参考文档
1.确定遍历目标
2.根据不同目标特性,找到语法格式

11.2 关键字id
按照id名称查找 注意格式 print(soup.select(“#目标id名称 “))。目标是id=link3,则写成”#link3”

print('id=link3:*************************')
print(soup.select("#link3"))

打印结果:

[Tillie]

11.4 组合高级查找
按照id名称查找 x标签中目标id y 格式 print(soup.select(“x #y”))

print('P标签id=link2:*************************')
print(soup.select("p #link2"))

打印结果:

P标签id=link2:*************************
[Lacie]

11.3 关键字标签
按照标签查找,注意目标标签名称

print('tag:*************************')
print(soup.select('a'))

打印结果:

tag:*************************
[Elsie, Lacie, Tillie]

综上,在bs4中希望筛选(或者查找)sth方法
1 直接查找
2 find_allfind
3 通过css选择器select()方法

2.2 BeautifulSoup :一些常用功能的使用和测试

点击此处,很喜欢这位小姐姐的文风,可以静下心阅读

2.2.1 关于bs4的解析速度

1.仔细阅读文档后发现,文档解析器对速度至关重要!
2.安装chardet模块
如果没有安装chardet模块,那么光一个网页就要7秒!!(安装方法自行度娘), 还不包括获取网页时间。然而试过后,如过山车一般:,安装了chardet以后7秒变成了一瞬。
ps:然而,用了几天后又变回了7秒,卸载了chardet又变回了一瞬间!

2.2.2 导入方式

BeautifulSoup升级到4以后,导入方法变了,如下:
from bs4 import BeautifulSoup

2.2.3 关于输入文本格式

关于被解析文档的编码格式
1.官方说无论被传入什么编码的文档,都会被统一为unicode
2.实际上有时候我发现,必须以unicode传入才能获得正确结果,这里试验发现,还真的是如此!必须传入decode过的码

    html_doc = open('test-Zhilian-list-page-sm1.html', 'r').read().decode('utf-8')
    # ^ 这个html文件其实是智联招聘搜索页的源码,可以自己保存下来直接试一试。

如下图,最简单一个爬虫示例。如果要用bs4,需要把参数the_pageread()后继续转换编码格式decode('uft-8')

最简单一个爬虫示例.png

2.2.4 关于bs4的文档解析器

又是一个大坑:bs升级到4后,实例化时需要明确指定文档解析器,如:
soup = BeautifulSoup(html_doc, 'lxml')
坑的地方:
1.但是著名的lxml在这里就是个大坑啊,
2.因为它会直接略过html所有没写规范的tag,而不管人家多在乎那些信息
PS:因为这个解析器的事,我少说也折腾了好几个小时才找到原因吧。

【总结】记住,选择 * html5lib*!效率没查多少,最起码容错率强,不会乱删你东西!
soup = BeautifulSoup(html_doc, 'html5lib')

5.# 关于bs4的输出格式 #################

prettify()官方解释是一律输出utf-8格式,

其实却是unicode类型!!所以必须在prettify()里面指定编码。

output = soup.prettify('utf-8')
print repr(output)


文章来源于互联网:01_7爬虫网页_BS4

发表评论