安装
pip install lxml
导包:from lxml import etree
xpath入门练习
准备一段html代码,html文件名称为testhtml.html
练习一:找到ul标签中的所有文本内容
ini
from lxml import etree
tree = etree.parse("testhtml.html")
result = tree.xpath("/html/body/ul/li/a/text()") # text()获取标签中的文本
print(result)
运行结果:
练习二:只找到ul标签中的百度,通过索引找
css
from lxml import etree
tree = etree.parse("testhtml.html")
result = tree.xpath("/html/body/ul/li[1]/a/text()") # xpath的顺序是从1开始数的,[]表示索引
print(result)
运行结果:
练习三:找到ol标签下href属性为dapao的文本值
css
from lxml import etree
tree = etree.parse("testhtml.html")
result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")
print(result)
运行结果:
练习四 :找到ol标签下,a标签中所有的文本值,"./
"表示相对路径查找
ini
from lxml import etree
tree = etree.parse("testhtml.html")
ol_li_list = tree.xpath("/html/body/ol/li")
for li in ol_li_list:
# 从每一个li中提取到文字信息
result = li.xpath("./a/text()") # 从li中继续去寻找,此时是相对路径查找,"./"表示相对路径查找
print(result)
运行结果:
练习五:找到ol标签下,a标签中所有href属性的值
ini
from lxml import etree
tree = etree.parse("testhtml.html")
ol_li_list = tree.xpath("/html/body/ol/li")
for li in ol_li_list:
# 从每一个li中提取到文字信息
result = li.xpath("./a/@href")
print(result)
运行结果:
技巧补充:
在网页中右击打开检查,选中需要查找的元素,直接copy xpath
解释说明:
etree.parse
和etree.HTML
的区别:
1、etree.parse是对标准网页格式数据进行解析用的。etree.parse直接接受一个文档,按照文档结构解析(本地文件)。
2、etree.html是将爬取的网页数据再生成标准网页格式数据,因为有些网页不规范写的时候。etree.html可以解析html文件(服务器上返回的html数据)。
案例实战
爬取猪八戒网站的信息
ini
from lxml import etree
import requests
# 获取网页源代码
url = "https://www.zbj.com/fw/?k=saas"
resp = requests.get(url)
# print(resp.text)
# 解析
html = etree.HTML(resp.text)
# 拿到每一个服务商的div
divs = html.xpath('//*[@id="__layout"]/div/div[3]/div/div[4]/div/div[2]/div[1]/div')
for div in divs:
title = div.xpath('./div/div[3]/div[2]/a/text()')[0] # 采取相对路径一层一层进行查找
price = div.xpath("./div/div[3]/div[1]/span/text()")[0].strip("¥")
com_name = div.xpath('./div/a/div[2]/div[1]/div/text()')[0]
# 将一个项目名称、价格、开发商名字放在一个列表中
result_list = []
result_list.append(title)
result_list.append(price)
result_list.append(com_name)
print(result_list)
运行结果:
常见问题处理技巧
1、处理cookie登录小说网
我们平时在访问一些网站的时候,都需要先进行登录才可以进行一些操作。此时我们在爬虫的时候就必须处理cookie。
需求:爬取17k小说网上我的书架中的内容。
操作步骤:
(1)登录网站,获取cookie;
(2)带着cookie去请求书架的url,从而得到书架上的内容;
ini
import requests
session = requests.session()
data = {
"loginName": "admin",
"password": "123456"
}
# 1、登录
url = "https://passport.17k.com/ck/user/login"
session.post(url, data=data)
# 2、拿书架上的数据
# 刚才的那个session中是有cookie的
# 方式一:使用session
resp = session.get('https://user.17k.com/ck/author/shelf?page=1&appKey=2487679091')
print(resp.json())
# # 方式二:使用requests,将cookie放在headers中
# resp = requests.get('https://user.17k.com/ck/author/shelf?page=1&appKey=2487679091', headers={
# "cookie": "GUID=44fcb076-a528-45d7-9f04-efdf5f2a32e9; BAIDU_SSP_lcr=https://www.baidu.com/link?url=qSYmNVhLaZd-7c2a9n1CN..."})
# print(resp.json())
2、处理防盗链问题爬取梨视频的下载地址
我们首先观察一下梨视频网页的信息
我们将三个链接放在一起做个对比:
(1)原始网页url: www.pearvideo.com/video_17932...
(2)请求结果中的无效地址:"video.pearvideo.com/mp4/short/2...
(3)网页源代码中有效地址:video.pearvideo.com/mp4/short/2... (只有视频播放的时候才出来,不能直接爬取)
经过对比之后,我们发现,srcUrl中一部分数据被替换成systemTime对应的值,想要从请求结果中得到正确的下载地址,需要把srcUrl中1712301257417这一串数字替换成cont-1793221,而1793221正好在原始url中存在。
操作步骤:
(1)通过原始URL拿到contID,也就是1793221这一串数字;
(2)拿到videoStatus接口返回的json,从返回结果里得到srcUrl;
(3)对srcUrl里面的内容进行修整;
(4)得到最终的下载链接进行视频下载;
ini
import requests
# 拉取视频的网址,原始url
url = "https://www.pearvideo.com/video_1793221"
contId = url.split("_")[1]
videoStatusUrl = "https://www.pearvideo.com/videoStatus.jsp?contId=1793221&mrd=0.7426146539763985"
headers = {
# 防盗链,会对当前打开的网页进行溯源,也就是校验了本次请求的上一级,如果不加,运行的时候会报错
# "Referer": "https://www.pearvideo.com/video_1793221"
# 也就是原始URL
"Referer": url
}
resp = requests.get(videoStatusUrl, headers=headers)
dic = resp.json()
systemTime = dic["systemTime"]
srcUrl = dic["videoInfo"]["videos"]["srcUrl"]
srcUrl_result = srcUrl.replace(systemTime, f"cont-{contId}")
print(srcUrl_result)
# 下载视频
with open("a.mp4", mode="wb")as f:
f.write(requests.get(srcUrl_result).content)
运行结果:
控制台中打印出正确的下载链接
文件夹中下载了视频,可以在本地打开
结语
只要我们掌握了如何使用xpath进行定位,就很容易掌握在爬虫的时候使用xpath的方式进行解析。本篇文章还是比较基础的,要想学习更多的知识,加油吧,朋友!
心灵鸡汤: 人生最幸福的事就是一转身,发现你爱着的人也正爱着你,喜欢一个人淡淡的就好,然后轻轻地放在心里,爱一个人浅浅的就好,然后生生世世一直到老。