当梦想照进现实

BeautifulSoup4最常用的5个函数【孙吉】

2016.04.27

宋陵公园图片

【注意】本文转自小伙伴孙吉在内网wiki里的一篇文章。孙吉,也叫堂主,是我们SEO组的强力DPS,在抓取方面有专精。

1、BeautifulSoup是爬取网页信息使用频率最高的库,下面简单介绍一下我编写脚本过程中利用bs4获取信息的方法。
2、本文用到到网的某一购物场所作为例子:
url='http://www.tripadvisor.cn/Attraction_Review-g294217-d3821611-Reviews-Empire_International_Tailors-Hong_Kong.html'
3、写脚本的时候经常参考网上别人写的,号称“菜鸟”“简洁易懂”,今天就让我来告诉你什么叫真正的菜!!!

1、find()

要点:找到唯一标签
例如:我们需要找出上面所给网页的购物场所的英文名,我们发现在这一段:
<span class="altHead">Empire International Tailors</span>
class 标签是唯一的,很简单,代码如下:

english_name=soup.find('span',{'class':"altHead"})
print english_name.string

2、extract()

要点:移除指定标签,并返回结果
例如:很多时候我们发现情况没有第一种那么简单,比如我们需要爬取所给网页中的中文名,我们发现在这一段:

<h1 id="HEADING" property="name" class="heading_name with_alt_title ">
    <div class="heading_height"></div>
Empire服装定制
    <span class="altHead">Empire International Tailors</span>
</h1>

如果通过:soup.find_all('h1',{'id':"HEADING"}),获取的是一整段,中文和英文名是一起的,所以一种方法是使用extract()移除<span>标签。代码如下:

biaoqian=soup.find('h1',{'id':"HEADING"})
english_name=biaoqian.span.extract()
print english_name#此处是英文名称
print biaoqian#此处span标签已经被移除,获得了中文名称,一举两得

3、select()

要点:通过属性值查找,避免相似
例如:很多属性值很相似,比如class="detail",class="detail_section info",class="detail wrap",所以如果通过find来查找,找出来的往往是一大批,这个时候就需要精确定位,例如我们需要爬取所给网页中的店铺分类,我们发现在这一段:

<div class="detail">
<a href="/Attractions-g294217-Activities-c26-t144-Hong_Kong.html">礼品与特产商店</a>, <a href="/Attractions-g294217-Activities-c26-Hong_Kong.html">购物</a> </div>

通观整个网页源代码我们发现,很多跟class="detail"类似的标签,所以我们使用select()精确指定我们需要的属性值,代码如下:

fenlei=soup.select('div[class="detail"]')
for fen in fenlei:
    print fen.text

再例如:我们需要获取导航栏目,我们发现在这一段:

<ul>
<li>
<span>&gt;&gt;</span>
<a href="/Tourism-g2-Asia-Vacations.html" title="亚洲旅游" onclick="ta.setEvtCookie('Breadcrumbs', 'click', 'Continent', 2, this.href); ">亚洲</a>
</li>
<li>
<span>&gt;&gt;</span>
<a href="/Tourism-g294211-China-Vacations.html" title="中国旅游" onclick="ta.setEvtCookie('Breadcrumbs', 'click', 'Country', 3, this.href); ">中国</a>
</li>
<li>
<span>&gt;&gt;</span>
<a href="/Tourism-g294217-Hong_Kong-Vacations.html" title="香港旅游" onclick="ta.setEvtCookie('Breadcrumbs', 'click', 'City', 4, this.href); ">香港</a>
</li>
<li>
<span>&gt;&gt;</span>
<a href="/Attractions-g294217-Activities-Hong_Kong.html" onclick="ta.setEvtCookie('Breadcrumbs', 'click', 'Attractions', 5, this.href);">香港景点</a>
</li>
<li>
<span>&gt;&gt;</span>
Empire服装定制 </li>
</ul>

分析:看上去让人很火大,一个个去获取的话,一方面比较繁琐,另一方面因为各个购物场所的情况不一样,当然也可以用selenium,不过那种也比较繁琐,看上去不简洁,通过观察我们发现onclick属性值有共同之处,于是代码如下:

daohang=soup.select('a[onclick^="ta.setEvtCookie(\'Breadcrumbs"]')
for dao in daohang:
    print dao.string

说明:^的意思是符合onclick属性值的前半部分,当然还可以符合后半部分加$。此种方法在获取href属性值的时候也会经常用到。

4、get_text()

要点:获取指定标签下所有文字内容,方便简洁
例如:我们需要爬取所给网页中的地址信息,我们发现在这一段:

<span class="format_address">地址: <span class="country-name" property="addressCountry">中国</span><span class="locality"><span property="addressLocality">香港</span></span><span class="street-address" property="streetAddress">麼地道63号好时中心6号铺</span><span class="extended-address">Houston Centre</span><span property="addressRegion" content=""><span class="postal-code" property="postalCode" content=""> </span>
</span>
</span>

分析:短短一个地址分得四分五裂,这就是到到的可恨之处,get_text()可以一锅端了,如果使用string必须定义到最近一层标签,比较麻烦,而且此处也没有必要。代码如下:

dizhi=soup.find('span',{'class':"format_address"})
print dizhi.get_text()

5、get_text("",strip=True)

要点:去除所获得文本的空白、换行等,干净整洁
例如:我们需要获得所给网页中的营业时间,我们发现在这一段:

<div class="hoursOverlay ">
<div>
<div class="days"><b>经营时间:</b></div> </div>
<div>
<span class="days">
周一 - 周六
</span>
<span class="hours">上午10点00分 - 下午9点00分</span>
</div>
</div>

如果直接获取文本内容的话,代码如下:

time=soup.find('div',{'class':"hoursOverlay"})
print time.get_text()

但是会出现很多换行,很不好看,需要去除空白处,代码如下:

time=soup.find('div',{'class':"hoursOverlay"})
print time.get_text("",strip=True)

评价:

一般来说,获取网页信息除了bs4,还有selenium、re两种。ba4不能获取的时候,一些边边角角毫无章程的信息使用re比较方便直接(我经常这么干),比如到到网的poi的经纬度信息。掌握了bs4的使用方法,结合re,爬取网页信息基本无障碍了。

后序:

bs4博大精深,我只是介绍了一下冰山一角,一般实际操作的过程中经常会发生各种意想不到的情况,此乃技艺生疏的表现,所以一般我会打开这个网址:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#searching-the-tree,非常全面,很久之后。我发现网页的头部写得很清楚,有中文版本:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/。

头图为我老家巩义,宋陵公园的图片
我之前也写过一篇关于BeautifulSoup的文章,Python BeautifulSoup4安装与简单应用,可以一起看下。

Comments
Write a Comment
  • Philipzzz reply

    谢谢分享!