Python爬虫利器:Beautiful Soup (2)

每个tag或字符串都有父节点,即每个节点都被包含在tag中,通过 .parent 属性来获取某个元素的父节点: p.parent,通过元素的 .parents 属性可以递归得到元素的所有父辈节点。

soup = BeautifulSoup(div_html), \'lxml\') # 使用3.1中定义的 div_html div = soup.div # 获取 div 节点 sa = div.a.string # 第一个 a 节点的string sa.parent # a 节点 sa.parent.parent # div 节点 for parent in sa.parents: print(parent) # a # div # [document] # None 3.3 兄弟节点

兄弟节点就是具有相同父节点的同义词节点。如3.1中定义的 div_html 中的3个p标签互相为兄弟节点。使用下面的节点tag属性访问兄弟节点

next_sibling:当前节点的下一个兄弟节点

previous_sibling:当前节点的上一个兄弟节点

next_siblings:当前节点之后的所有兄弟节点

previous_siblings:当前节点之前的所有兄弟节点

4. 搜索文档树

搜索功能可以说是写爬虫过程中必用的功能,用来查找指定的节点,Beautiful Soup定义了很多搜索方法,这些搜索方法的参数和用法都很类似,查询功能非常强大,下面主要针对 find_all 方法说明。

4.1 过滤器

过滤器是使用搜索方法过程中的匹配规则,即参数的可能取值。过滤器可以为下面几种形式:

字符串:find_all(\'div\')

列表:find_all([\'div\', \'span\'])

正则表达式:find_all(re.compile(\'[a-z]{1,3}\'))

True:匹配任意非字符串子节点

方法:相当于匹配的回调函数,该方法返回 True 表示匹配

content = \'<nav><a>a_1</a><a>a_2</a>string</nav>\' soup = BeautifulSoup(content), \'lxml\') nav_node = soup.nav # <nav><a>a_1</a><a>a_2</a>string</nav> nav_node.find_all(True) # 不匹配 string # [\'<a>a_1</a>\', \'<a>a_2</a>\'] def has_class_but_no_id(tag): # 定义匹配函数 return tag.has_attr(\'class\') and not tag.has_attr(\'id\') soup.find_all(has_class_but_no_id) # 返回有class属性没有id属性的节点 4.2 find_all() find() 方法

find_all 方法返回匹配搜索的所有节点的列表或者空,而 find 方法直接返回第一个匹配搜索的结果。详细的定义如下:

find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs) find_find(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)

各参数含义如下:

name:匹配 tag 标签名

attrs:匹配属性名:find_all(href=\'index.html\')

text:匹配文档中的字符串内容

limit:指定匹配的结果集数量

recursive:默认True,False表示只搜索直接子节点

以上的参数值都可以是 4.1 中说明的任意一种过滤器值。另外还需要注意以下几点:

attrs 参数为字典类型,可以是多个属性条件组合

单独使用 class 属性时,应该使用 class_

class 属性为多值属性,会分别搜索每个 CSS 类名

按照CSS类目完全匹配时,必须顺序相同

# 搜索所有 div 标签 soup.find_all(\'div\') # 搜索所有具有id属性并且id属性值为 link1 或者 link2 的节点 soup.find_all(id=[\'link1\', \'link2\']) # 搜索所有 class 属性包含 button 的节点 soup.find_all(class_=\'button\') # 搜索所有匹配给定正则表达式内容的 p 标签 soup.find_all(\'p\', text=re.compile(\'game\')) # 搜索具有 button 类,并且具有值为 link1 的 href 属性的 a 标签 soup.find_all(\'a\', {\'classl\': \'button\', \'href\': \'link1\'}) # 只搜索一个直接子节点的 a 标签 soup.find_all(\'a\', limit=1, recursive=False) 4.3 其他方法

其他的搜索方法参数和 find_all 和 find 类似,它们成对出现,分别返回结果列表和第一个匹配的结果,只是搜索文档的范围不一样,下面列举一些常用的:

find_parents() 和 find_parent():只从当前节点的父节点中搜索

find_next_siblings() 和 find_next_sibling():只从当前节点的后面的兄弟节点搜索

find_previous_siblings() 和 find_previous_sibling():只从当前节点的前面的兄弟节点搜索

find_all_next() 和 find_next():从当前节点之后的节点搜索

find_all_previous() 和 find_previous():从当前节点之前的节点搜索

4.4 CSS选择器

Beautiful Soup支持大部分的CSS选择器,使用 select() 方法来搜索。如id选择器,标签选择器,属性选择器设置组合选择器。如:

soup.select(\'body a\')

soup.select(\'#top\')

soup.select(\'div > span\')

soup.select(\'.button + img\')

5. 修改文档树

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypzws.html