一、常见响应内容分类

1、结构化响应内容

(1)json字符串

  • 常用解析方式:json、jsonpath

(2)xml字符串

  • xml:可扩展标记语言,更注重传输和存储数据
  • 常用解析方式:re(正则)、lxml(xpath)

2、非结构化响应内容

(1)html字符串

  • html:超文本标记语言,更注重数据的显示
  • 常用解析方式:re(正则)、lxml(xpath)、beautifulsoup(xpath/正则/css选择器)、pyquery(css选择器)

二、jsonpath模块

1、jsonpath方法

  • 适用数据:json字符串(需要先将json字符串转换为json对象,转换方式:ret = json.loads(data)
  • 作用:可以按照key对python字典进行批量数据提取
  • 使用方式ret = jsonpath.jsonpath(data, 'jsonpath语法')
  • 返回数据类型:列表

2、jsonpath常用语法规则

  • $ 取根节点
  • @ 取现行节点
  • .or[] 取子节点
  • .. 匹配任意位置节点
  • * 匹配所有元素节点
  • [] 迭代器标示
  • [,] 迭代器内多选
  • ?() 过滤器
  • () 表达式计算

三、lxml模块

1、xpath方法

  • 适用数据:xml字符串、html字符串(需要先将xml/html字符串转换为Element对象,转换方式:html = lxml.etree.HTML(text)
  1. lxml.etree.HTML(text)可以自动补全标签
  2. lxml.etree.tostring函数可以将Element对象再转换回字符串
  3. 应以lxml.etree.tostring的返回结果作为提取数据的依据
  • 作用:快速的定位HTML\XML 文档中特定元素以及获取节点信息(文本内容、属性值)
  • 使用方式ret = html.xpath('xpath语法')
  • 返回数据类型:列表
  1. 空列表:未定位到任何元素
  2. 由字符串构成的列表:匹配到文本内容或某属性的值
  3. 由Element对象构成的列表:匹配到标签,列表中的Element对象可以继续进行xpath

2、XPath常用语法规则

(1)基础语法

  • / 从根节点选取,或元素和元素之间的过渡
  • // 从当前节点内选取节点
  • . 选取当前节点
  • .. 选取当前节点的父节点
  • @ 选取属性
  • text() 选取文本

(2)节点修饰语法

  • 索引修饰

  • [数值] 通过索引定位

  • [last()-n] 通过索引定位倒数第n+1个元素

  • [position()>n] 通过索引定位第n个元素之后的元素

  • 属性值修饰

  • [@属性名=属性值] 通过属性值定位元素

  • [text()=”文本内容“] 通过文本定位元素

  • 节点值修饰

  • [节点名>n] 通过节点值定位结果为True的元素

  • 包含关系修饰

  • [contains(@属性名,属性值)] 定位包含对应属性名和属性值的元素

  • [contains(text(),"文本内容")] 定位包含对应文本的元素

(3)其他语法

  • * 匹配任意元素节点
  • @* 匹配任意属性节点
  • node() 匹配任意类型节点
  • 语法1|语法2 多个语法匹配节点

四、实战演练

lxml模块应用——百度贴吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import requests
from lxml import etree

class Tieba(object):

def __init__(self,name):
self.url = "https://tieba.baidu.com/f?kw={}".format(name)
# self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36"}
self.headers = {"User-Agent": "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) "}

def get_data(self,url):
response = requests.get(url,headers = self.headers)
return response.content

def parse_data(self,data):
html = etree.HTML(data)

el_list = html.xpath('//*[@id="thread_list"]/li/div/div[2]/div[1]/div[1]/a')

print(el_list)

data_list = []
for el in el_list:
temp = {}
temp['title'] = el.xpath('./text()')[0]
temp['link'] = "https://tieba.baidu.com/" + el.xpath('./@href')[0]
data_list.append(temp)

try:
next_url = "https:" + html.xpath('//a[contains(text(),"下一页")]/@href')[0]
except:
next_url = None

return data_list,next_url

def save_data(self,data_list):
for data in data_list:
print(data)

def run(self):
next_url = self.url
while True:
data = self.get_data(next_url)
data_list, next_url = self.parse_data(data)
self.save_data(data_list)
print(next_url)
if next_url ==None:
break

if __name__ == '__main__':
tieba = Tieba("edg战队")
tieba.run()