python 爬虫实战实现 XPath 和 lxml | 学习笔记

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 快速学习 python 爬虫实战实现 XPath 和 lxml

开发者学堂课程【Python  爬虫实战python  爬虫实战实现 XPath  和  lxml 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/555/detail/7645


python  爬虫实战实现 XPath 和  lxml


内容简介:

一、HTML  解析

二、XPath**

三、测试  XML、XPath


一、HTML  解析

通过上面的库,都可以拿到  HTML 内容。

HTML  的内容返回给浏览器,浏览器就会解析它,并对它渲染。

HTML  超文本表示语言,设计的初衷就是为了超越普通文本,让文本表现力更强。

XML  扩展标记语言,不是为了代替  HTML,而是觉得  HTML  的设计中包含了过多的格式,承担了一部分数据之外的任务,所以才设计了 XML  只用来描述数据。

HTML 和  XML  都有结构,使用标记形成树型的嵌套结构。DOM( DocumentObjectModel )来解析这种嵌套树型结构,浏览器往往都提供了对DOM  操作的  API,可以用面向对象的方式来操作  DOM。


二、XPath***

http://www.w3school.com.cn/xpath/index.asp 中文教程

XPath是一门在XML文档中查找信息的语言。XPath 可用来在  XML  文档中对元素和属性进行遍历。

工具

XMLQuirewin7 +需要.NET框架4.0-4.5。

测试  XML、XPath

(1)XPath  简介

XPath 是一门在 XML  文档中查找信息的语言。XPath  用于在  XML  文档中通过元素和属性进行导航。

在学习之前应该具备的知识:

在继续学习之前,应该对下面的知识有基本的了解:

HTML / XHTML

XML / XML 命名空间

(2)XPath  术语

节点(Node)

在  XPath  中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML  文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。

请看下面这个  XML 文档:

Harry Potter

J K. Rowling

2005

29.99

上面的  XML  文档中的节点例子:

(文档节点)

J K. Rowling (元素节点)

lang="en" (属性节点)

基本值(或称原子值,Atomic value)

基本值是无父或无子的节点。

基本值的例子:

J K. Rowling

"en"

项目( Item )

项目是基本值或者节点。

节点关系

父(Parent)

每个元素以及属性都有一个父。

在下面的例子中,book  元素是  title、author、year  以及 price 元素的父:

Harry Potter

J K. Rowling

2005

29.99

子(Children)

元素节点可有零个、一个或多个子。

在下面的例子中,title、author、year  以及  price 元素都是 book 元素的子:

Harry Potter

J K. Rowling

2005

29.99

同胞(Sibling)

拥有相同的父的节点

在下面的例子中,title、author、year 以及 price 元素都是同胞:

Harry Potter

J K. Rowling

2005

29.99

先辈(Ancestor)

某节点的父、父的父,等等。

在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素:

Harry Potter

J K. Rowling

2005

29.99

后代(Descendant)

某个节点的子,子的子,等等。

在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

Harry Potter

J K. Rowling

2005

29.99

XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。

XML 实例文档

我们将在下面的例子中使用这个 XML 文档。

Harry Potter

29.99

Learning XML

39.95

选取节点

XPath  使用路径表达式在  XML  文档中选取节点。节点是通过沿着路径或者斯特普来选取的

下列为最有用的路径表达式:

表达式

描述

nodename

选取此节点的所有子节点。

/

从根节点选取。

//

从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置

.

选取当前节点。

..

选取当前节点的父节点

@

选取属性

实例

在下面的表格里,已给列出一些路径表达式以及表达式结果:

路径表达式

结果

bookstore

选取bookstore元素的所有子节点

/bookstore

选取根元素bookstore。

注释:假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取属于bookstore的子元素的所有book元素

//book

选取所有book子元素,而不管它们在文档中的位置

bookstore//book

选择属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么

位置。

//@lang

选取名为lang的所有属性

谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式

结果

/bookstore/book[1]

选取属于bookstore子元素的第一个book元素。

/bookstore/book[last()]

选取属于bookstore子元素的最后一个book元素。

/bookstore/book[last()*1]

选取属于bookstore子元素的倒数第二个book元素

/bookstore/book[position()<3]

选取最前面的两个属于

 

bookstore元素的子元素的book元素

//title[@lang]

选取所有拥有名为lang的属性的title元素

//title[@lang=‘eng‘]

选取所有title元素,且这些元素拥有值为eng的lang属性

/bookstore/book[price>35, 00]

选取bookstore元素的所有book元素,且其中的price元素的值须大于35. 00

/bookstore/book[price>35.00]/title

选取bookstore元素中的book元素的所有title元素,且其中的price元素的值须大于35.00

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符

描述

*

匹配任何元素节点

@*

匹配任何属性节点

node()

匹配任何类型节点

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:路径表达式

结果

/bookstore/*

选取bookstore元素的所有子元素

//*

选取文档中的所有元素

//title[@*]

选取所有带有属性的title元素

选取若干路径

通过在路径表达式中使用“|”运算符,您可以选取若干个路径。

实例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

实例

在下面表格中,列出来一些路径表达式,以及表达式的结果:

路径表达式

结果

//book/title | //book/price

选取book元素的所有title和price元素

//title | //price

选取文档中的所有 title 和 price 元素。

/bookstore/book/title | //price

选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。



三、测试  XML、XPath

Gambardella ,Matthew

XML Developer's Guide

Computer

44. 95

2000-10-01

< description >An in-depth look at creating  applications

with XML.

Ralls, Kim

Midnight Rain

Fantasy

5. 95

2000-12-16

< description >A former architect battles corporate zombies,

an evil sorceress, and her own childhood to become queen

of the world.

Corets,Eva

Maeve Ascendant

Fantasy

5. 95

2000-11-17

< description >After the collapse of a  nanotechnology

society in England, the young survivors lay the

foundation  for a new society.

Corets, Eva

Oberon's Legacy

Fantasy

5. 95

2001-03-10

< description >In post- apocalypse  England, the  mysterious

agent known only as Oberon helps to create a new life

for the  inhabitants  of London. Sequel to Maeve

Ascendant.

将上述代码保存名为  books.xml  文件

通过  XMLQuire.exe  运行提取需要的东西

当鼠标点击代码所在行是,上述就会出现相对应的  XPath,这种是绝对路径

点击 XPath  后,会出现所需要的工具栏,

在工具栏中输入 /bookstore  会出现一下效果

与此同时,在原来的页面中会做出相应变化。

如果在工具栏中直接输入  book,该工具不会查找出来,这是由于他不是这段代码中的根节点,需要用到//,可以从根下开始寻找所有结点。

XPath  主要根据当前文档的特点来写对应  XPath  的表达式,还可以去找所有带有id的值,//@id  表示 id  是一个属性,可以通过这种方法或的所有的属性值搜索结果。

如果写成//book@id,这种写法是错误的,应该写成  //book[@id],若在后面加入“id=bk102” 变成  //book[@id=“bk102“]就会在查找栏中找到相应内容。

类似的,如果写成 //book[@*],则表示所有有book属性的都找出来。

通过以上操作可以快速找到所要的结点和结点对应的内容

/根结点

元素节点

Corets,Eva  元素节点,

id="bk104"  是属性节点,id  是元素节点 book  的属性

节点之间的嵌套形成父子 (parent、children)  关系。

具有同一个父节点的不同节点是兄弟 (sibling) 关系。

谓语( Predicates )

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

谓语就是查询的条件。

操作符或表达式

含义

/

从根节点开始找

//

从当前节点开始任意层找

.

当前节点

..

当前节点的父节点

@

选择属性

节点名

选取所有节点的父节点

*

匹配任意元素节点

@*

匹配任意属性节点

node()

匹配任意类型的节点

text()

匹配text类型节点

XPath 轴

轴可定义相对于当前节点的节点集。

轴名称

结果

ancestor

选取当前节点的所有先辈(父、祖父等)。

ancestor-or-self

选取当前节点的所有先辈(父、祖父等)以及当前节点本身。

attribute

选取当前节点的所有属性。

child

选取当前节点的所有子元素。

descendant

选取当前节点的所有后代元素(子、孙等)

descendant-or-self

选取当前节点的所有后代元素(子、孙等)以及当前节点本身。

following

选取文档中当前节点的结束标签之后的所有节点。

namespace

选取当前节点的所有命名空间节点。

parent

选取当前节点的父节点

preceding

选取文档中当前节点的开始标签之前的所有节点

preceding-sibling

选取当前节点之前的所有同级节点。

self

选取当前节点。


工具使用图:

注意:在表达式编写框中点回车键时,会发现东西不存在,再写其他的时候会发现执行不出来,需要用滚轮或光标来查看是否有多行,还有再点击debug模式后,开启之后需要再点击一下,否则表达式编写框不能够修改

在表达式编写框中输入  //bookstore//title|/bookstore//price

就会找见所有 price 和 title  所在的位置

左侧展开的就是树,在里面双击切换上下文节点,前面的小房子图标表示一篇文章的上下文

表达式编写框就相当于当前上下文节点,通过上下文的切换来选择所需内容,在编程过程中是可以控制上下节点,但在测试中想要选择上下节点是无法指定的,会选择这种方式来指定。

表示在当前节点下找到 price ,若觉得此种方式不便,也可以写. /price 来表示在当前节点下寻找。

XPATH  实例

以斜杠开始的称为绝对路径,表示从根开始。

不以斜杆开始的称为相对路径,一般都是依照当前节点来计算。当前节点在上下文环境中,当前节点很可能已经不是根节点了。

一般为了方便,往往 xml 如果层次很深,都会使用//来查找节点。

以下为主要路径表达式及含义:

title--- 选取当前节点下所有 title 子节点

/book---从根结点找子节点是 book 的,找不到

book/title---当前节点下所有子节点 book 下的 title 节点

//title---从根节点向下找任意层中 title 的节点

book/little---当前节点下所有 book 子节点下任意层次的 title 节点

//@name---任意层下含有 name 的属性,取回的是属性

//book[@id]---任意层下含有 name 属性的 book 节点

//book[@id="bk101"]---任意层下含有 name 属性且等于'bk101'的 book 节点

/bookstore/book[1]---根节点 bookstore  下第一个 book 节点,从1开始

/bookstore/book[1]/@id---根节点 bookstore  下第一个 book 节点的 id 属性

/bookstore/book[last()-1]---根节点 bookstore 下倒数第二个 book 节点,函数last0

/bookstore/*---匹配根节点 bookstore 的所有子节点,不递归

//*---匹配所有子孙节点

//*[@*]---匹配所有有属性的节点

//book[@*]---匹配所有有属性的 book 节点

//@*---匹配所有属性

//book/title]/price---匹配 book 下的 title 节点或者任意层下的 price

//book[position()=2] ---匹配 book 节点,取第二个

//book/title//price---匹配book下的title节点或者任意层下的price

//book[position()=2]---匹配 book 节点,取第二个

//book[position()

//book[price>40]---匹配 price 节点值大于40的 book 节点

//book[2]/node()---匹配位置为2的 book 节点下的所有类型的节点

//book[1]/text()---匹配第一个 book 节点下的所有文本子节点

//book[1]//text()---匹配第一个 book 节点下的所有文本节点

//*[local-name()="book]---匹配所有节点且不带限定名的节点名称为book的所有节点

//book/child::node()[local-name()='price'and text()<10]---所有 book 节点的子节点中名字叫做 price  的且其内容小于10的节点,等价于//book/price[text()<10]

lxmI

Ixml是 Python 下功能丰富的XML、HTML 解析库,性能非常好,是对  libxml2  和libxslt  的封装。最新版支持  Python 2.6+,python3  支持到3.6。

CentOS 编译安装需要

#yum  install libxml2 -devel libxslt-devel

注意,不同平台不一样,参看 http://lxmI.de/installation.html

lmxl安装

$pip install lxml

from lxml import  etree

#使用etree构建HTML

root=etree. Element('html')

print(type(root))

print(root. tag)

body=etree. Element('body')

root. append(body)

print(etree. tostring(root))

sub=etree. Sub Element(body,'child1')#增加子节点

print(type(sub))

sub=etree.  Subblement (body,'child2') append(etree. Element('child21'))

print(etree, tostring(root, pretty _ print=True). decode()

可以在浏览器上搜索   lxml  的官网,网页上内容丰富,可以在上面自学。一般会在上面学习一些简单的内容,比如构建切面,解析数据之类。

首先如何下载  lmxl,点击右上角的菜单,打开目录栏,选择  Installing lxml  目录。

其中会要求 c 语言的某些库以及依赖,都在网页中详细描述。

会直接用 pip install lxml 来安装。

如果要指定版本需要直接在后面加版本名称:pip install lxml==3.4.2,还会有在Windows 和 Linux 下安装的介绍,所需要的库在  Linux 下安装是没有太大的问题,但在 Windows 下会有较大问题,在编译过程中C语言的库会出现缺失库,版本不对的问题,所以在 Windows 中去写代码,用 Linux 去测试,在 Windows 中测试是不作数的,因为 python 主要是在 Linux 下运行的,可以详细查看网页文档来学习。

CentOS中的libxml2 -devel libxslt-devel  相当于 C 语言中的头文件,需要自行安装头文件

输入并允许以下代码:

from lxml import etree

root=etree. Element('html')

body=etree. Element('body')

root. append(body)

print(etree. tostring(root))

运行结果如下:

=====

在上述代码基础上创建子节点:

from lxml import etree

root=etree. Element('html')

body=etree. Element('body')

root. append(body)

div1 = etree.SubElement(body,’div’)

div2 = etree.SubElement(body,’div’)

print(etree. tostring(root))//也可以加入preet_print打印出来。

还可以通过其他方式创建 HTML,比如  Beautiful Soup  结合 lxml 做一些处理

etree  还提供了2个有用的函数

etype.HTML(text)解析HTML文档,返回根节点

anode. xpath('xpath路径')对节点使用xpath语法

from  lxml import  etree

import requests

url=' https://movie.douban.com/'

ua=“Mozilla/5.8(Windows NT6.1)  Applewebkit /537. 36(KH1ML, like Gecko) Chrome/ss.e. assa.7 Safari/537. 36"

with requests. get(url, headers={'User-agent':ua}) as response;

content=response. text#HTML内容

html=etree.HTML(content)#分析HTML,返回DOM根节点titles—html.xpath("//div[@class="billboard-bd"]//trtd/a/text()")#返回文本列表

for t in titles:#豆瓣电影之本周口碑榜

print(t)

从豆瓣电影中提取“本周口碑榜”

打开豆瓣页面右击鼠标选择并打开审查元素

现需要将审查元素中的东西提取出来,就要进行操作

按下图中 copy 出 XPath 内容,该东西不能使用,因为无法确定下回的元素与内容中的是否一致,所以不可以按下图方式提取。

在 js 中提到过要求 HTML 的 id 唯一,可以通过 id 找到

现在通过用  ChroPath  工具来找到  billboard ,需要对 div 有要求,还需要找到每一行

文字内容:

from lxml import  etree

import requests

urls=[' https://movie.douban.com/']

session=requests. Session()

with session:

for url in urls:

response=session.get(url,headers={'User-agent's"Mozilla/5.0(Windows NT 6.1)  Applewebkit /537. 36(KBTM.like

})

content = response . text

#print(content)

#xpath//div[@class='billboard-bd']//tr/td/a/text()]

html=etree.HTML(content)titles=html.xpath("//div[@class="billboard-bd']//tr/td/a/text()”)

for t in titles:

print(t)

运行后得到结果。

若想获得带有序号的排行榜,则要运行以下代码:

from lxml import  etree

import requests

urls=[' https://movie.douban.com/']

session=requests. Session()

with session:

for url in urls:

response=session.get(url,headers={'User-agent's"Mozilla/5.0(Windows NT 6.1)  Applewebkit /537. 36(KBTM.like

})

content = response . text

#print(content)

#xpath//div[@class='billboard-bd']//tr//text()]

html=etree.HTML(content)titles=html.xpath("//div[@class="billboard-bd']//tr")

for t in titles:

print(t)

print(’-‘*30)

同样,还可以运行以下代码:

from lxml import  etree

import requests

urls=[' https://movie.douban.com/']

session=requests. Session()

with session:

for url in urls:

response=session.get(url,headers={'User-agent's"Mozilla/5.0(Windows NT 6.1)  Applewebkit /537. 36(KBTM.like

})

content = response . text

#print(content)

#xpath//div[@class='billboard-bd']//tr]

html=etree.HTML(content)titles=html.xpath("//div[@class="billboard-bd']//tr//")

for t in titles:

txt=title.xpath(‘.//text()’)

print(‘’.join(map(lambda x:x.strip(),txt)))

print(‘-’*30)

相关文章
|
13天前
|
数据采集 API 数据库
探索Python中的异步编程:从基础到实战
【9月更文挑战第21天】在编程的世界中,效率是金。异步编程作为一种提升程序执行效率的技术,允许多个任务在等待某些操作完成时不阻塞主线程,从而显著提升应用性能。本文将深入探讨Python中异步编程的核心概念、实现方法以及如何在实际项目中的应用。通过具体代码示例,我们不仅理解理论,还将看到这些理论是如何转化为实际可运行的代码。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往更高效编程世界的大门。
32 6
|
9天前
|
数据可视化 数据挖掘 Linux
震撼发布!Python数据分析师必学,Matplotlib与Seaborn数据可视化实战全攻略!
在数据科学领域,数据可视化是连接数据与洞察的桥梁,能让复杂的关系变得直观。本文通过实战案例,介绍Python数据分析师必备的Matplotlib与Seaborn两大可视化工具。首先,通过Matplotlib绘制基本折线图;接着,使用Seaborn绘制统计分布图;最后,结合两者在同一图表中展示数据分布与趋势,帮助你提升数据可视化技能,更好地讲述数据故事。
25 1
|
3天前
|
调度 开发者 UED
探索Python中的异步编程:从基础到实战
【9月更文挑战第30天】在编程的世界里,异步编程是一个强大的概念,它允许程序在等待某些操作完成时继续执行其他任务。本文将深入探讨Python中的异步编程,从理解其基本概念开始,逐步过渡到高级应用。我们将通过具体的代码示例来展示如何在实际项目中实现异步功能,从而提高应用程序的性能和响应性。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
1天前
|
存储 数据处理 开发者
深入浅出:Python编程基础与实战技巧
【9月更文挑战第32天】本文将引导读者从零开始,掌握Python编程语言的核心概念,并通过实际代码示例深入理解。我们将逐步探索变量、数据结构、控制流、函数、类和异常处理等基本知识,并结合实用案例,如数据处理、文件操作和网络请求,提升编程技能。无论您是初学者还是有一定经验的开发者,这篇文章都能帮助您巩固基础,拓展视野。
|
2天前
|
设计模式 开发者 Python
探索Python中的异步编程:从基础到实战
【9月更文挑战第32天】在Python的世界中,异步编程是一种让程序在等待任务完成时不阻塞的技术。本文将通过浅显易懂的方式,带领读者了解异步编程的核心概念、常用库及其在实际项目中的应用。我们将从异步IO的基础知识出发,逐步深入到asyncio库的使用,最后通过一个简易Web服务器的示例,演示如何将理论应用到实践中。文章旨在为初学者提供一个清晰的学习路径,帮助他们掌握Python异步编程的精髓。
|
7天前
|
数据采集 人工智能 程序员
探索Python编程:从基础到实战
【9月更文挑战第27天】在这篇文章中,我们将一起踏上一段激动人心的Python编程之旅。无论你是初学者还是有一定经验的开发者,这里都有适合你的内容。文章将通过浅显易懂的语言带你了解Python的基础语法,并通过实际案例展示如何将这些知识应用于解决现实问题。准备好,我们即将启程!
|
8天前
|
存储 人工智能 数据挖掘
Python编程入门:从基础到实战
【9月更文挑战第26天】 在这篇文章中,我们将一起探索Python编程的奇妙世界。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的信息和技巧。我们将从Python的基本语法开始,然后逐步深入到更复杂的主题,如函数、类和模块。最后,我们将通过一个实际的项目来应用我们所学的知识。让我们一起开始这段Python编程之旅吧!
|
8天前
|
数据采集 人工智能 数据挖掘
Python编程入门:从基础到实战的快速指南
【9月更文挑战第25天】本文旨在为初学者提供一个简明扼要的Python编程入门指南。通过介绍Python的基本概念、语法规则以及实际案例分析,帮助读者迅速掌握Python编程的核心技能。文章将避免使用复杂的专业术语,而是采用通俗易懂的语言和直观的例子来阐述概念,确保内容的可读性和实用性。
|
7天前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
25 2
|
10天前
|
机器学习/深度学习 存储 数据挖掘
Python编程入门:从基础到实战
【9月更文挑战第24天】本教程将引领初学者步入Python编程的奇妙世界。我们将从最基础的概念开始,逐步深入,通过实例和练习,让你掌握这门强大而易学的语言。无论你是编程新手,还是希望扩展技能的开发者,这篇文章都将为你开启一段充满乐趣的编程之旅。
14 2
下一篇
无影云桌面