X-path解析器

目录

  • 解析库之X-path解析器

  • 实战案例之爬取猪八戒数据

 

X-path解析器

效率很高,使用广泛

 

模拟网页内容

doc = '''
<html>
 <head>
  <base href='http://example.com/' />
  <title id='t1'>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html' a="xxx">Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html' class='li'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
   <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
  </div>
 </body>
</html>
'''
View Code

导入模块生成对象

# 导入xpath所在模块
from lxml import etree

# 将待匹配的文本传入etree生成一个对象
html = etree.HTML(doc)

 

主要功能

所有节点

a = html.xpath('//*')  # 匹配所有的标签

 

指定节点(结果为列表)

a = html.xpath('//head')  # 匹配所有的head标签

 

子节点,子孙节点

a = html.xpath('//div/a')  # 匹配div标签内部所有的儿子a标签

a = html.xpath('//body//a')  # 匹配div标签内容所有的后代a标签

 

 

 父节点

a=html.xpath('//body//a[@href="image1.html"]')  
# 属性查找 获取body内部所有的href=image1.html后代a

a = html.xpath('//body//a[@href="image1.html"]/..')  
# ..表示查找上一级父标签

'''xpath选择器中中括号内部可以放属性也可以放位置数 从1开始'''
a = html.xpath('//body//a[1]') 

 查找父标签另外一种形式

a = html.xpath('//body//a[1]/parent::*')

 

 

文本获取

获取某个标签内的文本

a = html.xpath('//body//a[@href="image1.html"]/text()')

获取body内部所有后代a内部文本(一次性获取不需要循环)

a = html.xpath('//body//a/text()')

 

 属性获取

获取body内部所有后代a标签href属性值

a = html.xpath('//body//a/@href')

获取title标签id属性值

a = html.xpath('//title/@id')

a = html.xpath('//body//a[2]/@href')

 

 

 属性多值匹配

a=html.xpath('//body//a[@class="li"]')  # 写等号就表示等于,不是包含

a标签有多个class类,直接匹配就不可以了,需要用contains
a = html.xpath('//body//a[contains(@class,"li")]/text()') 

 

 多属性匹配

a = html.xpath('//body//a[contains(@class,"li") or @name="items"]')

# 查找body标签内部所有class含有li或者name=items的a标签

 

同理可得

# 查找body标签内部所有class含有li并且name=items的a标签的内部文本
a = html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')

 

 按序选择

取最后一个

a = html.xpath('//a[last()]/@href')

 

 位置小于3的

# 关键字position()  用于定位
a = html.xpath('//a[position()<3]/@href')  

 

 倒数第三个

a = html.xpath('//a[last()-2]/@href')

 

节点轴选择

 获取所有祖先节点

a = html.xpath('//a/ancestor::*')

 获取祖先节点中的div

a = html.xpath('//a/ancestor::div')

查找a标签内部所有的属性值

# attribute:属性值
a = html.xpath('//a[1]/attribute::*')

直接子节点与子孙节点

# child:直接子节点
a = html.xpath('//a[1]/child::*')
# descendant:所有子孙节点
a = html.xpath('//a[6]/descendant::*')

当前节点之后所有节点

# following
a = html.xpath('//a[1]/following::*')
a = html.xpath('//a[1]/following::*[1]/@href')

当前节点之后同级节点

# following-sibling
a = html.xpath('//a[1]/following-sibling::*')
a = html.xpath('//a[1]/following-sibling::a')
a = html.xpath('//a[1]/following-sibling::*[2]/text()')
a = html.xpath('//a[1]/following-sibling::*[2]/@href')

 

X-path爬取猪八戒数据

完整代码

import requests
from bs4 import BeautifulSoup
from lxml import etree
from openpyxl import Workbook

wb = Workbook()
# 构造工作簿
wb1 = wb.create_sheet('猪八戒',0)
# 创建表头
wb1.append(['价格','公司','接单数','详细信息'])

res = requests.get('https://shanghai.zbj.com/search/f/',
                   params={'kw': 'python'}
                   )
x_html = etree.HTML(res.text)
# 查找所有的外部div标签
div_list = x_html.xpath('/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div')  # 利用浏览器自动生成
# 循环获取每一个div标签
for div in div_list:
    price = div.xpath('.//span[@class="price"]/text()')  # 价格
    company_name = div.xpath('./div/div/a[1]/div[1]/p/text()')  # 公司
    order_num = div.xpath('./div/div/a[2]/div[2]/div[1]/span[2]/text()')  # 接单数
    info = div.xpath('./div/div/a[2]/div[2]/div[2]/p/text()')  # 详细信息

    try:
        name = company_name[1].strip('\\n')
    except Exception as f:
        name = ''
    try:
        wb1.append([price[0], name, order_num[0], info[0]])
    except Exception as f:
        continue
# 保存文件
wb.save('猪八戒.xlsx')
View Code

 

posted @ 2021-09-27 23:06  陌若安然  阅读(108)  评论(0)    收藏  举报