手刃一个善意的小爬虫(三),使用xpath解析,包括常用处理技巧

安装

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.parseetree.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的方式进行解析。本篇文章还是比较基础的,要想学习更多的知识,加油吧,朋友!

心灵鸡汤: 人生最幸福的事就是一转身,发现你爱着的人也正爱着你,喜欢一个人淡淡的就好,然后轻轻地放在心里,爱一个人浅浅的就好,然后生生世世一直到老。

相关推荐
北京_宏哥2 天前
《最新出炉》系列入门篇-Python+Playwright自动化测试-50-滚动条操作
python·前端框架·测试
sre运维3 天前
运维人员必备的 Mac Zsh 配置技巧
程序员
陈随易3 天前
anime,超强JS动画库和它的盈利模式
前端·后端·程序员
kida_yuan4 天前
【从零开始】6. RAG 应用性能压测工具(番外篇)
后端·llm·测试
陈随易4 天前
秦少卫-耗时5个月收入超过北京工资的超级独立开发者
前端·后端·程序员
陈随易5 天前
wangEditor,从开源、停更到重生
前端·后端·程序员
黑心萝卜三条杠5 天前
【Go语言】深入理解Go语言:并发、内存管理和垃圾回收
google·程序员·go
一只爱撸猫的程序猿5 天前
在SpringBoot 项目简单实现一个 Jar 包加密,防止反编译
spring boot·安全·程序员
TF男孩5 天前
独立开发上班后:我的故事,你的酒,一腔沉默往前走
程序员
肖哥弹架构6 天前
ScheduledThreadPool线程池设计/场景案例/性能调优/场景适配(架构篇)
java·后端·程序员