b站视频标题的获取(xpath、jsonpath的一个简单应用)

目录

注:该篇文章为本人原创,由于本人学习有限,若有错误或者笔误或者有问题,欢迎大家进行批评指正,谢谢。

1.目的

  在b站大学上,为了更好的写笔记,本人根据学到的Python(即Python入门(黑马)的学习笔记)与爬虫的知识(即Python爬虫的urlib的学习Python爬虫的解析),使用xpath进行解析,获取到了b站视频的标题,具体步骤如下。若要直接阅读最终源代码 ,请直接看最后的一小部分

2.代码的演示

  本次将以获取尚硅谷Python爬虫教程小白零基础速通的视频标题为例进行演示。

  在PyCharm中创建文件"b站视频标题的获取(xpath).py"

  按F12打开检查,点击网络,清空网络中的接口,点击刷新,寻找含有视频标题的接口,将该接口的请求地址复制到PyCharm中。

  如下编程,先确定能获取到网页源码。

python 复制代码
"""
b站视频标题的获取(xpath)
"""
import urllib.request
import gzip
import io

# 1.获取网页源码
# 请求地址
url = 'https://www.bilibili.com/video/BV1Db4y1m7Ho/?p=51&vd_source=ffb19c330efad3ae5d7d43710d936b1f'
# 请求头
headers = {
    'Referer': 'https://dianying.taobao.com/',
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

# 读取响应的内容
content_bytes = response.read()  # 从响应中读取的字节数据
#  响应内容是压缩的,需要解压         将压缩的字节数据解压并解码成UTF-8编码的字符串
content_io = io.BytesIO(content_bytes)  # 创建了一个io.BytesIO对象,用于将字节数据包装成类似文件对象的形式
# 使用gzip.GzipFile来解压缩数据      mode='rb'指定以二进制模式读取
with gzip.GzipFile(fileobj=content_io, mode='rb') as f:
    content = f.read().decode('utf-8')

print(content)  # 测试代码,用于验证是否获取到网页源码

  接着,使用快捷键Ctr+Alt+X打开xpath插件,然后如下图所示寻找到xpath路径,并复制到PyCharm中。

  继续编程,发现按照该路径无法获取到内容。所以将获取到的网页源码保存为html文件,然后在html文件中不断使用搜索快捷键Ctr+F来协助我们找到xpath路径。

python 复制代码
"""
b站视频标题的获取(xpath)
"""
import urllib.request
import gzip
import io
from lxml import etree

# 1.获取网页源码
# 请求地址
url = 'https://www.bilibili.com/video/BV1Db4y1m7Ho/?p=51&vd_source=ffb19c330efad3ae5d7d43710d936b1f'
# 请求头
headers = {
    'Referer': 'https://dianying.taobao.com/',
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

# 读取响应的内容
content_bytes = response.read()  # 从响应中读取的字节数据
#  响应内容是压缩的,需要解压         将压缩的字节数据解压并解码成UTF-8编码的字符串
content_io = io.BytesIO(content_bytes)  # 创建了一个io.BytesIO对象,用于将字节数据包装成类似文件对象的形式
# 使用gzip.GzipFile来解压缩数据      mode='rb'指定以二进制模式读取
with gzip.GzipFile(fileobj=content_io, mode='rb') as f:
    content = f.read().decode('utf-8')

# print(content)  # 测试代码,用于验证是否获取到网页源码

# 将网页源码保存到文件"b站视频标题的获取(xpath).html"中
with open('b站视频标题的获取(xpath).html', 'w', encoding='UTF-8') as fp:
    fp.write(content)

# 2.获取视频标题
# 解析服务器响应的文件  etree.HTML
tree = etree.HTML(content)
# 获取想要的数据
# 失败路径,需要将网页源码导入html文件中,手动找  /html/body/div[2]/div[2]/div[2]/div/div[7]/div[2]/ul/li/a/div/div[1]/span[2]/text()
result = tree.xpath('/html/head[@itemprop="video"]/script[4]/text()')[0]  # 由于tree.xpath返回的是列表,需要使用切片[0]将它取出来
print(result)

  如图,发现将获取的内容就是json数据(本人使用的json解析网站为"https://c.runoob.com/front-end/53/"),只是多了一些东西,具体为"window.**INITIAL_STATE** ="、";(function(){var s;(s=document.currentScript||document.scriptsdocument.scripts.length-1).parentNode.removeChild(s);}());"。

  然后继续编程,将数据处理成json数据,然后根据json数据的层次获取到视频标题。

python 复制代码
"""
b站视频标题的获取(xpath)
"""
import urllib.request
import gzip
import io
from lxml import etree
import json

# 1.获取网页源码
# 请求地址
url = 'https://www.bilibili.com/video/BV1Db4y1m7Ho/?p=51&vd_source=ffb19c330efad3ae5d7d43710d936b1f'
# 请求头
headers = {
    'Referer': 'https://dianying.taobao.com/',
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

# 读取响应的内容
content_bytes = response.read()  # 从响应中读取的字节数据
#  响应内容是压缩的,需要解压         将压缩的字节数据解压并解码成UTF-8编码的字符串
content_io = io.BytesIO(content_bytes)  # 创建了一个io.BytesIO对象,用于将字节数据包装成类似文件对象的形式
# 使用gzip.GzipFile来解压缩数据      mode='rb'指定以二进制模式读取
with gzip.GzipFile(fileobj=content_io, mode='rb') as f:
    content = f.read().decode('utf-8')

# print(content)  # 测试代码,用于验证是否获取到网页源码

# # 将网页源码保存到文件"b站视频标题的获取(xpath).html"中
# with open('b站视频标题的获取(xpath).html', 'w', encoding='UTF-8') as fp:
#     fp.write(content)

# 2.获取视频标题
# 解析服务器响应的文件  etree.HTML
tree = etree.HTML(content)
# 获取想要的数据
# 失败路径,需要将网页源码导入html文件中,手动找  /html/body/div[2]/div[2]/div[2]/div/div[7]/div[2]/ul/li/a/div/div[1]/span[2]/text()
the_data = tree.xpath('/html/head[@itemprop="video"]/script[4]/text()')[0]  # 由于tree.xpath返回的是列表,需要使用切片[0]将它取出来
# print(the_data)  # 测试代码,验证xpath路径是否正确
the_json_data = the_data.split('__=')[1].split(';(function')[0]
# print(the_json_data)  # 测试代码,验证得到的json数据是否正确

# 将字符串json转换为python的字典
data_dict = json.loads(the_json_data)

# 根据json数据的层次结构获取视频的标题
the_temp_data = data_dict['videoData']['pages']
the_name_of_videos = []  # 用于存储视频的标题
for name in the_temp_data:
    the_name_of_videos.append(name['part'])

# 打印b站视频的标题
for name in the_name_of_videos:
    print(name)

  当然,json数据部分可使用jsonpath来解析,代码与运行结果如下。

python 复制代码
"""
b站视频标题的获取(xpath)
"""
import urllib.request
import gzip
import io
from lxml import etree
import json
import jsonpath

# 1.获取网页源码
# 请求地址
url = 'https://www.bilibili.com/video/BV1Db4y1m7Ho/?p=51&vd_source=ffb19c330efad3ae5d7d43710d936b1f'
# 请求头
headers = {
    'Referer': 'https://dianying.taobao.com/',
}
# 请求对象定制
request = urllib.request.Request(url=url, headers=headers)
# 模拟浏览器向服务器发送请求
response = urllib.request.urlopen(request)

# 读取响应的内容
content_bytes = response.read()  # 从响应中读取的字节数据
#  响应内容是压缩的,需要解压         将压缩的字节数据解压并解码成UTF-8编码的字符串
content_io = io.BytesIO(content_bytes)  # 创建了一个io.BytesIO对象,用于将字节数据包装成类似文件对象的形式
# 使用gzip.GzipFile来解压缩数据      mode='rb'指定以二进制模式读取
with gzip.GzipFile(fileobj=content_io, mode='rb') as f:
    content = f.read().decode('utf-8')

# print(content)  # 测试代码,用于验证是否获取到网页源码

# # 将网页源码保存到文件"b站视频标题的获取(xpath).html"中
# with open('b站视频标题的获取(xpath).html', 'w', encoding='UTF-8') as fp:
#     fp.write(content)

# 2.获取视频标题
#(1)处理变成json数据
# 解析服务器响应的文件  etree.HTML
tree = etree.HTML(content)
# 获取想要的数据
# 失败路径,需要将网页源码导入html文件中,手动找  /html/body/div[2]/div[2]/div[2]/div/div[7]/div[2]/ul/li/a/div/div[1]/span[2]/text()
the_data = tree.xpath('/html/head[@itemprop="video"]/script[4]/text()')[0]  # 由于tree.xpath返回的是列表,需要使用切片[0]将它取出来
# print(the_data)  # 测试代码,验证xpath路径是否正确
the_json_data = the_data.split('__=')[1].split(';(function')[0]
# print(the_json_data)  # 测试代码,验证得到的json数据是否正确

# (2)处理json数据,得到视频的标题

# # 法1.使用切片
# # 将字符串json转换为python的字典
# data_dict = json.loads(the_json_data)
#
# # 根据json数据的层次结构获取视频的标题
# the_temp_data = data_dict['videoData']['pages']
# the_name_of_videos = []  # 用于存储视频的标题
# for name in the_temp_data:
#     the_name_of_videos.append(name['part'])

# 法2.使用jsonpath解析
the_name_of_videos=jsonpath.jsonpath(json.loads(the_json_data),'$.videoData.pages[*].part')

# 打印b站视频的标题
for name in the_name_of_videos:
    print(name)

  好了,本次的笔记到此结束,谢谢大家阅读。

相关推荐
不如语冰13 分钟前
AI大模型入门-pytorch-张量2 tensor创建
python
NPE~25 分钟前
[AI]Agent开发——ADK框架使用
人工智能·python·ai·教程·adk·agent开发
矮个史蒂芬26 分钟前
统计verilog .v文件中output 的bit数
python
gwf2161 小时前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
爱吃提升1 小时前
python 分布式爬虫、爬虫合规与综合实战项目
分布式·爬虫·python
审小匠OpenCPAi1 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
元Y亨H2 小时前
Pandas 解析 Excel 导致的内存溢出(MemoryError)
python·excel
金銀銅鐵3 小时前
[Python] 用 turtle 来绘制瑞典国旗
python
Albert Edison3 小时前
【GUI 自动化测试】Pywinauto 常见操作
自动化测试·python·pywinauto
海兰3 小时前
【高速缓存】RedisVL为文本生成嵌入向量实践指南
人工智能·python·机器学习