xpath高级使用
from lxml import etree
# 由于本次要格式化的内容是一个文件,所以用parse,如果是一个html格式的字符串 就用HTML
html = etree.parse('02_xpath.html')
# 可以连接多个 但是每两个之间要用一个管道符来连接
# print(html.xpath('//ol/li[@data="one"]/text() | //ul/li[@code="84"]/text()'))
# 轴的用法:关键字加两个冒号,后面跟上要选取的元素的名字
# child轴:xpath默认使用的轴 作用和斜杠一样
# print(html.xpath('//div[@id="testid"]/ul/li/text()'))
# print(html.xpath('//div[@id="testid"]/child::ul/child::li/child::text()'))
# attribute轴:作用和@一样
# print(html.xpath('//div[@id="testid"]/@data-h'))
# print(html.xpath('//div[attribute::id="testid"]/attribute::data-h'))
# ancestor轴:获取当前节点指定的父节点,如果父节点不是指定的值则不会获取到,如果父节点的父节点也是同一个指定的值,那么也会获取到,更上层也一样
# print(html.xpath('//li[@data="one"]/../../@id')) # 不管父节点是什么,只要满足结构的父节点都能获取到
# print(html.xpath('//li[@data="one"]/ancestor::ol/ancestor::div/@id')) # 必须当li的父节点是li才会获取到
# print(html.xpath('//li[@data="one"]/ancestor::div/@id'))
# ancestor-or-self轴:作用是获取自己本身和父节点,必须自己本身和父节点都是这个指定的值
# print(html.xpath('//div[@id="testid"]/ancestor-or-self::div/@id'))
# following轴:获取当前标签的结束标签之后的所有指定的标签
# print(html.xpath('//div[@id="testid"]/following::div//li[1]/text()'))
# preceding轴:获取当前节点之前的所有节点 是从上往下获取
# print(html.xpath('//div[@id="go"]/preceding::div//li[1]/text()'))
# 作用和两个点一模一样,获取当前节点的父节点
# print(html.xpath('//h2/../@id'))
# print(html.xpath('//h2/parent::div/@id'))
# count统计
# print(html.xpath('count(//li)'))
# print(html.xpath('count(//li[@data])'))
# contains:查看前一个里面有没有包含第二个
# 先根据code来查找所有包含code属性的li,然后看哪一个里面有84
# print(html.xpath('//li[contains(@code,"84")]/text()'))
print(html.xpath('count(//li[not(@data)])'))
bs4使用
from bs4 import BeautifulSoup
import re
案例
html = """
<html>
<head><title id='123' class='story' name='aaa'>story12345</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><span>westos</span><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister1" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
<p>story</P>
"""
# 第一个参数是一个字符串,第二个参数是固定的
# 普通的html对象经过bs构造后,里面每一个标签就变成了tag对象
soup = BeautifulSoup(html,'html.parser')
# print(soup)
# print(soup.title.name)
# print(soup.title.attrs)
# print(soup.title.text)
# print(soup.title.attrs['name'])
# print(soup.title.attrs.get('data'))
#
# title = soup.title
# print(title.name)
# print(soup.a)
# print(soup.a.string) # 只有当标签中没有标签 或者只有一个子标签的话才能获取到内容
# print(soup.a.text)
# print(soup.find_all('a')) # 这个是由获取到的tag标签组成的列表
# print(soup.find_all('a')[1])
# print(soup.find_all(id='123'))
# print(soup.find_all('p',class_='story')) # 因为class是关键字 所以使用的时候后面要加下划线
# print(soup.find_all(string='...')) # 根据文本内容查找 bs4旧版本是text 新版本是string
print(soup.find_all(string=re.compile('.*?little.*?')))
bs4-css选择器
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('02_xpath.html','r',encoding='utf8').read(),'html.parser')
# print(soup)
# print(soup.select('div[data-h="first"] > h2')) # 得到的是一个列表 列表里面是一个个tag对象
# print(soup.select('[data-h="first"] > ol > [data="one"]'))# >子代选择器
# print(soup.select('[data-h="first"] [data="one"]'))#空格 后代选择器
# print(soup.div.ol.select('[data="one"]'))
# print(soup.select('#go li'))
# print(soup.select('#go li')[2]) #返回第三个
print(soup.select('#go li:nth-of-type(3)')) #返回第3个