Python使用BeautifulSoup库解析HTML基本使用教程


Posted in Python onMarch 31, 2016

 BeautifulSoup是Python的一个第三方库,可用于帮助解析html/XML等内容,以抓取特定的网页信息。目前最新的是v4版本,这里主要总结一下我使用的v3版本解析html的一些常用方法。

准备

1.Beautiful Soup安装

为了能够对页面中的内容进行解析,本文使用Beautiful Soup。当然,本文的例子需求较简单,完全可以使用分析字符串的方式。

执行

sudo easy_install beautifulsoup4

即可安装。

2.requests模块的安装

requests模块用于加载要请求的web页面。

在python的命令行中输入import requests,报错说明requests模块没有安装。

我这里打算采用easy_install的在线安装方式安装,发现系统中并不存在easy_install命令,输入sudo apt-get install python-setuptools来安装easy_install工具。

执行sudo easy_install requests安装requests模块。

基础

1.初始化
   导入模块

#!/usr/bin/env python
from BeautifulSoup import BeautifulSoup    #process html
#from BeautifulSoup import BeautifulStoneSoup #process xml
#import BeautifulSoup             #all

    创建对象:str初始化,常用urllib2或browser返回的html初始化BeautifulSoup对象。

doc = ['hello',
    '
This is paragraph one of ptyhonclub.org.',
    '
This is paragraph two of pythonclub.org.',
    '']
soup = BeautifulSoup(''.join(doc))

    指定编码:当html为其他类型编码(非utf-8和asc ii),比如GB2312的话,则需要指定相应的字符编码,BeautifulSoup才能正确解析。

htmlCharset = "GB2312"
soup = BeautifulSoup(respHtml, fromEncoding=htmlCharset)

2.获取tag内容
   寻找感兴趣的tag块内容,返回对应tag块的剖析树

head = soup.find('head')
#head = soup.head
#head = soup.contents[0].contents[0]
print head

    返回内容:hello
   说明一下,contents属性是一个列表,里面保存了该剖析树的直接儿子。

html = soup.contents[0]    # <html> ... </html>
head = html.contents[0]    # <head> ... </head>
body = html.contents[1]    # <body> ... </body>

3.获取关系节点
   使用parent获取父节点

body = soup.body
html = body.parent       # html是body的父亲

    使用nextSibling, previousSibling获取前后兄弟

head = body.previousSibling  # head和body在同一层,是body的前一个兄弟
p1 = body.contents[0]     # p1, p2都是body的儿子,我们用contents[0]取得p1
p2 = p1.nextSibling      # p2与p1在同一层,是p1的后一个兄弟, 当然body.content[1]也可得到

    contents[]的灵活运用也可以寻找关系节点,寻找祖先或者子孙可以采用findParent(s), findNextSibling(s), findPreviousSibling(s)

4.find/findAll用法详解
   函数原型:find(name=None, attrs={}, recursive=True, text=None, **kwargs),findAll会返回所有符合要求的结果,并以list返回。
   tag搜索

find(tagname)                 # 直接搜索名为tagname的tag 如:find('head')
find(list)                   # 搜索在list中的tag,如: find(['head', 'body'])
find(dict)                   # 搜索在dict中的tag,如:find({'head':True, 'body':True})
find(re.compile(''))              # 搜索符合正则的tag, 如:find(re.compile('^p')) 搜索以p开头的tag
find(lambda)            # 搜索函数返回结果为true的tag, 如:find(lambda name: if len(name) == 1) 搜索长度为1的tag
find(True)                   # 搜索所有tag

   attrs搜索

find(id='xxx')                 # 寻找id属性为xxx的
find(attrs={id=re.compile('xxx'), algin='xxx'}) # 寻找id属性符合正则且algin属性为xxx的
find(attrs={id=True, algin=None})        # 寻找有id属性但是没有algin属性的


resp1 = soup.findAll('a', attrs = {'href': match1})
resp2 = soup.findAll('h1', attrs = {'class': match2})
resp3 = soup.findAll('img', attrs = {'id': match3})

text搜索
文字的搜索会导致其他搜索给的值如:tag, attrs都失效。方法与搜索tag一致

print p1.text
# u'This is paragraphone.'
print p2.text
# u'This is paragraphtwo.'
# 注意:1,每个tag的text包括了它以及它子孙的text。2,所有text已经被自动转为unicode,如果需要,可以自行转码encode(xxx)

recursive和limit属性
recursive=False表示只搜索直接儿子,否则搜索整个子树,默认为True。当使用findAll或者类似返回list的方法时,limit属性用于限制返回的数量,如findAll('p', limit=2): 返回首先找到的两个tag。

实例
本文以博客的文档列表页面为例,利用python对页面中的文章名进行提取。

文章列表页中的文章列表部分的url如下:

<ul class="listing">
  <li class="listing-item"><span class="date">2014-12-03</span><a href="/post/linux_funtion_advance_feature" title="Linux函数高级特性" >Linux函数高级特性</a>
  </li>
  <li class="listing-item"><span class="date">2014-12-02</span><a href="/post/cgdb" title="cgdb的使用" >cgdb的使用</a>
  </li>
...
</ul>

代码:

#!/usr/bin/env python                                                                              
# -*- coding: utf-8 -*-

' a http parse test programe '

__author__ = 'kuring lv'


import requests
import bs4

archives_url = "http://kuring.me/archive"

def start_parse(url) :
  print "开始获取(%s)内容" % url
  response = requests.get(url)
  print "获取网页内容完毕"

  soup = bs4.BeautifulSoup(response.content.decode("utf-8"))
  #soup = bs4.BeautifulSoup(response.text);

  # 为了防止漏掉调用close方法,这里使用了with语句
  # 写入到文件中的编码为utf-8
  with open('archives.txt', 'w') as f :
    for archive in soup.select("li.listing-item a") :
      f.write(archive.get_text().encode('utf-8') + "\n")
      print archive.get_text().encode('utf-8')

# 当命令行运行该模块时,__name__等于'__main__'
# 其他模块导入该模块时,__name__等于'parse_html'
if __name__ == '__main__' :
  start_parse(archives_url)
Python 相关文章推荐
Python基于sftp及rsa密匙实现远程拷贝文件的方法
Sep 21 Python
利用Django内置的认证视图实现用户密码重置功能详解
Nov 24 Python
tensorflow实现KNN识别MNIST
Mar 12 Python
pip安装时ReadTimeoutError的解决方法
Jun 12 Python
selenium设置proxy、headers的方法(phantomjs、Chrome、Firefox)
Nov 29 Python
Python基于mysql实现学生管理系统
Feb 21 Python
Python 的字典(Dict)是如何存储的
Jul 05 Python
pytorch .detach() .detach_() 和 .data用于切断反向传播的实现
Dec 27 Python
PyTorch 普通卷积和空洞卷积实例
Jan 07 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
Feb 04 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
Mar 09 Python
pycharm激活码免费分享适用最新pycharm2020.2.3永久激活
Nov 25 Python
Python使用Mechanize模块编写爬虫的要点解析
Mar 31 #Python
Python语言实现获取主机名根据端口杀死进程
Mar 31 #Python
Linux中Python 环境软件包安装步骤
Mar 31 #Python
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
Mar 30 #Python
横向对比分析Python解析XML的四种方式
Mar 30 #Python
python简单实现刷新智联简历
Mar 30 #Python
详解Python迭代和迭代器
Mar 28 #Python
You might like
php 获取远程网页内容的函数
2009/09/08 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
Yii 框架控制器创建使用及控制器响应操作示例
2019/10/14 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
2007/04/12 Javascript
Mootools 1.2 手风琴(Accordion)教程
2009/09/15 Javascript
Js-$.extend扩展方法使方法参数更灵活
2013/01/15 Javascript
使用window.prompt()实现弹出用户输入的对话框
2015/04/13 Javascript
详解javascript函数的参数
2015/11/10 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
用jquery获取自定义的标签属性的值简单实例
2016/09/17 Javascript
Bootstrap模态框(Modal)实现过渡效果
2017/03/17 Javascript
Vue生命周期示例详解
2017/04/12 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(二)
2017/05/11 Javascript
js实现数组和对象的深浅拷贝
2017/09/30 Javascript
JavaScript实现随机数生成器(去重)
2017/10/13 Javascript
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
python 并发下载器实现方法示例
2019/11/22 Python
Python concurrent.futures模块使用实例
2019/12/24 Python
一文带你了解Python 四种常见基础爬虫方法介绍
2020/12/04 Python
解决PyCharm无法使用lxml库的问题(图解)
2020/12/22 Python
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
室内设计专业学生的自我评价分享
2013/11/27 职场文书
简历自我评价怎么写呢?
2014/01/06 职场文书
主持词开场白
2014/03/17 职场文书
遗产继承公证书
2014/04/09 职场文书
关于责任的演讲稿
2014/05/20 职场文书
法学专业毕业生自荐信
2014/06/11 职场文书
带香烟到学校抽的检讨书
2014/09/25 职场文书
自我检讨报告
2015/01/28 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
南京南京观后感
2015/06/02 职场文书
海上钢琴师的观后感
2015/06/11 职场文书
鲁滨逊漂流记读书笔记
2015/06/26 职场文书
怎样评估创业计划书是否有可行性?
2019/08/07 职场文书
Mysql binlog日志文件过大的解决
2021/10/05 MySQL