本博客所用示例html代码:
<div id="content">
<h1>TITLE</h1>
<div class="clear fix">
<div class="article">
<div class="indent">
<p class="ul first"></p>
<table width="100%">
<tr class="item">
<td width="100" valign="top">
<a class="nbg" href="somelink">
<img src="link_to_the_picture" width="90"/>
</a>
</td>
<td valign="top">
<div class="pl2">
<a href="somelink" title="title">INFORMATION 1</a>
</div>
<p class="pl">INFORMATION 2</p>
<div class="star clearfix">
<span class="allstar50"></span>
<span class="rating">INFORMATION 3</span>
<span class="pl">INFORMATION 4</span>
</div>
<p class="quote" style="somestyle">
<span class="inq">INFORMATION 5</span>
</p>
</td>
</tr>
</table>
<h2>INFORMATION 6</h2>
</div>
</div>
</div>
</div>
假设我们已经用以上内容初始化了一个bs4
对象:
soup = BeautifulSoup(html, 'lxml')
在以下内容中默认#
后为输出结果,为简洁起见,不再写print()
节点选择器
soup.h1 # <h1>TITLE</h1>
soup.p # <p class="ul first"></p> (文本中有多个p节点时,只输出第一个)
soup.div # 整个html文档 (注意若节点内嵌套有别的节点会全部输出)
soup.p.name # p (获取节点名 似乎是个很鸡肋的写法)
soup.a.attrs # {'class': ['nbg'], 'href': 'somelink'} (获取a节点所有属性)
soup.a.attrs['href'] # somelink
soup.table.div.a.string # INFORMATION 1 (.string可以获取节点的文本内容)
soup.table.tr.td.contents # ['\n', <a class="nbg" href="somelink">
<img src="link_to_the_picture" width="90"/>
</a>, '\n']
(.contents可以获取指定节点下所有直接子节点组成的列表 注意换行符也包括在内)
soup.table.tr.td.children # <list_iterator object at 0x0000016ED00DACC0> (依然是获取指定节点下的所有直接子节点,不过返回的是一个可迭代对象,可用for..in遍历)
soup.ul.descendants # <generator object Tag.descendants at 0x000002CEA442F9A8> (获取指定节点下所有子孙节点,可用for...in迭代)
soup.p.parent.name # div (获取指定节点的直接父节点的名字)
soup.p.parents # <generator object PageElement.parents at 0x000001C999E409A8> (获取指定节点的所有父节点,可用for...in遍历)
soup.table.previous_siblings # <generator object PageElement.previous_siblings at 0x0000021F33D109A8> (获取指定节点的所有前⾯的兄弟节点,可用for...in遍历)
soup.table.next_siblings # <generator object PageElement.next_siblings at 0x0000021F33D109A8> (获取指定节点的所有后⾯的兄弟节点,可用for...in遍历)
方法选择器
find_all() :
传⼊属性或⽂本,返回所有符合条件的节点
soup.find_all(name="p") # [<p class="ulfirst"></p>, <p class="pl">INFORMATION 2</p>, <p class="quote" style="somestyle">
<span class="inq">INFORMATION 5</span>
</p>] (获取名字为指定名的所有节点)
soup.find_all(attrs={"class":"inq"}) # [<span class="inq">INFORMATION 5</span>] (获取满足attr给定的属性的所有节点)
soup.find_all(class_="inq") # 同上 (注意这种方法和上一种方法在匹配时只要class属性中包含所给字段就可以匹配到)
soup.find_all(id='content') # 整个html文档 (获取满足给定的id的所有节点)
soup.find_all(text=re.compile('INFORMATION')) # ['INFORMATION 1', 'INFORMATION 2', 'INFORMATION 3', 'INFORMATION 4', 'INFORMATION 5', 'INFORMATION 6'] (获取含有给定字段的所有文本,其中re是正则模块)
find() :
传⼊属性或⽂本,返回所有符合条件的第⼀个元素
soup.find(name="p") # <p class="ul first"></p> (获取名字为指定名的第一个节点)
soup.find(text=re.compile('INFORMATION')) # INFORMATION 1 (获取含有给定字段的第一个文本,其中re是正则模块)
其余按属性和文本查找的语法和find_all()相同,只是结果只取第一个匹配的节点,不再赘述
CSS选择器
通过调用select()
方法可以使用css选择器的语法进行匹配
soup.select('table tr img') # [<img src="link_to_the_picture" width="90"/>]
soup.select('div.star span') # [<span class="allstar50"></span>, <span class="rating">INFORMATION 3</span>, <span class="pl">INFORMATION 4</span>]
soup.select('table tr img')[0].attrs['src'] # link_to_the_picture (获取节点属性值的方法,注意select返回的结果是列表,故需要先取出其中的元素)
soup.select('table div.pl2')[0].text # INFORMATION 1 (获取节点文本的方法,与上例相同,需要先将列表里的元素挑出来)
soup.select('table div.pl2')[0].get_text() # 结果同上
for a in soup.select('div.star span'):
print(a['class']) # 获取属性class的值
print(a.attrs['href']) # 等价 同上 获取属性值
print(a.get_text()) # 等价于print(a.string) 获取元素节点的⽂本内容