xpath(lxml 库)
初始化etree对象
From lxml import etree
text = '''
<div>
<ul>
<li class="item-0"><a href=”link1. html”>first item</a><li>
<li class=” item-1”>< a href=”link2.html”> second item</a><li>
<li class=” item-inactive” >< a href="link3.html”>third item</ a></h>
<li class=” item-1 item-0”><a href="link4.html'’>fourth item</a><li>
<li class =” item -0” id=“a”><a href=”link5.html”>fifth item</a>
</ul>
</div>
‘’’
//加载字符串数据或者响应到的数据
Html = etree.HTML(text)
//可以看到该字符串最后一个li标签没有闭合,采用toString()方法修复该标签
Html = Etree.toString(html). 结果是bytes类型
//加载本地文件中的数据进行解析
Html = etree.parse(filepath,etree.HTMLParser())
//获取上述text所有节点
etree.xpath(“//*”)
//获取第一个li节点
Etree.xpath(“/div/ul/li[1]”)
//获取第一个li标签内a标签的文本数据
Etree.xpath(//li[1][@class=“item-0”]/a[@href = “link1.html]/text())
//获取li标签内的子孙标签内的文本数据
Html.xpath(//li[@class=“item-0]//text())
//获取父节点和属性
Html.xpath(//a[@href=“link2.html”]/../@class)
//有时某个节点的属性有多个
Html.xpath(//li[contains(@class,”item1”)]/a/text())
//多属性匹配
Html.xpath(//li[@class=“item-0” and @id=“a”]/a/@href)
//节点轴选择
ancester::选择器——-获取当前选中标签的所有父标签
child::选择器———获取所有选中节点的直接子节点
Attribute::选择器——-获取所有选中节点的属性
Beautiful Soup库
beautiful soup 会自动将输入的文档转为unicode 编码格式,自动将输出的文档转为utf8的格式,无需考虑编码的问题,除非文档自身没有指定编码,指定一个编码格式就ok
(lxml解析器可以解析HTML,xml,解析的速度快,容错能力强)
//导入BeautifulSoup,lxml
from bs4 import BeautifulSoup
Import lxml
//文本数据
html = “”“
<html> <head>< title>The Dormouse ’s story</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=”linkl”>< ! - Elsie … >< la>,
<a href=” http://example.com/lacie ” class=”sister” 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”> ... <Ip>
“”“
//初始化
From bs4 import BeautifulSoup
//此步骤会将html中不标准的标签,进行标准化输出
Soup = BeautifulSoup(html,’lxml)
//将文档以标准缩紧的格式输出
print(soup.prettify())
//节点选择,直接soup对象+节点名称(标签名称)就可以获取该节点,获取该节点的文本数据用string属性
//获取title节点
Soup.title
//获取title节点内的文本数据string属性或者get_text()方法,两者功能完全一致
Soup.title.string
//获取p标签—-此时返回的是文档中第一个p标签内容(只会返回第一个选中的节点)
Soup.p
//调用name属性返回节点的名称(标签名称)
Soup.title.name
//提取选中节点的属性,attrs不携带属性返回选中节点的所有属性值,携带参数返回特定属性值
Soup.p.attrs. //返回的是一个字典,如果一个属性有多个值,那么该键所对应的值是一个列表
Soup.p.attrs[“title”]
//嵌套选择—每个返回结果都是bs4.element.tag类型
//选择head标签内的title标签
Soup.head.title
//contents属性与children属性,descendants
//content与children属性一致,返回选中节点内的所有直接子节点,contents返回的是列表,children返回的是生成器
Soup.body.contents soup.body.children
//descendants将返回选中节点的子孙节点,返回一个生成器
//获取父节点
Soup.p.parent. ——直接父节点
soup.p.parents——返回所有的父节点和祖先节点。返回结果是一个生成器
//获取兄弟节点
Soup.p.next_sibling —- soup.p.previous_sibling 返回的p节点的下一个和上一个兄弟节点
Soup.p.next_siblings ——soup.p.previous_siblings 返回的是所有的下兄弟节点和上兄弟节点
//方法选择器
find_all(name,attrs,recursive,text,**kwargs) 返回需有符合条件的节点,返回结果是一个列表形式
//选择节点名称name
soup.find_all(“p”)
//选择属性,参数类型是字典形式
Soup.find_All(attrs={“id”:”aa”})
//text属性可以传入字符串或者正则表达式-返回节点中的文本符合该条件的文本列表
Soup.find_all(text=re.compile(“text”))
//find()方法与find_all接口一致,只不过find返回第一个匹配成功的节点,后者返回所有匹配的列表
//css选择器
//select()方法返回所有符合css选择器的节点列表—-也可以进行嵌套选择
Soup.select(“#id .class tag”)
//获取属性
Soup.ul[“id”] ———-soup.ul.attrs[“id”]
pyquery
From pyquery import PyQuery as pq
初始化:
Doc = PyQuery(参数):这里的参数可以是字符串,文件名(需要指定参数为filename),url(这里的url代表请求网页的url,原理:先对该url发起请求,将获得响应对象的数据作为字符串参数参与初始化
例如:PyQuery(url) 相当于 PyQuery(requests.get(url).text)
选择器的使用:
例如:doc(’#contain .abs p’) 代表选择id为contain下class为abs下的p标签。
查找子节点时需要用到find方法,传入的参数时css选择器(范围时子孙节点)
例如 :ul = doc(‘.ul’)
li = ul.find(“li”)
代表先选中calss为ul的标签,在获取其下的li标签
查找子节点的时候可以使用children方法(范围是子节点)
例如:item.children() 返回item的所有子节点,
Item.children(“#a”) 返回item中id为a的子节点
查找父节点方法parent (只会返回直接点父节点,不会返回祖先节点)
例如:parent = item.parent() 返回item的父节点
查找祖先节点parents
例如:item.parents() 返回父节点和所有的祖先节点
item.parents(“#a”) 返回id为a的祖先节点
查找兄弟节点siblings方法
例如:item.siblings()返回item 的所有兄弟节点
item.siblings(“#a”) 返回item兄弟节点中id为a 的兄弟节点
遍历:在调用相关方法后可能得到一个节点或多个节点,一个节点可以对其直接打印或转为字符串,但多个节点需要用items()方法将其转为生成器进行遍历
获取节点的属性attr()方法
例如 item.attr(“href) 或者 item.attr.href 效果相同,当item是一个节点时,必然返回相应的属性值,但是如果item为多个节点,则只会返回第一个节点的属性,如果想要返回所有节点的属性,可以采用上述的遍历的方法
获取节点的文本值和html文本
例如 item.text(), item.html() ,前者回返回当前节点的所有文本数据,在item为多个节点时同样返回每个节点的文本数据,每个节点之间的文本数据用空格分开,但html方法,在节点有一个的时候返回的是当前节点内的html文本,但在多个节点时只会返回第一个节点内的html文本,所以在有多个节点时需要用到遍历的方法
修改节点的属性
例如:addClass 为当前节点添加一个class,removeClass 为当前节点移除class
Attr()方法传入一个参数时获取该属性,传入两个参数时添加属性,text()携带参数代表添加文本数据到当前节点,html()携带参数代表添加html文本到当前节点。
remove()方法移除选中的节点,