您的位置:首页 > 编程语言 > Python开发

python-63: 为什么要学习BS4

2015-12-21 20:45 766 查看
上一小节我们提出了一个问题:为什么要学习BS4

前面的学习中我一直使用RE,觉得也不是很难用,但是,上网查资料的时候看到大部分都使用BS4,还有很多人一直说BS4很好,虽然BS4很好,但是这还不足以让我去学习它,总不能别人说什么好就去做什么事情吧,所以我决定花点心思找一找,有没有某些情况,使用RE没法实现或者很难实现,但是BS4却很容易实现的呢?如果真的找到的话,这会是一个很好的学习bs4的理由

我们来看看下面一个网页:http://www.w3school.com.cn/html5/html_5_intro.asp

这是一个免费的网络教程网站,现在我需要做这样一个尝试,从网页源码中将文章的标题,正文的内容取出来,为了便于分析,这里还是贴上源码

<div id="maincontent">
<h1>HTML 5 简介</h1>
<div id="tpn">
<ul class="prenext">
<li class="pre"><a href="/html5/index.asp" title="HTML5 教程">HTML5 教程</a></li>
<li class="next"><a href="/html5/html_5_video.asp" title="HTML5 视频">HTML5 视频</a></li>
</ul>
</div>
<div id="intro">
<p><strong>HTML5 是下一代的 HTML。</strong></p>
</div>
<div>
<h2>什么是 HTML5?</h2>
<p>HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。</p>
<p>HTML 的上一个版本诞生于 1999 年。自从那以后,Web 世界已经经历了巨变。</p>
<p>HTML5 仍处于完善之中。然而,大部分现代浏览器已经具备了某些 HTML5 支持。</p>
</div>
<div>
<h2>HTML5 是如何起步的?</h2>
<p>HTML5 是 W3C 与 WHATWG 合作的结果。</p>
<p class="note"><span>编者注:</span>W3C 指 World Wide Web Consortium,万维网联盟。</p>
<p class="note"><span>编者注:</span>WHATWG 指 Web Hypertext Application Technology Working Group。</p>
<p>WHATWG 致力于 web 表单和应用程序,而 W3C 专注于 XHTML 2.0。在 2006 年,双方决定进行合作,来创建一个新版本的 HTML。</p>
<p>为 HTML5 建立的一些规则:</p>
<ul>
<li>新特性应该基于 HTML、CSS、DOM 以及 JavaScript。</li>
<li>减少对外部插件的需求(比如 Flash)</li>
<li>更优秀的错误处理</li>
<li>更多取代脚本的标记</li>
<li>HTML5 应该独立于设备</li>
<li>开发进程应对公众透明</li>
</ul>
</div>

好,我们来分析一下怎么从网页中获取我们想要的数据,首先,大的标题是在 <h1>HTML 5 简介</h1> 里面,然后<h2>......</h2>是小的标题,正文的内容在<p>......</p>或者<li>......</li>里面,第一眼看过去可能觉得这个规律这么好找,所以re应该很好写,但实际上真的是这样吗?我们来试试看吧,按照我们前面对源码的分析,我首先会这样写,

<h1>(.*?)</h1>.*?<h2>(.*?)</h2>.*?<p>(.*?)</p>.*?<li>(.*?)</li>

但是这样的输出结果是什么呢?



明显不是我们想要的结果,为什么会这么少,究竟发生了什么事情

其实原因很简单,这样写的re是同时匹配这4个标签的,它只会按照上面写的顺序去匹配内容,如果我们网页中所有的内容都是按下面这样的格式写的话,re很容易匹配

<h1>HTML 5 简介</h1>
<h2>什么是 HTML5?</h2>
<p>HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。</p>
<li>新特性应该基于 HTML、CSS、DOM 以及 JavaScript。</li>

但是网页上的源码并不是这样的,它可能是<h2>......</h2><p>......</p>或者<h2>......</h2><li>......</li>这样各种乱入的,re就不能适应这种情况,它并不会识别这些乱了套的标签,因为事实上,它查找的流程是这样的

大家好我是re,我要先匹配<h1>......</h1>,找到内容了,好,那就匹配下一个<h2>......</h2>

但是这些<div,<ul,<li......这些是什么鬼,我要找的不是这些,别来烦我啦,我要继续往下找,额?又找到了,好耶

我现在需要匹配第三个<p>......</p>,但是中间还是碰到好多<h2>,<li>的,咦?这个<h2>好像很眼熟捏?这个不是我上回找的那个吗?但是不管了,我现在找的不是这个,我要找的是<p>,好,终于又找到了

接下来是<li>,中间还是遇到很多的<h2>,<p>,真是的,一天天的没事做来烦我,我要赶紧找到<li>,OK,找到了,但是这只是第一轮,我还要再找找看有没有<h1>

貌似真的找不到<h1>的标签了,好了,完美收工,今天就到这里吧

如果照这样的流程,那我们似乎没有办法能够获取我们想要的信息了,其实不然,方法是人想出来的嘛,我们可以绕点远路,曲线救国,我这里给大家提供两个思路

写四个re分别获取<h1><h2><p><li>的数据,然后将获取的数据整理再拼接起来

比如可以使用<h1>(.*?)</h1>,<h2>(.*?)</h2>......获取相对应的值,然后将这些内容在输出的时候进行拼接处理

2.先获取一整个代码块的内容,然后将不需要的部分删掉

我们看到,我们要获取的部分是在<div id="maincontent">到<div id="bpn">之间的内容,这应该是整个网页源码中比较有规律的一块,我们可以使用re将这部分的内容取出来,就像这样

<div id="maincontent">(.*?)<div id="bpn">

  然后中间的标签或者是各种符号什么的我们可以使用re再进行处理,将这些内容去掉

但是这样的方法其实也还是很麻烦的,还有没有别的方法呢?如果使用BS4呢?会不会好一点?

我这里就直接上代码了,现在可以不用管代码是怎么实现的,看懂看不懂都没关系,反正后面也会学习到的,这代码包括查资料什么的总共花了十几分钟,之前没有任何BS4的知识,写得不好但还是可以看出效果,大家随意感受下

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
__author__ = '217小月月坑'

'''
为什么要使用bs4
'''

import urllib2
from bs4 import BeautifulSoup
# 获取网页内容
url = 'http://www.w3school.com.cn/html5/html_5_intro.asp'

headers = {'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0'}

request = urllib2.Request(url,headers=headers)
response = urllib2.urlopen(request)
contents = response.read().decode("gbk")
# bs4进行处理
soup = BeautifulSoup(contents)
result = soup.find(id="maincontent")
result_str = str(result)
soup = BeautifulSoup(result_str)
print soup.get_text()

我们来看看结果



除去获取网页源码的部分,整个BS4的处理只用了5行代码就基本实现我们想要的效果,这比RE要方便很多吧,当然,这只是其中的一种情况,还有很多种情况使用BS4比RE要方便得多,以及BS4和RE一起使用的,甚至BS4中嵌入RE使用的,这些内容在后面都会尽量讲到,当然是以实例的方式来学习,毕竟看了好多无聊的文档,己所不欲勿施于人
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 爬虫