利用BeautifulSoup的find_all()函数查找某个标签且该标签某属性不出现

介绍

HTML代码如下:

<ul class="sf-r-list">
  <li>
	<a href="/book/77" class="sc-list-cover fl">
	<img class="ba_page_prvimg" onload="baImgCenter(this)" badt_outwidth="" src="https://wqxuetang.oss-cn-beijing.aliyuncs.com/cover/0/0/77/77.jpg!m">
	</a>
	<div class="sf-r-info">
	 <h3 class="sf-r-infotit"><a href="/book/77" class="ellipsis-2">Android多媒体开发高级编程——为智能手机和平板电脑开发图形、音乐、视频和富媒体应用</a>
	 </h3>
	<p class="sf-r-infoau text-truncate"> (美) 艾佛瑞 (Every,S.V.)...</p>
    <p class="sf-r-infotext ellipsis-2">《Android多媒体开发高级编程》使用清晰、直观的示例介绍了Android SDK中丰富的多媒体功能,有助于您开发能够创建、播放和共享多媒体的优秀Android应用程序。许多Android设备本身就是照相机、相册、...</p>
	<div class="sf-r-infoprice">
	<span style="color:#8E9AA6;">	暂不销售</span>
	</div>
	</div>
  </li>
  ...<!-- 与前述<li> .. </li>类同 -->
  ...
  <li style="float:none;margin:0;display:block;clear:both;"></li>
</ul>

需要把<ul> ...</ul直接的列表项中的信息抓取出来,其中每个列表项包含书籍的名称、作者、简介和价格信息。我最初使用的代码如下:

from bs4 import BeautifulSoup
from urllib.request import urlopen 

html = urlopen('https://wqbook.wqxuetang.com/category/tid_2004/pid_/pn_1014.html')
bs = BeautifulSoup(html,'lxml')
book_ul = bs.find("ul",class_="sf-r-list")
book_lis = book_ul.find_all("li")
for item in book_lis:
    print(item.prettify())

但是抓取的列表项中总会包含:

<li style="float:none;margin:0;display:block;clear:both;"></li>

当时在BeautifulSoup的函数find_all()中的参数上想了一些办法,因为我预感对标签的筛选肯定在参数中有所体现。可是都不成功。在我读到的爬虫书籍中,对此场景的技术方案都没讲解。无奈最后我采用了笨方法将<li style="float:none;margin:0;display:block;clear:both;"></li>剔除出去,代码如下:

from bs4 import BeautifulSoup
from urllib.request import urlopen 

html = urlopen('https://wqbook.wqxuetang.com/category/tid_2004/pid_/pn_1014.html')
bs = BeautifulSoup(html,'lxml')
book_ul = bs.find("ul",class_="sf-r-list")
book_lis = book_ul.find_all("li")
for item in book_lis:
    if book_li.find("a"):
        print(item.prettify())

亦即,我是通过判断在标签<li></li>是否包含子标签<a></a>来完成的。当时也顺利完成了爬虫的功能。但这个问题在我脑中记录下来了。直到今天,读书籍《Web Scraping with Python》第二版1的85页代码时,发现:

downloadList = bs.findAll(src=True)

受启发,可以用到本文场景中。当时书上也没讲解src=True的含义。

优雅的解决方案

在BeautifulSoup的函数find_all()中的参数中设置某个属性值为FalseTrue,允许我们在匹配时控制某个属性在标签中是否出现,以此来匹配查找。于是,本应用场景的优美解决方案为:

# scrapeBookInfoUnitTest.py
# 2020-08-20

from bs4 import BeautifulSoup
from urllib.request import urlopen 

html = urlopen('https://wqbook.wqxuetang.com/category/tid_2004/pid_/pn_1014.html')
bs = BeautifulSoup(html,'lxml')
book_ul = bs.find("ul",class_="sf-r-list")
#book_lis = book_ul.find_all("li")
book_lis = book_ul.find_all("li",style=False)
for item in book_lis:
    print(item.prettify())

  1. Ryan Mitchell. Web Scraping with Python: Collecting more data from the Modern Web. 2ed, O’Reilly, 2018. ↩︎

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页