linRichielinRichie
前端
Python
Linux
ChatGPT
  • B 站
  • 500px
前端
Python
Linux
ChatGPT
  • B 站
  • 500px
    • Python学习指南
  • 快速开始

    • Python: 输入与输出 (I/O)
    • Python: 异常处理 try-except
    • Python: List深入概述
    • Python: 面向对象编程(OOP)
  • Python 语法库函数

    • 语法库目录
    • 库

      • library目录
      • argparse:解析命令行参数
      • difflib:比较序列并生成差异信息
      • dnspython: DNS处理库
      • IPy:IP地址处理库
      • logging:记录和管理日志信息
      • os:访问和操作操作系统
      • psutil:系统性能信息库
      • re:正则表达式库
      • smtplib:邮件发送库
    • 函数

      • function目录
      • any() 函数
      • input 函数
      • lambda 和 map 函数
      • reversed()函数
      • zip()函数
    • 语句

      • statement目录
      • import 语句
      • Try/Exception 异常
    • 概念

      • concept目录
      • 深拷贝与浅拷贝
      • 列表、字典与元组
      • 文件读写
      • IO: 输入与输出
      • 逻辑判断与条件语句
      • OOP 面向对象:class
      • OOP: 面向对象编程
  • SQLAlchemy

    • 获取insert或者update的id
  • Pandas

    • Pandas目录
    • Pandas:基础操作
    • Pandas:数据处理与转换
    • Pandas: 数据写入 excel 表格
  • Python前端框架

    • Flask

      • 1. Flask简介
      • 2. Flask程序基本结构
      • 3. Flask请求-响应循环
      • 4. flask案例: 框架网页查询IP
      • Python: Flask中的GitHub OAuth
    • Django

      • chapter-01:Django框架认识

        • 1.1 Django的产生背景
        • 1.2 MTV设计模式
        • 1.3 Django 主要功能模块
      • chapter-02:开发环境配置

        • 2.1 Python的安装与配置
        • 2.2 虚拟环境安装与配置
        • 2.3 Django安装与配置
        • 2.4 MySQL安装配置
      • chapter-03:项目框架搭建

        • 3.1 Django管理工具-创建项目骨架
        • 3.2 修改项目的默认配置
        • 3.3 初始化项目环境
      • chapter-04:ORM应用与原理剖析

        • 4.1 构建POST应用需要的数据集
        • 4.2 Model相关的概念和使用方法
        • 4.3 Model的查询操作API
        • 4.4 ORM实现原理
      • chapter-05:Django管理后台

        • 5.1 将Model注册到管理后台
        • 5.2 管理后台实现原理
      • chapter-06:视图

        • 6.1 视图基础
        • 6.2 视图的高级特性和快捷方法
        • 6.3 基于类的通用视图
      • chapter-07:模板系统

        • 7.1 模板系统基础
        • 7.2 模板语言
      • chapter-08:表单系统

        • 8.2 使用表单系统实现表单: ModelForm
      • chapter-09:用户认证系统

        • 9.1 用户与身份认证
        • 9.2 权限管理
        • 9.3 用户认证系统应用
      • chapter-10:Django路由系统

        • 10.1 路由系统基础
      • chapter-11:Django中间件

        • 11.1 中间件基础
  • Python例子

    • Python: Linux的Shell命令
    • Python: PEP8自动格式化代码
    • Python: pip操作
    • Python: 业务服务监控
    • Python: 从文件逐行读取数据
    • 将链表转换为字符串
    • Python: 检查URL是否能正常访问
    • Python: 爬取网易云音乐
    • Python: 读取目录下的所有内容
    • 案例研究:文本统计
  • Python爬虫

    • 数据解析工具:Xpath
  • 算法题

    • 02:两数相加
    • 09:回文数
    • 13:罗马数值转换为整数
    • 14:最长公共前缀

数据解析工具:Xpath

  • Xpath介绍
  • Xpath安装
  • Xpath解析原理
  • Xpath使用方法
    • 3个特殊符号
    • 常见路径表达式
    • 举例
    • Xpath运算符
  • HTML元素
    • 常见属性
    • HTML标题
  • 原数据
    • 获取单个标签内容
    • 获取标签内的多个内容
    • 属性定位
    • 索引定位
    • 获取文本内容
    • 直系和非直系理解
    • 取属性内容
    • 总结
  • 实战
    • 网页数据分析
    • 获取网页源码
    • 获取信息

搬运:知乎【@皮大大】

之前爬虫解析数据的时候,自己几乎都是用正则表达式。正则解析数据很强大,但是表达式写起来很麻烦,速度相对较慢。本文介绍的是如何快速入门一种数据解析工具:Xpath。

c319590f977a1147789985b423df3485

Xpath介绍

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

XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

  • Xpath是一种查询语言
  • 在XML(Extensible Markup Language)和HTML的树状结构中寻找节点
  • XPATH是一种根据‘地址’来‘寻找人’的语言

快速入门网站:https://www.w3schools.com/xml/default.asp

Xpath安装

MacOS中安装非常的简单:

Linux中的安装以Ubuntu为例:

sudo apt-get install python-lxml

Windows中的安装请自行百度,肯定会有教程的,就是过程相对会比较麻烦些。

如何检验安装是否成功?命令行中import lxml没有报错,即表示安装成功!

d057b57f8a7b1dd26d2343f5e14418a3

Xpath解析原理

  • 实例化一个etree解析对象,且需要将解析的页面源码数据加载到对象中
  • 调用xpath中的xpath解析方法结合着xpath表达式实现标签的定位和内容的捕获

如何实例化etree对象?

  1. 将本地的html文档中的源码数据加载到etree对象中:etree.parse(filePath)
  2. 将互联网上获取的源码数据加载到该对象中:etree.HTML('page_text'),其中page_text指的就是我们获取到的源码内容

Xpath使用方法

3个特殊符号

  • /:表示从根节点开始解析,并且是单个层级,逐步定位
  • //:表示多个层级,可以跳过其中的部分层级;也表示从任意位置开始定位
  • .:一个点表示当前的节点

常见路径表达式

下面是常见的Xpath路径表达式:

c992c549ef10134d1697df626a38c74e

举例

3aa9ceb87da5efd69dc688197afd3891

Xpath运算符

在Xpath表达式式中是直接支持运算符的:

c1fb8a5c1c9485f36b748d438605f117

HTML元素

HTML 元素指的是从开始标签(start tag)到结束标签(end tag)的所有代码。基本语法:

  • HTML 元素以_开始标签_起始;HTML 元素以结束标签终止
  • 元素的内容是开始标签与结束标签之间的内容
  • 某些 HTML 元素具有空内容(empty content)
  • 空元素在开始标签中进行关闭(以开始标签的结束而结束)
  • 大多数 HTML 元素可拥有属性;属性推荐使用小写

关于空元素的使用:在开始标签中添加斜杠,比如<br />,是关闭空元素的正确方法,HTML、XHTML 和 XML 都接受这种方式。

常见属性

441ddd595e28e6dcea360e003f468e08

HTML标题

HTML中标题共有6级。

标题(Heading)是通过 <h1> - <h6> 等标签进行定义的。

<h1> 定义最大的标题,<h6> 定义最小的标题。

原数据

使用Xpath解析数据之前,我们需要先导入库,同时实例化一个etree对象:

# 导入库 
from lxml import etree 
# 实例化解析对象 
tree = etree.parse("test.html") tree

下面是待解析的原数据test.html:

<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>古代诗人及作品</title>
    </head>
    <body>
        <div>
            <p>诗人姓名</p>
        </div>
        <div class="name">
            <p>李白</p>
            <p>白居易</p>
            <p>李清照</p>
            <p>杜甫</p>
            <p>王安石</p>
            <a href="http://wwww.tang.com" title="李世民" target="_self">
                <span> this is span </span>
                古代诗人写的诗词真的非常棒
            </a>
            <a href="" class="du">床前明月光,疑是地上霜</a>
            <img src="http://www.baidu.com/tang.jpg" alt="" />
        </div>
        <div class="tang">
            <ul>
                <li><a href="http://www.baidu.com" title="百度">朝辞白帝彩云间,千里江陵一日还</a></li>
                <li><a href="http://www.sougou.com" title="搜狗">清明时节雨纷纷,路上行人欲断魂</a></li>
                <li><a href="http://www.360.com" alt="360">秦时明月汉时关,万里长征人未还</a></li>
                <li><a href="http://www.sina.com" title="必应">君子赠人以言,庶人赠人以财</a></li>
                <li><b>苏轼</b></li>
                <li><i>苏洵</i></li>
                <li><a href="http://www.google.cn" id="谷歌">欢迎使用谷歌浏览器</a></li>
            </ul>
        </div>
    </body>
</html>

8709005f1f4116460e672920cde1f08c_b

获取单个标签内容

比如想获取title标签中的内容:古代诗人及作品

3f0a44ec2c3631a3f65398182b451b15_b

title = tree.xpath("/html/head/title") title

6cecec3c9f7e919c9aca14190506a09b_b

通过上面的结果发现:每个Xpath解析的结果都是一个列表

如果想取得标签中的文本内容,使用text():

# 从列表中提取相应内容 
title = tree.xpath("/html/head/title/text()")[0] 
# 索引0表示取得第一个元素值 title

a4febe2d16da28214bbdf1b00f5229d7

获取标签内的多个内容

比如我们想获取div标签的内容,原数据中有3对div标签,结果是列表中含有3个元素:

f8d673615de2a6c363ac883ef42a1207

1、使用单斜线/:表示根节点html开始定位,表示的是一个层级

36da2a9c24d1f56aa8546ce3171814f1_b

2、中间使用双斜线//:表示跳过中间的层级,表示的是多个层级

bbd6161e75bf25fb9706397037be19c0_b

3、开头部位使用双斜线//:表示从任意位置开始

85d7550b9bdb911e19775871b3b2f28e_b

属性定位

使用属性定位的时候直接在标签后面跟上[@属性名="属性值"]:

952fae118055e689512d6ebb727251cd_b

name = tree.xpath('//div[@class="name"]') # 定位class属性,值为name name

f7448a83b813a7845c887e4df8f431be_b

索引定位

Xpath中索引是从1开始,和python中的索引从0开始是不同的。比如想定位div标签下class属性(值为name)下的全部p标签:5对p标签,结果应该是5个元素

67adc2bfff0b9a9c8099ce6e8fc232ac_b

# 获取全部数据
index = tree.xpath('//div[@class="name"]/p') 
index

5db9972fc64921050bea09abfc43112a_b

如果我们想获取其中的第3个p标签:

# 获取单个指定数据:索引从1开始 
index = tree.xpath('//div[@class="name"]/p[3]') # 索引从1开始 index

2aff37157f836f4245c51a555742d07e_b

获取文本内容

第一种方法:text()方法

1、获取具体某个标签下面的元素:

# 1、/:单个层级 
class_text = tree.xpath('//div[@class="tang"]/ul/li/b/text()')
class_text 
# 2、//:多个层级 
class_text = tree.xpath('//div[@class="tang"]//b/text()') 
class_text

3420b22bb29235273619950514c20e68_b

2、某个标签下面的多个内容

9f2d8f8e50826c53c8cc922f1d659fd8_b

比如想获取p标签下面的全部内容:

# 获取全部数据 
p_text = tree.xpath('//div[@class="name"]/p/text()')
p_text

6c573bef16fa701a80a3aee610e84e42_b

比如想获取第3个p标签下面的内容:

# 获取第3个标签内容 
p_text = tree.xpath('//div[@class="name"]/p[3]/text()') 
p_text

fb00e2e74cf4f50f819f3540cfaebebe_b

如果是先获取p标签中的全部内容,结果是列表,再使用python索引获取,注意索引为2:

67cc1ef17148f75fdda5704c401cfe62_b

非标签直系内容的获取:

02927425f2c61753567bbbb6dd4b0f01_b

标签直系内容的获取:结果为空,直系的li标签中没有任何内容

2dc3fafb04a298e656e5adff50871379_b

如果想获取li标签的全部内容,可以将下面的a、b、i标签合并起来,使用竖线|

52582baa74556994d9509a77497f70a0_b

# 同时获取li标签下面a/b/i标签的内容,相当于是li标签全部的内容 
abi_text = tree.xpath('//div[@class="tang"]//li/a/text() | //div[@class="tang"]//li/b/text() | //div[@class="tang"]//li/i/text()') 
abi_text

91a50e72c6116ded300ced41feecce1f_b

直系和非直系理解

4d7fa74561b393a373e92df35c64b57e_b

取属性内容

如果想获取属性的值,在最后的表达式中加上:@+属性名,即可取出相应属性的值

1、获取单个属性的值

6dc7c5c1485586b8c99cc52ad64e54c2_b

07d2ec70b990a26f6c0feffe78cced57_b

2、获取属性的多个值

17e28cdff77de933130469cb1634e712_b

3c09e1d22ddd4a8d1d4a36f03e61dc1a_b

总结

在这里对Xpath的使用总结下:

  • //:表示获取标签非直系内容,有跨越层级
  • /:表示只获取标签的直系内容,不跨越层级
  • 如果索引是在Xpath表达式中,索引从1开始;如果从Xpath表达式中获取到列表数据后,再使用python索引取数,索引从0开始

实战

利用XPATH来爬取小说网站上古龙的全部小说名称(name)和URL地址(url),古龙简介:

本名熊耀华,江西人;台湾淡江英专(即淡江大学前身)毕业(一说肄业)。少年时期便嗜读古今武侠小说及西洋文学作品,一般多以为他是受到吉川英治、大小仲马、海明威、杰克伦敦、史坦贝克小说乃至尼采、沙特等西洋哲学的影响启迪。 (古龙自己也说过“我喜欢从近代日本及西洋小说‘偷招’。”) 故能日新又新,後来居上,且别开武侠小说新境界。

网页数据分析

爬取的信息在这个网站上:https://www.kanunu8.com/zj/10867.html

f059f1dd403ef1d6c6c637483cfaaf33_b

当我们点击具体某个小说,比如“绝代双骄”就可以进去该小说的具体信息中:

18696e98d658d2bd6e5dea5800cafac5_b

通过查看网页的源码,我们发现名称和URL地址全部在下面的标签中:

88b2cf6e6f52ee2ddd3f2d5976a6415e_b

每个tr标签下面有3个td标签,代表3个小说,一个td包含地址和名称

e675447e620c8a1233713fb97bab1b30_b

获取网页源码

发送网页请求获取到源码

import requests from lxml import etree import pandas as pd url = 'https://www.kanunu8.com/zj/10867.html' headers = {'user-agent': '请求头'} response = requests.get(url = url,headers = headers) result = response.content.decode('gbk') # 该网页需要通过gbk编码来解析数据 result

b4a83e0aea4c49ee28566ce32884fd6e_b

获取信息

1、获取每个小说的专属链接地址

tree = etree.HTML(result) href_list = tree.xpath('//tbody/tr//a/@href') # 指定属性的信息 href_list[:5]

8dc1cd3aad00d900f4e8541c357fe867_b

2、获取每个小说的名称

name_list = tree.xpath('//tbody/tr//a/text()') # 指定标签下面的全部内容 
name_list[:5]

f7f2726f9c6dd23f1d11251a66b2b95c_b

3、生成数据帧DataFrame

# 生成古龙小说的地址和名称 
gulong = pd.DataFrame({ "name":name_list, "url":href_list }) 
gulong

e34586ed311e8b6ef57b4d4507aab3c8_b

4、完善URL地址

实际上每个小说的URL地址是有一个前缀的,比如绝代双骄的完整地址:https://www.kanunu8.com/book/4573/

gulong['url'] = 'https://www.kanunu8.com/book' + gulong['url'] # 加上公共前缀 
gulong 

# 导出为excel文件 
gulong.to_excel("gulong.xlsx",index=False)

afd23e6b81945e71a3528eee656f9d2f_b

最近更新时间: