Python网页解析利器BeautifulSoup安装使用介绍
admin
2023-07-31 02:19:11
0

python解析网页,无出BeautifulSoup左右,此是序言

安装

BeautifulSoup4以后的安装需要用eazy_install,如果不需要最新的功能,安装版本3就够了,千万别以为老版本就怎么怎么不好,想当初也是千万人在用的啊。安装很简单

复制代码 代码如下:
$ wget \”http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.2.1.tar.gz\” 
$ tar zxvf BeautifulSoup-3.2.1.tar.gz 

然后把里面的BeautifulSoup.py这个文件放到你python安装目录下的site-packages目录下

site-packages是存放Python第三方包的地方,至于这个目录在什么地方呢,每个系统不一样,可以用下面的方式找一下,基本上都能找到

复制代码 代码如下:
$ sudo find / -name \”site-packages\” -maxdepth 5 -type d 
$ find ~ -name \”site-packages\” -maxdepth 5 

当然如果没有root权限就查找当前用户的根目录
复制代码 代码如下:
$ find ~ -name \”site-packages\” -maxdepth 5 -type d 

如果你用的是Mac,哈哈,你有福了,我可以直接告诉你,Mac的这个目录在/Library/Python/下,这个下面可能会有多个版本的目录,没关系,放在最新的一个版本下的site-packages就行了。使用之前先import一下
复制代码 代码如下:
from BeautifulSoup import BeautifulSoup 

使用

在使用之前我们先来看一个实例
现在给你这样一个页面

复制代码 代码如下:
http://movie.douban.com/tag/%E5%96%9C%E5%89%A7

它是豆瓣电影分类下的喜剧电影,如果让你找出里面评分最高的100部,该怎么做呢
好了,我先晒一下我做的,鉴于本人在CSS方面处于小白阶段以及天生没有美术细菌,界面做的也就将就能看下,别吐

接下来我们开始学习BeautifulSoup的一些基本方法,做出上面那个页面就易如反掌了

鉴于豆瓣那个页面比较复杂,我们先以一个简单样例来举例,假设我们处理如下的网页代码

复制代码 代码如下:
 
Page title 
 
   

 
    This is paragraph 
         
        one 
       
 
        . 
   

 
   

 
    This is paragraph 
         
        two 
       
 
        . 
   

 
 
 

你没看错,这就是官方文档里的一个样例,如果你有耐心,看官方文档就足够了,后面的你都不用看
http://www.leeon.me/upload/other/beautifulsoup-documentation-zh.html

初始化

首先将上面的HTML代码赋给一个变量html如下,为了方便大家复制这里贴的是不带回车的,上面带回车的代码可以让大家看清楚HTML结构

复制代码 代码如下:
html = \'Page title

This is paragraphone.

This is paragraphtwo.

\’ 

初始化如下:
复制代码 代码如下:
soup = BeautifulSoup(html) 

我们知道HTML代码可以看成一棵树,这个操作等于是把HTML代码解析成一种树型的数据结构并存储在soup中,注意这个数据结构的根节点不是,而是soup,其中html标签是soup的唯一子节点,不信你试试下面的操作
复制代码 代码如下:
print soup 
print soup.contents[0] 
print soup.contents[1] 

前两个输出结果是一致的,就是整个html文档,第三条输出报错IndexError: list index out of range

查找节点

查找节点有两种反回形式,一种是返回单个节点,一种是返回节点list,对应的查找函数分别为find和findAll

单个节点

1.根据节点名

复制代码 代码如下:
## 查找head节点 
print soup.find(\’head\’) ## 输出为Page title 
## or 
## head = soup.head 

这种方式查找到的是待查找节点最近的节点,比如这里待查找节点是soup,这里找到的是离soup最近的一个head(如果有多个的话)

2.根据属性

复制代码 代码如下:
## 查找id属性为firstpara的节点 
print soup.find(attrs={\’id\’:\’firstpara\’})   
## 输出为

This is paragraphone.

 
## 也可节点名和属性进行组合 
print soup.find(\’p\’, attrs={\’id\’:\’firstpara\’})  ## 输出同上

3.根据节点关系

节点关系无非就是兄弟节点,父子节点这样的

复制代码 代码如下:
p1 = soup.find(attrs={\’id\’:\’firstpara\’}) ## 得到第一个p节点 
print p1.nextSibling ## 下一个兄弟节点 
## 输出

This is paragraphtwo.

 
p2 = soup.find(attrs={\’id\’:\’secondpara\’}) ## 得到第二个p节点 
print p2.previousSibling ## 上一个兄弟节点 
## 输出

This is paragraphone.

 
print p2.parent ## 父节点,输出太长这里省略部分 … 
print p2.contents[0] ## 第一个子节点,输出u\’This is paragraph\’

多个节点

将上面介绍的find改为findAll即可返回查找到的节点列表,所需参数都是一致的

1.根据节点名

复制代码 代码如下:
## 查找所有p节点 
soup.findAll(\’p\’)

2.根据属性查找
复制代码 代码如下:
## 查找id=firstpara的所有节点 
soup.findAll(attrs={\’id\’:\’firstpara\’}) 

需要注意的是,虽然在这个例子中只找到一个节点,但返回的仍是一个列表对象

上面的这些基本查找功能已经可以应付大多数情况,如果需要各个高级的查找,比如正则式,可以去看官方文档

获取文本

getText方法可以获取节点下的所有文本,其中可以传递一个字符参数,用来分割每个各节点之间的文本

复制代码 代码如下:
## 获取head节点下的文本 
soup.head.getText()         ## u\’Page title\’ 
## or 
soup.head.text 
## 获取body下的所有文本并以\\n分割 
soup.body.getText(\’\\n\’)     ## u\’This is paragraph\\none\\n.\\nThis is paragraph\\ntwo\\n.\’ 

实战

有了这些功能,文章开头给出的那个Demo就好做了,我们再来回顾下豆瓣的这个页面
http://movie.douban.com/tag/%E5%96%9C%E5%89%A7
如果要得到评分前100的所有电影,对这个页面需要提取两个信息:1、翻页链接;2、每部电影的信息(外链,图片,评分、简介、标题等)
当我们提取到所有电影的信息后再按评分进行排序,选出最高的即可,这里贴出翻页提取和电影信息提取的代码

复制代码 代码如下:
## filename: Grab.py 
from BeautifulSoup import BeautifulSoup, Tag 
import urllib2 
import re 
from Log import LOG 
 
def LOG(*argv): 
    sys.stderr.write(*argv) 
    sys.stderr.write(\’\\n\’) 
 
class Grab(): 
    url = \’\’ 
    soup = None 
    def GetPage(self, url): 
        if url.find(\’http://\’,0,7) != 0: 
            url = \’http://\’ + url 
        self.url = url 
        LOG(\’input url is: %s\’ % self.url) 
        req = urllib2.Request(url, headers={\’User-Agent\’ : \”Magic Browser\”}) 
        try: 
            page = urllib2.urlopen(req) 
        except: 
            return 
        return page.read()   
 
    def ExtractInfo(self,buf): 
        if not self.soup: 
            try: 
                self.soup = BeautifulSoup(buf) 
            except: 
                LOG(\’soup failed in ExtractInfo :%s\’ % self.url) 
            return 
        try: 
            items = self.soup.findAll(attrs={\’class\’:\’item\’}) 
        except: 
            LOG(\’failed on find items:%s\’ % self.url) 
            return 
        links = [] 
        objs = []  
        titles = [] 
        scores = [] 
        comments = [] 
        intros = [] 
        for item in items: 
            try: 
                pic = item.find(attrs={\’class\’:\’nbg\’}) 
                link = pic[\’href\’] 
                obj = pic.img[\’src\’] 
                info = item.find(attrs={\’class\’:\’pl2\’}) 
                title = re.sub(\'[ \\t]+\’,\’ \’,info.a.getText().replace(\’ \’,\’\’).replace(\’\\n\’,\’\’)) 
                star = info.find(attrs={\’class\’:\’star clearfix\’}) 
                score = star.find(attrs={\’class\’:\’rating_nums\’}).getText().replace(\’ \’,\’\’) 
                comment = star.find(attrs={\’class\’:\’pl\’}).getText().replace(\’ \’,\’\’) 
                intro = info.find(attrs={\’class\’:\’pl\’}).getText().replace(\’ \’,\’\’) 
            except Exception,e: 
                LOG(\’process error in ExtractInfo: %s\’ % self.url) 
                continue 
            links.append(link) 
            objs.append(obj) 
            titles.append(title)     
            scores.append(score) 
            comments.append(comment) 
            intros.append(intro) 
        return(links, objs, titles, scores, comments, intros) 
 
    def ExtractPageTurning(self,buf): 
        links = set([]) 
        if not self.soup: 
            try: 
                self.soup = BeautifulSoup(buf) 
            except: 
                LOG(\’soup failed in ExtractPageTurning:%s\’ % self.url) 
                return 
        try: 
            pageturning = self.soup.find(attrs={\’class\’:\’paginator\’}) 
            a_nodes = pageturning.findAll(\’a\’) 
            for a_node in a_nodes: 
                href = a_node[\’href\’] 
                if href.find(\’http://\’,0,7) == -1: 
                    href = self.url.split(\’?\’)[0] + href 
                links.add(href) 
        except: 
            LOG(\’get pageturning failed in ExtractPageTurning:%s\’ % self.url) 
 
        return links 
 
    def Destroy(self): 
        del self.soup 
        self.soup = None 

接着我们再来写个测试样例

复制代码 代码如下:
## filename: test.py 
#encoding: utf-8 
from Grab import Grab 
import sys 
reload(sys) 
sys.setdefaultencoding(\’utf-8\’) 
 
grab = Grab() 
buf = grab.GetPage(\’http://movie.douban.com/tag/喜剧?start=160&type=T\’) 
if not buf: 
        print \’GetPage failed!\’ 
        sys.exit() 
links, objs, titles, scores, comments, intros = grab.ExtractInfo(buf) 
for link, obj, title, score, comment, intro in zip(links, objs, titles, scores, comments, intros): 
        print link+\’\\t\’+obj+\’\\t\’+title+\’\\t\’+score+\’\\t\’+comment+\’\\t\’+intro 
pageturning = grab.ExtractPageTurning(buf) 
for link in pageturning: 
        print link 
grab.Destroy() 

OK,完成这一步接下来的事儿就自个看着办吧
本文只是介绍了BeautifulSoup的皮毛而已,目的是为了让大家快速学会一些基本要领,想当初我要用什么功能都是去BeautifulSoup的源代码里一个函数一个函数看然后才会的,一把辛酸泪啊,所以希望后来者能够通过更便捷的方式去掌握一些基本功能,也不枉我一字一句敲出这篇文章,尤其是这些代码的排版,真是伤透了脑筋

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...