【python爬虫】xpath使用与学习,python xpath解析

xpath:

通用性最强,最便捷高效 xpath解析原理

  1. 实例化一个etree对象,且需要将被解析的页面加载到该对象中
  2. 调用etree对象中的xpath方法结合着xpath表达式来实现标签的定位和内容的捕获

xpath使用(from lxml import etree) ​ 1. 将本地的html文档中的源码数据加载到etree对象中 ​ etree.parse(file)

  1. 将网络中获取的源码数据加载到该对象 tree= etree.HTML(page_text)
  • tree.xpath(‘xpath表达式’)
1
2
3
4
# 实例化一个xpath对象
from lxml import etree
tree = etree.parse('./test.html')
tree.xpath('/html/head/title')
xpath路径学习

绝对路径起始于正斜杠( / ),而相对路径不会这样。

  • /:下一层级 /html/body/div
  • //: 多个层级 /html//div或者//div(表示任意位置开始定位)
  • . :当前层级
  • .. :当前节点的父节点
  • nodeName 选取该节点的所有子节点
  • @:获取属性 可以使用 + - * div(除法) mod or and >= <= = !=
  • //div[@class=”song”] 属性定位 //tagName[@attrName=”attrValue”]

运算符

描述

实例

返回值

|

计算两个节点集

//book | //cd

返回所有拥有 book 和 cd 元素的节点集

+

加法

6 + 4

10

-

减法

6 - 4

2

*

乘法

6 * 4

24

div

除法

8 div 4

2

=

等于

price=9.80

如果 price 是 9.80,则返回 true。如果 price 是 9.90,则返回 false。

!=

不等于

price!=9.80

如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。

<

小于

price<9.80

如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。

<=

小于或等于

price<=9.80

如果 price 是 9.00,则返回 true。如果 price 是 9.90,则返回 false。

>

大于

price>9.80

如果 price 是 9.90,则返回 true。如果 price 是 9.80,则返回 false。

>=

大于或等于

price>=9.80

如果 price 是 9.90,则返回 true。如果 price 是 9.70,则返回 false。

or

price=9.80 or price=9.70

如果 price 是 9.80,则返回 true。如果 price 是 9.50,则返回 false。

and

price>9.00 and price<9.90

如果 price 是 9.80,则返回 true。如果 price 是 8.50,则返回 false。

mod

计算除法的余数

5 mod 2

1

  • 索引定位(记住这里的索引是从1开始的,而非0) //div[@class=”song”]/p[3]
xpath取文本
  • /text() 获取直系的字符串 //div[@class=”song”]/p[3]/text()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from lxml import etree
    import requests

    if __name__ == "__main__":
    headers = {
    "User-Agent": r"Mozilla/5.0 (Windows NT"
    r" 10.0; Win64; x64) App"
    r"leWebKit/537.36 (KHTML, l"
    r"ike Gecko) Chrome/84.0.414"
    r"7.135 Safari/537.36 Edg/84.0.522.63"
    }
    # 实例化一个xpath对象
    tree = etree.parse('baidu.html')
    divs = tree.xpath('//div[@class="song"]/p[3]/text()')
    print(divs)
  • //text() 获取所有的子系字符串(包括非直系) //div[@class=”song”]//text()
xpath取属性

/@attr //div[@class=”song”]//img/@src

xpath多项并立

使用 符号 //div[@class=”test”]/ul/li div[@class=”test1”/p]

1
2
3
4
5
6
7
8
9
10
11
<div class="test demo"></div>










此时可以使用 xpath(‘//div[contains(@class,”a”)]‘) 它会取到包含a的值 如果是多项则有 xpath(‘//div[contains(@class,”a”) and contains(@class,”b”)]

1
'//div[contains(@class,"main_list") and contains(@id,"container")]'

中文乱码问题

哪种有效就使用哪种

方案一、

响应编码修改为utf-8

1
2
3
4
5
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36 Edg/84.0.522.63'
}
response = requests.get(url='http://pic.netbian.com/4kdongman/', headers=headers)
response.encoding='utf-8'
方案二、

编码出问题位置,进行一种常见的通用解码修改赋值的方式进行修改 此处乱码为gbk编码,则为:

1
file_name = file_name.encode('iso-8859-1').decode('gbk')

验证码