1.简介

XPath是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历

XPath的安装

Chrome插件XPath Helper

点Chrome浏览器右上角:更多工具-----扩展程序-----谷歌商店--------勾选XPath Helper(需要翻墙)

2.语法详解

#1.选取节点
'''
/ 如果是在最前面,代表从根节点选取,否则选择某节点下的某个节点.只查询子一辈的节点
/html 查询到一个结果
/div 查询到0个结果,因为根节点以下只有一个html子节点
/html/body 查询到1个结果 // 查询所有子孙节点
//head/script
//div . 选取当前节点 .. 选取当前节点的父节点 @ 选取属性
//div[@id] 选择所有带有id属性的div元素
<div id="sidebar" class="sidebar" data-lg-tj-track-code="index_navigation" data-lg-tj-track-type="1"> '''
#2.谓语
'''
谓语是用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。
//body/div[1] body下的第一个div元素
//body/div[last()] body下的最后一个div元素
//body/div[position()<3] body下的位置小于3的元素
//div[@id] div下带id属性的元素
<div id="sidebar" class="sidebar" data-lg-tj-track-code="index_navigation" data-lg-tj-track-type="1">
//input[@id="serverTime"] input下id="serverTime"的元素 模糊匹配
//div[contains(@class,'f1')] div的class属性带有f1的
通配符 *
//body/* body下面所有的元素
//div[@*] 只要有用属性的div元素
//div[@id='footer'] //div 带有id='footer'属性的div下的所有div元素
//div[@class='job_bt'] //dd[@class='job-advantage'] 运算符
//div[@class='job_detail'] and @id='job_tent'
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
也可以百度搜索XPath语法 .//a/text() 当前标签下所有a标签的文字内容
//tr[position()>1 and position()<11] 位置大于1小于11
''' #需要注意的知识点
'''
1./和//的区别:/代表子节点,//代表子孙节点,//用的比较多
2.contains有时候某个属性中包含了多个值,那么使用contains函数
//div[contains(@class,'lg')]
3.谓语中的下标是从1开始的,不是从0开始的
'''

3.要在python中使用xpath,要导入一个库 lxml。

这个是C编写的库,直接pip3 install lxml可能会有一些显示问题,但是不影响使用。

然而程序员特有的代码洁癖让我看见波浪线也不会爽,所以去https://www.lfd.uci.edu/~gohlke/pythonlibs/下载lxml的whl文件进行pip(根据自己的pycharm版本选择)

4.lxml和xpath的结合使用

#  -*-coding:utf8 -*-
from lxml import etree
#1.获取所有tr标签
#2.获取第2个tr标签
#3.获取所有class等于even的标签
#4.获取所有a标签的href属性
#5.获取所有的职位信息(纯文本) parser=etree.HTMLParser(encoding='utf-8')
html=etree.parse('tencent.html',parser=parser) #1.获取所有tr标签
#xpath函数返回的是一个列表
# trs=html.xpath('//tr')
# print(trs)
# for tr in trs:
# print(etree.tostring(tr,encoding='utf-8').decode('utf-8')) #2.获取第2个tr标签 # trs=html.xpath('//tr[2]')[0]
#这样直接找第2个tr标签,实际上会把所有的table下的第二个tr标签找出来,
#为了更精准,可以先把table标签找到,再找这个table下的第二个tr标签
# trs=html.xpath('//table[@class="tablelist"]//tr[1]')[0]
# print(etree.tostring(trs,encoding='utf-8').decode('utf-8')) #3.获取所有class等于even的标签
# trs=html.xpath("//tr[@class='even']")
# for tr in trs:
# print(etree.tostring(tr, encoding='utf-8').decode('utf-8')) #4.获取所有a标签的href属性
# a_list=html.xpath('//a/@href')
# for a in a_list:
# print(a) #5.获取所有的职位信息(纯文本)
trs=html.xpath('//tr[position()>1 and position()<11]')
positions=[]
for tr in trs:
#写了//后,则一定会从整个文档找a标签,会无视前面的tr
# href=tr.xpath('//a')
#写了.后,则获取当前标签下的a标签
href=tr.xpath('.//a/@href')[0]
fullurl='http://hr.tencent.com/'+href
#title文本信息不是td[1]的直接子元素标签,所以要加./td[1]//text()
title=tr.xpath('./td[1]//text()')[0]
category=tr.xpath('./td[2]/text()')[0]
nums=tr.xpath('./td[3]/text()')[0]
address=tr.xpath('./td[4]/text()')[0]
pubtime=tr.xpath('./td[5]/text()')[0]
position={
'url':fullurl,
'title':title,
'category':category,
'nums':nums,
'pubtime':pubtime
}
positions.append(position)
# print(positions) #6.获取纯文本信息还可以用string
# print(html.xpath("string(//tr[1])"))
# trs=html.xpath('//tr')
# for tr in trs:
# print(tr.xpath("string(.)").strip()

5.实战案例,豆瓣电影爬虫

#  -*-coding:utf8 -*-
#1.将目标网站上的页面抓取下来
#2.将抓取下来的数据根据一定的规则进行提取 import requests
from lxml import etree
#1.将目标网站上的页面抓取下来
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36',
'Referer':'https://www.douban.com/',
}
url='https://movie.douban.com/'
response=requests.get(url,headers=headers)
text=response.text
html=etree.HTML(text)
ul=html.xpath("//ul[@class='ui-slide-content']")[0]
# print(etree.tostring(ul,encoding='utf-8').decode('utf-8'))
lis=ul.xpath('./li[@data-title]')
movies=[]
for li in lis:
title=li.xpath('@data-title')[0]
score=li.xpath('@data-rate')[0]
duration=li.xpath('@data-duration')[0]
region=li.xpath('@data-region')[0]
director=li.xpath('@data-director')[0]
actors=li.xpath('@data-actors')[0]
thumbnail=li.xpath('.//img/@src')[0]
movie={
'title':title,
'score':score,
'duration':duration,
'region':region,
'director':director,
'actors':actors,
'thumbnail':thumbnail
}
movies.append(movie)
print(movies)

6.实战案例,电影天堂爬虫

#  -*-coding:utf8 -*-
import requests
from lxml import etree # url='https://www.dytt8.net/html/gndy/dyzz/list_23_1.html'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}
# response=requests.get(url,headers=headers)
# 在电影天堂的网页中,因为编码方式,requests库猜错了,所以response.text出现乱码
# print(response.text)
# text=response.content.decode('gbk')
BaseDomain = 'https://www.dytt8.net' def get_detail_url(url):
response = requests.get(url, headers=headers)
# print(response.encoding)
# 默认解码方式ISO-8859-1
# text=response.content.decode('gbk')
# 在使用gbk解码时遇到了一些问题,第五页里有特殊字符,无法解析
# 估计是因为xpath默认解码方式和gbk不一致导致的,这时可以直接传requests.text
# 因为要获取的是英文字符,不指定解码方式也能得到
html = etree.HTML(response.text)
detail_urls = html.xpath('//table[@class="tbspan"]//a/@href')
detail_urls = list(map(lambda url: BaseDomain + url, detail_urls))
return detail_urls def parse_detail_page(url):
response = requests.get(url, headers=headers)
text = response.content.decode('gbk')
html = etree.HTML(text)
title = html.xpath("//font[@color='#07519a' and position()=1]/text()")
zoomE = html.xpath("//div[@id='Zoom']")[0]
imgs = zoomE.xpath(".//img/@src")
cover = imgs[0]
screenshot = imgs[1]
infos = zoomE.xpath(".//text()")
movie = {
'title': title,
'cover': cover,
'screenshot': screenshot
} def parse_info(info, rule):
return info.replace(rule, '').strip() for index, info in enumerate(infos):
if info.startswith('◎年  代'):
info = parse_info(info, '◎年  代')
movie['year'] = info
elif info.startswith('◎产  地'):
info = parse_info(info, '◎产  地')
movie['country'] = info
elif info.startswith('◎类  别'):
info = parse_info(info, '◎类  别')
movie['category'] = info
elif info.startswith('◎豆瓣评分'):
info = parse_info(info, '◎豆瓣评分')
movie['douban_rating'] = info
elif info.startswith('◎片  长'):
info = parse_info(info, '◎片  长')
movie['duration'] = info
elif info.startswith('◎导  演'):
info = parse_info(info, '◎导  演')
movie['director'] = info
elif info.startswith('◎主  演'):
info = parse_info(info, '◎主  演')
actors = []
actors.append(info)
for x in range(index + 1, len(infos)):
actor = infos[x].strip()
if actor.startswith('◎简  介'):
break
actors.append(actor)
movie['actors'] = actors
elif info.startswith('◎简  介 '):
info=''
for x in range(index+1,len(infos)):
if infos[x].startswith('【下载地址】'):
break
info = info + infos[x].strip()
movie['profile']=info
download_url = html.xpath("//td[@bgcolor='#fdfddf']//a/@href")[0]
movie['download_url']=download_url
return movie def spider():
# url = ['https://www.dytt8.net/html/gndy/dyzz/list_23_%s.html' % i for i in range(1, 8)]
base_url = 'https://www.dytt8.net/html/gndy/dyzz/list_23_{}.html'
movies=[]
for x in range(1, 8):
url = base_url.format(x)
detail_urls = get_detail_url(url)
for detail_url in detail_urls:
movie = parse_detail_page(detail_url)
movies.append(movie)
print(movies)
if __name__ == '__main__':
spider()

7.实战案例,腾讯招聘爬虫

#  -*-coding:utf8 -*-
import requests
from lxml import etree base_url = 'https://hr.tencent.com/position.php?tid=87&start={}0#a'
base_domain = 'https://hr.tencent.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}
positions=[] def parse_url(url):
detail_urls=[]
response=requests.get(url,headers=headers)
html=etree.HTML(response.text)
trs=html.xpath("//table[@class='tablelist']//tr[position()>1 and position()<12]")
for tr in trs:
href=tr.xpath('.//a/@href')[0]
url=base_domain+href
detail_urls.append(url)
return detail_urls def parse_detail_page(url):
response=requests.get(url,headers=headers)
html=etree.HTML(response.text)
zoomE=html.xpath('//table[@class="tablelist textl"]')[0]
title=zoomE.xpath('.//tr[1]/td/text()')[0]
city=zoomE.xpath('.//tr[2]/td[1]/text()')[0]
category=zoomE.xpath('.//tr[2]/td[2]/text()')[0]
nums=zoomE.xpath('.//tr[2]/td[3]/text()')[0]
duty=zoomE.xpath('.//tr[3]//ul//text()')
dutys=''
for i in duty:
dutys=dutys+i.strip()
require=zoomE.xpath('.//tr[4]//ul//text()')
requires=''
for i in require:
requires=requires+i.strip()
position={
'title':title,
'city':city,
'category':category,
'nums':nums,
'dutys':dutys,
'requires':requires
}
return position if __name__ == '__main__':
for i in range(1,10):
url=base_url.format(i)
detail_urls=parse_url(url)
for detail_url in detail_urls:
position=parse_detail_page(detail_url)
positions.append(position)
print(position)

Xpath语法详解的更多相关文章

  1. Velocity魔法堂系列二:VTL语法详解

    一.前言 Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力.而且Velocity被移植到不 ...

  2. Hive笔记--sql语法详解及JavaAPI

    Hive SQL 语法详解:http://blog.csdn.net/hguisu/article/details/7256833Hive SQL 学习笔记(常用):http://blog.sina. ...

  3. Hadoop Hive sql语法详解

    Hadoop Hive sql语法详解 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件 ...

  4. Thymeleaf3语法详解和实战

    Thymeleaf3语法详解 Thymeleaf是Spring boot推荐使用的模版引擎,除此之外常见的还有Freemarker和Jsp.Jsp应该是我们最早接触的模版引擎.而Freemarker工 ...

  5. mysql用户授权、数据库权限管理、sql语法详解

    mysql用户授权.数据库权限管理.sql语法详解 —— NiceCui 某个数据库所有的权限 ALL 后面+ PRIVILEGES SQL 某个数据库 特定的权限SQL mysql 授权语法 SQL ...

  6. Java8的Stream语法详解(转载)

    1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...

  7. [持续交付实践] pipeline使用:语法详解

    一.引言 jenkins pipeline语法的发展如此之快用日新月异来形容也不为过,而目前国内对jenkins pipeline关注的人还非常少,相关的文章更是稀少,唯一看到w3c有篇相关的估计是直 ...

  8. Java 8系列之Stream的基本语法详解

    本文转至:https://blog.csdn.net/io_field/article/details/54971761 Stream系列: Java 8系列之Stream的基本语法详解 Java 8 ...

  9. spring AspectJ切入点语法详解 记录以便查阅

    AspectJ切入点语法详解 6.5.1  Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spri ...

随机推荐

  1. web开篇

    一.内容回顾 1.python基础 2.网络编程 3.并发编程 4.前端 5.数据库(MySQL) 二.今日概要 1.了解Web应用程序的本质 2.Django简介及安装使用 三.今日详细 1.最简单 ...

  2. Python内置函数之classmetho staticmethod

    当对类的静态属性进行修改时(不需要借助于对象就行类静态属性的修改) class Goods: discount = 0.5 def __init__(self,name,price): self.na ...

  3. HTTP Status 500 - java.lang.reflect.InvocationTargetException

    type Exception report message java.lang.reflect.InvocationTargetException description The server enc ...

  4. SQL 安装MySQL

    假设学员的电脑是Windows系统,如Windows7,需要准备以下软件 Microsoft .NET Framework 4.5 Visual C++ Redistributable for Vis ...

  5. Swift 统计项目中所有按钮的点击次数

    class Swizzle: NSObject { override class func load() { UIButton.xxx_swizzleSendAction() } } extensio ...

  6. [转]Windows 安装Kafka

    来源:https://www.cnblogs.com/liuyuhua/p/5329926.html https://www.cnblogs.com/xinlingyoulan/p/6054361.h ...

  7. net core体系-web应用程序-4asp.net core2.0 项目实战(1)-11项目日志解决方案

    本文目录1. Net下日志记录2. NLog的使用    2.1 添加nuget引用NLog.Web.AspNetCore    2.2 配置文件设置    2.3 依赖配置及调用    2.4 日志 ...

  8. P1516 青蛙的约会

    P1516 青蛙的约会x+mt-p1L=y+nt-p2L(m-n)t+L(p2-p1)=y-x令p=p2-p1(m-n)t+Lp=y-x然后套扩欧就完事了 #include<iostream&g ...

  9. EL表达式与标签的使用

  10. css 实现文字提示说明、文字绕图效果

    鼠标放在某个文字上时,展示文字的解释说明 代码: <!DOCTYPE html> <html lang="en"> <head> <met ...