[关闭]
@songying 2020-07-23T15:58:54.000000Z 字数 3642 阅读 2112

python爬虫利器之Beautifulsoup

python爬虫


find 无法定位怎么办

  1. 尝试换个解析器
  2. lxml
  3. html.parser

安装与导入

  1. pip install beautifulsoup4
  2. from bs4 import BeautifulSoup # 导入BeautifulSoup

1. 创建一个BeautifulSoup对象

当你爬取下HTML文本之后,你要做的第一件事就是将其解析成BeautifulSoup对象,这样才能进行后续分析。

  1. soup = BeautifulSoup( "html语句","lxml")

2. 格式化输出

BeautifulSoup 对象表示的是一个文档的全部内容

  1. soup.prettify() # 格式化输出html内容

简单试一试

我们就来爬取简书上的一篇文章为例:

  1. import requests
  2. from bs4 import BeautifulSoup
  3. response = requests.get('https://www.jianshu.com/p/0f5dc1d3d406')
  4. soup = soup = BeautifulSoup(response.text,"lxml")
  5. soup.prettify()

你自己查看输出,看看是不是HTML代码。

3. Beautiful Soup 四大对象种类

在前面我们提到了Beautiful Soup对象,这里我们详细探讨一下Beautiful Soup中的对象种类。

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .

3.1 Tag对象

Tag对象指的就是HTML代码中的 h1,p,body 等标签,在下面中就是一段HTML代码,其中的meta 就是一个Tag 。

  1. <meta content="title: 少年,想不想搭建一个属于自己的博客 date: 2017-10-19 17:04:12" name="description"/>

此外,tag的属性操作方法与python中的字典一样。

  1. tag = soup.标签名 # 如p,title等,查找的时第一个符合要求的标签

tag对象有两个属性,分别时name属性和attrs属性

  • name属性: tag.name,输出值为标签本身(title,p)
  • attrs属性: tag.attrs

一个tag,attrs会有多个子属性,诸如在HTML中提到的有class, id, style, title等属性。

  1. tag.attrs # 显示所有属性
  2. tag['属性名'] # 获取单一属性
  3. tag.get('属性名') # 获取单一属性
  4. tag['id'] = 1 # 修改属性
  5. del tag['id'] # 删除属性

3.2 NavigableString 对象

该对象用来表示Tag对象中的文字.

  1. tag_name.string # 获取标签中的内容,类型为NavigableString
  2. unicode_string = unicode(tag.string) # 将 NavigableString 对象转换成Unicode字符串
  3. tag.string.replace_with("更改后的内容") # 更改tag中打内容

3.3 BeautifulSoup 对象

BeautifulSoup 对象表示的是一个文档的全部内容,可以将它想象成一个特殊的tag。一般情况下只会用到格式化输出soup.prettify(),以及后面的find()find_all函数。

总的来说,你把它当成Tag对象就行。

3.4 comment对象

Comment对象 表示的是HTML文件中的注释部分。

  1. <!-- 注释内容 -->

Comment 对象是一个特殊类型的 NavigableString 对象。我们并不需要注释内容,所以我们需要在处理前判断某段文字是否属于注释内容。

  1. if type(soup.tag_name.string) == bs4.element.Comment

3.5 最重要的一点

无论是tag对象还是Beautifulsoup对象都可以通过.tag_name来访问它的子节点,不理解的话可以参见官方文档的 遍历文档树 -> 子节点 一节。

4. 最常用的两个查找函数

4.1 什么是过滤器?

过滤器顾名思义就是过滤信息的容器,通常与下面两个查找函数组合起来筛选出我们想要的信息。过滤器可以被用在tag的name中,节点的属性中,字符串中或他们的混合中.

过滤器有以下几种类型:

4.2 find_all()

  • 函数功能: 搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件.
  • 返回值: 没找到返回空列表,找到返回包含tag信息的列表
  1. html.find_all( name , attrs , recursive , text ,limit, keywords )
  • name参数:

    可以查找所有名字为 name 的tag, 可以是任意类型过滤器,字符串,正则,列表,方法,True。

    1. soup.find_all("title") # 查找tag名为title的tag
  • attrs参数

    有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:

    1. data_soup.find_all(data-foo="value")
    2. # SyntaxError: keyword can't be an expression

    但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:

    1. data_soup.find_all(attrs={"data-foo": "value"})
  • keyword参数:

    如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为 id 的参数,Beautiful Soup会搜索每个tag的”id”属性.

    1. soup.find_all(id='link2') # 查找属性内容中id='link2'的tag

    其中,属性内容可以使用过滤器,字符串,正则,列表,方法,True。

    1. soup.find_all(href=re.compile("elsie")) # 查找属性内容中属性herf中包含elsie的tag

    可以使用多个制定名字的参数来过滤tag:

    1. soup.find_all(href=re.compile("elsie"), id='link1')

    在tag的属性中,有一个常用的属性class,但由于与python关键字冲突,因此使用class_来代替class作为搜索时候的属性描述。

    1. soup.find_all("a", class_="sister") # 搜索所有class内容为sister的a

    class_ 参数同样接受不同类型的 过滤器 ,字符串,正则表达式,方法或 True

  • recursive参数

    • false:只搜索tag的直接子节点
    • true: 搜索tag的所有子孙节点(默认)
  • text参数

    通过 text 参数可以搜搜文档中的字符串内容,text参数接受字符串,正则,列表,True。

    1. soup.find_all("a", text="Elsie") # 找到string内容中包含Elsie的a
  • limit参数:

    limit 参数限制返回结果的数量.

    1. soup.find_all("a", limit=2)

4.3 find()

  1. find(name, attrs, recursive, text, keywords)
  2. # 返回值: 没找到: None

find() 相当于limit = 1 的findAll(),唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.

总结

其实,你只要掌握了上述内容,基本可以应付大多数爬虫,这就是典型的掌握20%,解决80%.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注