Python使用BeautifulSoup库解析HTML基本使用教程
作者:kuring 发布时间:2021-12-22 17:48:05
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实现列表删除重复元素的三种常用方法。分享给大家供大家参考,具体如下:给定一个列表,要求删除列表中重复元素。list
- Jinja是组成Flask的模板引擎。可能你还不太了解它是干嘛的,但你对下面这些百分号和大括号肯定不陌生:{% block body %}
- --相信大家肯定经常会把数据导入到数据库中,但是可能会有些记录行的所有列的数据是null,这为null的数据是我们不需要 --现在需要一个简
- StringIO它主要是用在内存读写str中。主要用法就是:from io import StringIOf = StringIO()f.w
- 我们以学信网为例爬取个人信息 **如果看不清楚按照以下步骤:**1.火狐为例 打开需要登录的网页–> F12 开发者模式 (鼠标右击,
- 如果不是因为总监审查严格,一定要求这个细节解决掉,也许我也不会去深究根源性的解决办法,再此感谢MTIME负责而严格的同事。首先描述一下问题:
- 前言:python虽然是一门'慢语言',但是也有着比较多的性能检测工具来帮助我们优化程序的运行效率。这里总结了五个比较好的p
- 先来看看Global.asax文件代码:<script language="VB" runat
- pyautogui是一个可以控制鼠标和键盘的python库,类似的还有pywin32。pyautogui的安装pip3 install py
- 程序图标主要作用是为了使该程序更加具象及更容易理解,除了上述的作用外,有更好视觉效果的图标可以提高产品的整体体验和品牌,可引起用户的关注和下
- Array可以使用下标,Map和Set不能使用下标,ES6引入了iterable类型,Array,Map,Set都属于iterable类型,
- Xception是继Inception后提出的对Inception v3的另一种改进,学一学总是好的什么是Xception模型Xceptio
- phpMyAdmin可以管理整个MySQL服务器(需要超级用户),也可以管理单个数据库。为了实现后一种,你将需要合理设置MySQL用户,他只
- 背景考虑这样一种情况,产品同学希望达到以下功能:在我们的网页中有一个固定区域,这个区域会用于渲染从后端拉取的含有图片等资源的富文本字符串。他
- 本文实例讲述了jQuery实现简单复制json对象和json对象集合操作。分享给大家供大家参考,具体如下:<!DOCTYPE html
- 发现问题最近在打开项目的时候,发现我的默认路由没加载上linkActiveClass,网上一搜,发现很多同学也有这个问题,查了一些资料发现这
- 本文实例为大家分享了php微信公众号开发之快递查询的具体代码,供大家参考,具体内容如下快递查询数组用法foreach查询接口是:爱快递:ht
- 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。re 模块使 Python 语言拥有全部的正则表达式功能。
- 一、安装前准备查看数据库版本命令: mysql --versionmysql-community-common-8.0.17-1.el7.x
- 在对数值进行格式化的时候,一个常见的问题是按照千分位格式化,网上对这个问题已经有很多种解决方法了,还可以利用Array.prototype.