文章目录
- Xpath入门到精通与案例详解
- 一、Xpath介绍
- 1、结点的关系
- 2、为什么学习Xpath
- 3、Xpath原理
- 二、Xpath工具使用
- xpath入门测试一
- xpath入门测试二
- 三、Xpath语句介绍
- 位置定位
- 四、lxml模块
- lxml介绍
- lxml下载
- lxml的使用
- 五、豆瓣--案例详解
- 豆瓣案例--网址与需求
- 页面分析
- 翻页
- 代码演示
提示:以下是本篇文章正文内容,下面案例可供参考
一、Xpath介绍● XPath(XML Path Language)是一种XML的查询语言,他能在XML树状结构中寻找节点。XPath 用于在 XML 文档中通过元素和属性进行导航
● xml是一种标记语法的文本格式,xpath可以方便的定位xml中的元素和其中的属性值。lxml是python中的一个第三方模块,它包含了将html文本转成xml对象,和对对象执行xpath的功能
xml_content = '''''' Harry Potter JK.Rowing2005 29
● 父(Parent) book元素是title、author、year、price元素的父
● 子(Children) title、author、year、price都是book元素的子
● 同胞(Sibling) title、author、year、price都是同胞
● 先辈(Ancestor) title元素的先辈是 book元素和bookstore元素
正则比较复杂,根据不同网页结构 灵活的选择解析方法
3、Xpath原理X path根据路径找到数据的技术
xml path language
html是xml的一个子集
根据元素和属性进行导航
from lxml import etree
xml_content = '''
Harry Potter
from lxml import etree
# 网页源代码
html = '''
test2
经典老歌
经典老歌列表
- 沧海一声笑
- 往事随风
- 光辉岁月
- 记事本
- 但愿人长久
| 符号 | 作用 |
|---|---|
| / | 从根节点选取 |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
| . | 选取当前节点 |
| … | 选取当前节点的父节点 |
| @ | 选取属性 |
| * | 可用匹配任意节点,匹配当前节点下的任意节点,简单理解为通配符 |
| text() | 获取当前选取节点的数据 |
tree.xpath('')[列表下标]#通过列表下标定位
tree.xpath('/html/body/li[节点下标]')#通过节点下标定位
tree.xpath('/html/body/li[last()]')#选取最后一个
tree.xpath('/html/body/li[last()-1]')#选取倒数第二个
tree.xpath('/html/body/li/a[属性名=""]')#通过属性值筛选数据
四、lxml模块
lxml介绍
lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取HTML/XML数据利用etree.HTML,将字符串转化为Element对象
lxml python 官方文档:http://lxml.de/index.html
可使用 pip 安装:pip install lxml
lxml 可以⾃动修正 html 代码
第三方模块 需要安装
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simplelxml的使用
使用:
1、代码导入etree: from lxml import etree
2、发请求 获得相应 拿到网页源代码(html)
3、tree = etree.HTML(html)
4、找数据:title = tree.xpath(xxxxx)
5、保存数据(csv)
五、豆瓣–案例详解 豆瓣案例–网址与需求https://movie.douban.com/top250
页面分析爬取需求:详情页的url、图片的url、标题、评分、评价人数、引言
一部影片的数据是放在一个li节点下面
这些所有li节点都是放在ol[class=“grid_view”]节点下面
详情页的url:先找到的div节点下面的一个a节点 里面有一个href属性 放的是详情页的url
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[1]/a
标题,图片的url:先找到的div节点下面的一个a节点,在a节点下面有一个img节点 里面能通过alt属性获得标题,src可以获得img的url
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[1]/a/img
评分:是的span节点里面的文本
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[2]
评价人数:的div节点 再往下找到最后一个span节点 里面有评价人数
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[4]
引言:通过的span节点获取引言
翻页/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/p[2]/span
翻页:
https://movie.douban.com/top250?start=0&filter= 第一页
https://movie.douban.com/top250?start=25&filter= 第二页
https://movie.douban.com/top250?start=50&filter= 第三页
代码演示动态更替start能够实现翻页 增长基数为25
import time
from lxml import etree
import csv
import requests
# # 目标url
# url = "https://movie.douban.com/top250"
# # 请求头
# header = {
# "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
# "Chrome/97.0.4692.99 Safari/537.36 "
# }
"""
页面分析:
一部影片的数据是放在一个li节点下面
这些所有li节点都是放在ol节点下面grid_view
详情页的url:先找到的div节点下面的一个a节点 里面有一个href属性 放的是详情页的url
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[1]/a
标题,图片的url:先找到的div节点下面的一个a节点,在a节点下面有一个img节点 里面能通过alt属性获得标题,src可以获得img的url
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[1]/a/img
评分:是的span节点里面的文本
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[2]
评价人数:的div节点 再往下找到最后一个span节点 里面有评价人数
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[4]
引言:通过的span节点获取引言
/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[2]/p[2]/span
"""
"""
翻页:
https://movie.douban.com/top250?start=0&filter= 第一页
https://movie.douban.com/top250?start=25&filter= 第二页
https://movie.douban.com/top250?start=50&filter= 第三页
动态更替start能够实现翻页 增长基数为25
"""
class DoubanMovie():
def __init__(self):
header = ['排名', "详情页url", "图片url", "标题", "评分", "评价人数", "引言"]
self.file_obj = open('movie.csv', 'w', encoding='utf-8', newline='')
# 1、创建csv对象
self.Dictwrite = csv.DictWriter(self.file_obj, header)
# 2、写入表头
self.Dictwrite.writeheader()
def get_html(self, url, header):
res_obj = requests.get(url, headers=header)
html = res_obj.text
# print(html)
return html
def parse_data(self, html):
# 把网页源码加载成element对象 赋值给tree
tree = etree.HTML(html)
li_list = tree.xpath('//ol[@]/li')
for li in li_list:
item = {}
# print(li)
# 基于已经找到的li节点继续往下
item['排名'] = li.xpath('.//div[@]/em/text()')[0]
item['详情页url'] = li.xpath('.//div[@]/a/@href')[0]
item['图片url'] = li.xpath('.//div[@]/a/img/@src')[0]
item['标题'] = li.xpath('.//div[@]/a/img/@alt')[0]
item['评分'] = li.xpath('.//span[@]/text()')[0]
item['评价人数'] = li.xpath('.//div[@]/span/text()')[-1]
item['引言'] = li.xpath('.//span[@]/text()')[0]
print(item)
try:
item['inq'] = li.xpath('.//span[@]/text()')[0]
except:
item['inq'] = ''
print(item)
self.save_data(item)
def save_data(self, item):
self.Dictwrite.writerow(item)
def main(self):
# 目标url
url = "https://movie.douban.com/top250?start=0&filter="
# 请求头
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/97.0.4692.99 Safari/537.36 "
}
# 处理翻页
for i in range(5):
# 1、i=0
# 2、i=1
print("正在爬取第{}页数据".format(i + 1))
next_url = url.format(i * 25)
html = self.get_html(next_url, header)
self.parse_data(html)
time.sleep(2)
self.file_obj.close()
if __name__ == '__main__':
douban = DoubanMovie()
douban.main()



