Python爬虫案例与实战:常见的网页解析工具

Python爬虫案例与实战:常见的网页解析工具

在前面了解网页结构的基础上,接下来将介绍几种工具,分别是XPath、BeautifulSoup模块以及lxml模块。

1.3.1BeautifulSoup

BeautifulSoup是一个很流行的Python库,名字来源于《爱丽丝梦游仙境》中的一首诗,作为网页解析(准确地说是XML和HTML解析)的利器,BeautifulSoup提供了定位内容的人性化接口,简便正是它的设计理念。由于BeautifulSoup并不是Python内置的,因此仍需要使用pip来安装。这里来安装最新的版本(BeautifulSoup4版本,也叫bs4):pipinstallbeautifulsoup4。另外,也可以这样安装:pipinstallbs4。Linux用户也可以使用apt-get工具来进行安装:apt-getinstallPython-bs4。注意,如果计算机上Python2和Python3两种版本同时存在,那么可以使用pip2或者pip3命令来指明是为哪个版本的Python来安装,执行这两种命令是有区别的,如图1-4所示。
在这里插入图片描述
BeautifulSoup中的主要工具就是BeautifulSoup(对象),这个对象的意义是指一个HTML文档的全部内容,先来看看BeautifulSoup对象能干什么:

import bs4, requests 
from bs4 import BeautifulSoup    

ht = requests. get(' https://www. douban. com')
bsl = BeautifulSoup(ht. content) 
print(bs1. prettify())
print(' title')
print(bs1. title) 
print(' title. name')
print(bs1. title. name) 
print(' title. parent. name')
print(bs1. title. parent. name)
print(' find all "a"')
print(bs1. find_all('a')) 
print(' text of all "h2"')
for one in bs1. find_all('h2'):
    print(one. text)

如上示例程序的输出是这样的:

<!DOCTYPE HTML >
<html class=""lang ="zh-cmn-Hans">
< head >
                 ...
豆瓣时间

可以看出,使用BeautifulSoup来定位和获取内容是非常方便的,一切看上去都很和谐,但是有可能会遇到这样一个提示:

UserWarning:Noparserwasexplicitlyspecified

这意味着没有指定BeautifulSoup的解析器,解析器的指定需要把原来的代码变为这样:

bs1=BeautifulSoup(ht.content,'parser')

BeutifulSoup本身支持Python标准库中的HTML解析器,另外还支持一些第三方的解析器,其中最有用的就是lxml。根据操作系统不同,安装lxml的方法包括:
$ apt - get install Python- lxml
$ easy_install lxml
$ pip install lxml
Python标准库html,parser是Python内置的解析器,性能过关。而lxml的性能和容错能力都是最好的,缺点是安装起来有可能碰到一些麻烦(其中一个原因是lxml需要C语言库的支持),lxml既可以解析HTML,也可以解析XML。不同的解析器分别对应下面的指定方法:
bs1 = BeautifulSoup(ht. content, ’ html. parser’)
bs1 = BeautifulSoup(ht. content, ’ lxml’)
bs1 = BeautifulSoup(ht. content, ’ xml’)
除此之外,还可以使用html5lib,这个解析器支持 HTML5标准,不过目前还不是很常用。主要使用的是lxml解析器。
使用 find()方法获取到的结果都是Tag对象,这也是BeautifulSoup库中的主要对象之
-,Tag对象在逻辑上与XML或HTML 文档中的 tag相同,可以使用 tag.name和 tag,attrs来访问tag的名字和属性,获取属性的操作方法类似于字典 tag[‘href’]。
在定位内容时,最常用的就是find()和find_all()方法,find_all方法的定义如下:

find all(name, attrs, recursive, text,** kwargs)

该方法搜索当前这个tag(这时 BeautifulSoup 对象可以被视为一个tag,是所有 tag的根)的所有 tag子节点,并判断是否符合搜索条件。name参数可以查找所有名为name的 tag:

bs.find_all('tagname'

keyword参数在搜索时支持把该参数当作指定名字 tag的属性来搜索,就像这样:

bs.find(href ='https://book.douban.com'.text

其结果应该是“豆瓣读书”。当然,同时使用多个属性来搜索也是可以的,可以通过find_all()方法的attrs参数定义一个字典参数来搜索多个属性:

bs.find_all(attrs ={"href":re.compile'time'),"class""title"}

1.3.2XPath与lxml

XPath(XML Path Language,XML路径语言)是一种被设计用来在XML 文档中搜寻信息的语言。在这里需要先介绍一下XML 和HTML的关系,所谓的HTML,也就是之前所说的“超文本标记语言”,是WWW的描述语言,其设计目标是“创建网页和其他可在网页浏览器中访问的信息”,而XML(Extensible Markup Language,可扩展标记语言的前身是SGML) (标准通用标记语言)。简单地说,HTML 是用来显示数据的语言(同时也是html文件的作用),XML是用来描述数据、传输数据的语言(对应xml文件,这个意义上XML 十分类似于JSON)。也有人说,XML是对HTML的补充。因此,XPath可用来在XML 文档中对元素和属性进行遍历,实现搜索和查询的目的,也正是因为XML与HTML的紧密联系,可以使用XPath来对HTML文件进行查询。

XPath的语法规则并不复杂,需要先了解XML中的一些重要概念,包括元素、属性、文本、命名空间、处理指令、注释以及文档,这些都是XML中的“节点”,XML 文档本身就是被作为节点树来对待的。每个节点都有一个parent(父/母节点),例如:

<movie>
    < name > Transformers </name >
    <director > Michael Bay </director 》
</movie>

上面的例子里,movie是name 和 director的parent节点。name、director是movie的子节点。name 和 director互为兄弟节点(Sibling)。

<cinema >
    <movie >
        < name > Transformers </name >
        <director > Michael Bay </director >
    </movie>
    <movie>
        < name > Kung Fu Hustle </name >
        <director > Stephen Chow </director 》
    </movie>
</cinema >

如果XML是上面这样子,对于name而言,cinema 和movie就是先祖节点(Ancestor),同时name和movie 就是cinema的后辈(Descendant)节点。

XPath表达式的基本规则如表1-1所示。
在这里插入图片描述

在实际编程中,一般不必亲自编写XPath,使用 Chrome等浏览器自带的开发者工具就能获得某个网页元素的XPath路径,通过分析感兴趣的元素的XPath,就能编写对应的抓取语句。

在 Python 中用于 XML处理的工具不少,如Python 2版本中的 ElementTree API等,不过目前一般使用1xml这个库来处理XPath。lxml的构建是基于两个C语言库的:libxml2和 libxslt,因此,性能方面,lxml表现得足以让人满意。另外,lxml支持XPath 1.0.XSLT 1.0.定制元素类,,以及 Python 风格的数据绑定接口,因此受到很多人的欢迎。

当然,如果机器上没有安装Ixml,首先还是得用pip install lxml命令来进行安装,安装时可能会出现一些问题(这是由于lxml本身的特性造成的)。另外,lxml还可以使用 easy install 等方式安装,这些都可以参照1xml官方的说明:http://lxml.de/installation.html。

最基本的lxml解析方式如下:

from lxml import etree 
doc = etree. parse(' exsample. xml')

其中的parse()方法会读取整个XML 文档并在内存中构建一个树结构,如果换一种导入方式:

from lxml import html

这样会导入html tree结构,一般使用 fromstring()方法来构建:

text-requests.get('http://example.com'.text
html.fromstring(text)

这时将会拥有一个lxml.html.HtmlElement对象,然后就可以直接使用 xpath寻找其中的元素:

h1.xpath('your xpath expression'

例如,假设有一个HTML文档如图1-5所示。

这实际上是维基百科“苹果”词条的页面结构,可以通过多种方式获得页面中的Apple这个大标题(hl元素),例如:

from lxml import html #访问链接,获取 HTML 
text = requests.get('https://en.wikipedia.org/wiki/Apple'.text

在这里插入图片描述

ht = html.fromstring(text)#HTML解析

h1Ele = ht.xpath('//*[@id ="firstHeading"]'[0]#选取id为 firstHeading的元素
print(h1Ele.text)#获取 text 
print(h1Ele.attrib)#获取所有属性,保存在一个dict钟 
print(h1Ele.get('class'))
#根据属性名获取属性
print(h1Ele.keys())
#获取所有属性名
print(h1Ele.values())
#获取所有属性的值

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值