当前位置: 首页 > news >正文

python网络爬虫开发实战之网页数据的解析提取

目录

1 XPath的使用

1.1 XPath概览

1.2  XPath常用规则

1.3 准备工作

1.4 实例引入

1.5 所有节点

1.6 节点

1.7 父节点

1.8 属性匹配

1.9 文本获取

1.10 属性获取

1.11 属性多值匹配

1.12 多属性匹配

1.13 按序选择

1.14 节点轴选择

2 Beautiful Soup

2.1 简介

2.2 解析器

2.3 准备工作

2.4 基本使用

2.5 节点选择器

2.6 提取信息

2.6.1 获取名称

2.6.2 获取属性

2.6.3 获取内容

2.6.4 嵌套选择

2.7 关联选择

2.7.1 子节点和子孙节点

2.7.2 父节点和祖先节点

2.7.3 兄弟节点

2.7.4 提取信息

2.8 方法选择器

2.8.1 find_all

2.8.2 name

2.8.3 attrs

2.8.4 text

2.8.5 find

2.8.6 其他查询方法

2.9 CSS选择器

2.9.1 嵌套选择

2.9.2 获取属性

2.9.3 获取文本

2.9.4 总结

3 pyquery

3.1 准备工作

3.2 初始化

3.2.1 字符串初始化

3.2.2 URL初始化

3.2.3 文件初始化

3.3 基本CSS选择器

3.4 查找节点

3.4.1 子节点

3.4.2 父节点

3.4.3 兄弟节点

3.5 遍历节点

3.5.1 获取属性

3.5.2 获取文本

3.6 节点操作

3.6.1 addClass和removeClass

3.6.2 attr、text和html

3.6.3 remove

3.7 伪类选择器

4 parsel 的使用

4.1 提取数据 

4.2 提取文本内容

4.3 提取特定的文本内容

4.4 提取特定的属性值

4.5 提取属性

4.6 正则提取


对于网页的节点来说,可以定义id、class或其他属性,而且节点之间还有层次关系,在网页中可以通过XPath或CSS选择器来定位一个或多个节点。相关的解析库也比较多,包括lxml、Beautiful Soup、pyquery、parsel等。

1 XPath的使用

XPath的全程是XML Path Language,即XML路径语言,用来在XML文档中查找信息。虽然最初是用来搜寻XML文档的,但同样适用于HTML文档的搜索。

1.1 XPath概览

包含许多定位的节点。

1.2  XPath常用规则

XPath的一个常用匹配规则://title[@lang='eng'],代表选择所有名称为title,同时属性为lang的值为eng的节点。

1.3 准备工作

使用lxml库,利用XPath对HTML进行解析。

pip install lxml

1.4 实例引入

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></li><li class='item-1'><a href='link4.html'>fourth item</a></li><li class='item-0'><a href='link5.html'>fifth item</a></ul>
</div>
'''
html=etree.HTML(text)
result=etree.tostring(html)
print(result.decode('utf-8'))

<html><body><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></li><li class='item-1'><a href='link4.html'>fourth item</a></li><li class='item-0'><a href='link5.html'>fifth item</a></li></ul>
</div>
</body></html>

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=etree.tostring(html)
print(result.decode('utf-8'))

1.5 所有节点

一般会用以//开头的XPath规则,来选取所有符合要求的节点。

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//*')
print(result)

*代表匹配的所有节点,也就是获取整个HTML文本中的所有节点。从运行结果可以看到,返回形式是一个列表,其中每个元素是element类型,类型后面跟着节点的名称。

如果想要获取所有的li节点,实例如下:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li')
print(result)
print(result[0])

从运行结果也可以看出,提取结果是一个列表,其中每个元素都是element类型,如果想要取出其中一个对象,可以直接用中括号加索引获取,如[0]。

1.6 节点

通过/或//即可查找元素的子节点或子孙节点。如果想选择li节点的所有直接子节点a,则可以通过以下代码实现:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li//a')
print(result)

如果要获取节点的所有子孙节点,可以使用//。

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//ul//a')
print(result)

但是如果这里用//ul/a,就无法获取任何结果了,因为/用于获取直接子节点,但ul节点下没有直接的a子节点,只有li节点。

1.7 父节点

通过连续的/或//可以查找子节点或子孙节点,如果指导子节点,查找父节点,可以通过..实现。

例如,首先选中href属性为link4.html的a节点,然后获取其父节点,在获取父节点的class属性,代码如下:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//a[@href='link4.html]'/../@class')
print(result)

运行结果如下:

['item-1']

此外,也可以通过parent::获取父节点,代码如下:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//a[@href='link4.html]'/parent::*/@class')
print(result)

1.8 属性匹配

在选取节点的时候,还可以使用@符号实现属性过滤。例如,要选取class属性为item-0的li节点,可以通过以下代码实现:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li[@class='item-0']')
print(result)

1.9 文本获取

用XPath中的text方法可以获取节点中的文本,接下来尝试获取前面li节点中的文本,代码如下:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li[@class='item-0']/text()')
print(result)

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li[@class='item-0']/a/text()')
print(result)

如果使用//,能够获取到的结果,代码:

from lxml import etree
html=etree.parse('./test.html',etree.HTMLParser())
result=html.xpath('//li[@class='item-0']//text()')
print(result)

1.10 属性获取

利用@符号,可以获取所有li节点下所有a节点的href属性:

from lxml import etree
html = etree.parse('./test.html',etree.HTMLParser())
result = html.xpath('//li/a/@href')
print(result)

通过@href获取节点的href属性。此处与属性匹配方法不同,属性匹配是用中括号加属性名和值来限定某个属性,如[@href="link1.html"],此处的@href是指获取节点的某个属性。

1.11 属性多值匹配

有时候,某些节点的某个属性可能有多个值,例如:

from lxml import etree
text='''
<li class='li li-first'><a href='link.html'>first item</a></li>
'''
html=etree.HTML(text)
result=html.xpath('//li[@class='li']/a/text()')
print(result)

这里的HTML文本中li节点的class属性就有两个值:li和li-frist,需要用到contains方法,代码如下:

from lxml import etree
text='''
<li class='li li-first'><a href='link.html'>first item</a></li>
'''
html=etree.HTML(text)
result=html.xpath('//li[contains(@class,'li')]/a/text()')
print(result)

上面的contains,给第一个参数传入属性名称,第二个参数传入属性值,只要传入的属性包含传入的属性值,就可以完成匹配。

1.12 多属性匹配

根据多个属性确定一个节点,这时需要同时匹配多个属性,运算符and用于连接多个属性,代码如下:

from lxml import etree
text='''
<li class='li li-first'><a href='link.html'>first item</a></li>
'''
html=etree.HTML(text)
result=html.xpath('//li[contains(@class='li') and @name='item']/a/text()')
print(result)

此外,还有许多运算符:

1.13 按序选择

在选择节点时,某些属性可能同时匹配了多个节点,但我么只想要其中的某一个,可以使用往中括号中传入索引的方法获取特定次序的节点,代码:

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></li><li class='item-1'><a href='link4.html'>fourth item</a></li><li class='item-0'><a href='link5.html'>fifth item</a></ul>
</div>
'''
html=etree.HTML(text)
result=html.xpath('//li[1]/a/text()')
print(result)
result=html.xpath('//li[last()]/a/text()')
print(result)
result=html.xpath('//li[position()<3]/a/text()')
print(result)
result=html.xpath('//li[last()-2]/a/text()')
print(result)

注:这里的代码序号以1开头,而不是0。last()表示最后,position表示位置。

1.14 节点轴选择

XPath提供了许多节点轴的选择方法,包括获取子元素、兄弟元素、父元素、祖先元素等,代码:

from lxml import etree
text ='''
<div><ul><li class="item-0"><a href="link1.html"><span>first item</span></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></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul>
</div>
'''
html = etree.HTML(text)
result = html.xpath('//li[1]/ancestor::*')
print(result)
result = html.xpath('//li[1]/ancestor::div')
print(result)
result = html.xpath('//li[1]/attribute::*')
print(result)
result = html.xpath('//li[1]/child::a[@href="link1.html"]')
print(result)
result = html.xpath('//li[1]/descendant::span')
print(result)
result = html.xpath('//li[1]/following::*[2]')
print(result)
result = html.xpath('//li[1]/following-sibling::*')
print(result)

第一次选择,调用ancestor轴,可以获取所有祖先节点,其后需要跟两个冒号,然后是节点的选择器(*表示匹配所有节点)。返回的是第一个li节点的所有祖先节点,包括html、body、div和ul。

第二次选择,加了限定条件。

第三次选择,调用了attribute轴,可以获取所有属性值,其后跟的选择器还是*,代表获取节点的所有属性,返回值就是li节点的所有属性值。

第四次选择,调用了child轴,可以获取所有直接子节点,这里的限定条件指的事选取href属性为link.html的a节点。

第五次选择,调用了descendant轴,可以获取所有子孙节点,这里的限定条件指获取span节点。

第六次选择,调用了following轴,获取当前节点之后的所有节点,这里的限定条件指获取了第二个后续节点。

第七次选择,调用了following-sibling轴,获取当前节点之后的所有同级节点。

2 Beautiful Soup

2.1 简介

python的一个html或xml的解析库,用它可以方便地从网页中提取数据。

2.2 解析器

通过上表,lxml解析器具有解析html和xml的功能。

使用lxml解析器,只需要在初始化时,把第二个参数修改为lxml即可:

from bs4 import BeautifulSoup
soup=BeautifulSoup('<p>Hello</p>','lxml')
print(soup.p.string)

2.3 准备工作

pip3 install beautifulsoup4

2.4 基本使用

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/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">...</p>
"""
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.prettify())
print(soup.title.string)

2.5 节点选择器

直接调用节点的名称即可选择节点,然后调用string属性就可以得到节点内的文本了。

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/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">...</p>
"""from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)

2.6 提取信息

2.6.1 获取名称

利用name属性可以获取节点的名称。

print(soup.title.name)

2.6.2 获取属性

一个节点可能有多个属性,例如id和class,选择某个节点元素后,可以调用attrs获取其所有属性:

print(soup.p.attrs)
print(soup.p.attrs['name'])

print(soup.p['name'])
print(soup.p['Class'])

2.6.3 获取内容

print(soup.p.string)

2.6.4 嵌套选择

html ='''
<html><head><title>The Dormouse's story</title></head>
<body>
'''
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)

2.7 关联选择

在做选择的过程中,需要先选中某一个节点,然后再以这个节点为基准选子节点、父节点、兄弟节点等。

2.7.1 子节点和子孙节点

选取节点之后,如果想要获取它的直接子节点,可以调用contens属性,代码:

<html><head><title>The Dormouse's story</title></head><body><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>Elsie</span></a><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">...</p>
'''
from bs4 import BeautifulSoup
soup=BeautifulSoup(html,'lxml')
print(soup.p.contents)

可以看到,返回结果是列表形式:p节点里既包括文本,又包括节点。列表中的每个元素都是p节点的直接子节点。像第一个a节点里面包括的span节点,相当于孙子节点,但是返回结果并没有把span节点单独选出来。所以说,contens属性得到的结果是直接子节点组成的列表。

同样,可以调用children属性得到相应的结果:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.children)
for i, child in enumerate(soup.p.children):print(i, child)

这里掉用children属性来选择,返回结果是生成器类型,利用for循环输出了相应内容。

如果要得到所有的子孙节点,则可以调用descendants属性:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.descendants)
for i, child in enumerate(soup.p.descendants):print(i, child)

2.7.2 父节点和祖先节点

如果要获取某个节点元素的父节点,可以掉用parents属性:

html = """
<html><head><title>The Dormouse's story</title></head><body><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>Elsie</span></a></p><p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.a.parent)

这里选的是第一个a节点的父节点元素,a节点的父节点是p节点,所以输出结果是p节点及其内部内容。

如果想要获取所有祖先节点,可以调用parents属性:

html = """
<html><body><p class="story"><a href="http://example.com/elsie" class="sister" id="link1"><span>Elsie</span></a></p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(type(soup.a.parents))
print(list(enumerate(soup.a.parents)))

2.7.3 兄弟节点

如果想要获取同级节点,也就是兄弟节点:

html = """
<html><body><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>Elsie</span></a>Hello<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>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print('Next Sibling', soup.a.next_sibling)
print('Prev Sibling', soup.a.previous_sibling)
print('Next Siblings', list(enumerate(soup.a.next_siblings)))
print('Prev Siblings', list(enumerate(soup.a.previous_siblings)))

可以看到,这里调用了4个属性。next_sibling和previous_sibling分别用于获取节点的下一个和上一个兄弟节点,next_siblings和previous_siblings则分别返回后面和前面的所有兄弟节点。

2.7.4 提取信息

关联元素的信息获取,代码如下:

html = """
<html><body><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">Bob</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a></p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print('Next Sibling:')
print(type(soup.a.next_sibling))
print(soup.a.next_sibling)
print(soup.a.next_sibling.string)
print('Parent:')
print(type(soup.a.parents))
print(list(soup.a.parents)[0])
print(list(soup.a.parents)[0].attrs['class'])

如果返回结果是单个节点,可以直接掉用string、attrs等属性获取其文本和属性;如果返回结果是包含多个节点的生成器,则可以现将结果转为列表,再从中取出某个元素,之后调用string、attrs等属性即可获取对应节点的文本和属性。

2.8 方法选择器

利用以下方法可以灵活查询相应参数:

2.8.1 find_all

查询所有符合条件的元素,可以给它传入一些属性或文本得到符合条件的元素,API如下:

find_all(name,attrs,recursive,text,**kwargs)

2.8.2 name

根据name参数查询元素,代码如下:

html = '''
<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">Foo</li><li class="element">Bar</li><li class="element">Jay</li></ul><ul class="list list-small" id="list-2"><li class="element">Foo</li><li class="element">Bar</li></ul></div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(name='ul'))
print(type(soup.find_all(name='ul')[0]))

调用find_all方法,向其中传入name参数,其参数值为ul,意思是查询所有ul节点。

列表中每个元素都是bs4.element.Tag类型,依然可以进行嵌套查询。代码:

for ul in soup.find_all(name='ul'):print(ul.find_all(name='li'))

返回结果还是列表类型,列表中每个元素依然是Tag类型。接下来遍历每个li节点,获取文本内容:

for ul in soup.find_all(name='ul'):print(ul.find_all(name='li'))for li in ul.find_all(name='li'):print(li.string)

2.8.3 attrs

除了根据节点名查询,也可以传入一些属性进行查询:

html = '''
<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">Foo</li><li class="element">Bar</li><li class="element">Jay</li></ul><ul class="list list-small" id="list-2"><li class="element">Foo</li><li class="element">Bar</li></ul></div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(attrs={'id':'lisy-1'}))
print(soup.find_all(attrs={'name':'elements'}))

另一种查询方式:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(id="lisy-1"))
print(soup.find_all(class="elements"))

2.8.4 text

text参数可以用来匹配节点的文本,其传入形式可以是字符串,也可以是正则表达式形式,代码:

import re
html='''
<div class="panel"><div class="panel-body"><a>Hello, this is a link</a><a>Hello, this is a link, too</a></div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(text=re.compile('link')))

这里有两个a节点,其内部包含文本信息,find_all方法中传入text参数,该参数为正则表达式,返回结果是由所有与正则表达式相匹配的节点文本组成的元素。

2.8.5 find

find方法可以查询符合条件的元素,但是find方法返回的是单个元素,也就是第一个匹配的元素,而find_all会返回由所有匹配的元素组成的列表,代码:

html='''
<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">Foo</li><li class="element">Bar</li><li class="element">Jay</li></ul><ul class="list list-small" id="list-2"><li class="element">Foo</li><li class="element">Bar</li></ul></div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find(name='ul'))
print(type(soup.find(name='ul')))
print(soup.find(class_='list'))

2.8.6 其他查询方法

2.9 CSS选择器

使用CSS选择器,只需要调用select方法,传入相应的CSS选择器即可,代码:

html = '''
<div class="panel"><div class="panel-heading"><h4>Hello</h4></div><div class="panel-body"><ul class="list" id="list-1"><li class="element">Foo</li><li class="element">Bar</li><li class="element">Jay</li></ul><ul class="list list-small" id="list-2"><li class="element">Foo</li><li class="element">Bar</li></ul></div>
</div>
'''
from bs4 import BeautifulSoupsoup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))

返回结果均是符合css选择器的节点组成的列表,例如select('ul li')表示选择所有ul节点下面的所有li节点,结果便是所有li节点组成的列表。

2.9.1 嵌套选择

例如,先选择所有ul节点,再遍历每个ul节点,选择其li节点,代码:
 

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):print(ul.select('li'))

2.9.2 获取属性

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):print(ul['id'])print(ul.attrs['id'])

2.9.3 获取文本

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li'):print('Get Text:', li.get_text())print('String:', li.string)

2.9.4 总结

3 pyquery

功能更强大的库

3.1 准备工作

pip3 install pyquery

3.2 初始化

在用pyquery库解析html文本的时候,需要先将其初始化为一个PyQuery对象。

3.2.1 字符串初始化

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li'))

3.2.2 URL初始化

初始化的参数除了能以字符串形式传递,还能是网页的url,此时只需要指定PyQuery对象的参数url即可:

from pyquery import PyQuery as pq
doc = pq(url='https://cuiqingcai.com')
print(doc('title'))

下面代码实现的功能是相同的:

from pyquery import PyQuery as pq
import requests
doc = pq(requests.get('https://cuiqingcai.com').text)
print(doc('title'))

3.2.3 文件初始化

还可以传递本地的文件名,此时将参数指定为filename即可:

from pyquery import PyQuery as pq
doc = pq(filename = 'demo.html')
print(doc('li'))

3.3 基本CSS选择器

实例:

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))

运行结果如下:

采用直接遍历获取的节点,调用text方法,可以直接获取节点的文本内容,代码:

for item in doc('#container .list li').items():print(item.text())

3.4 查找节点

3.4.1 子节点

查找子节点时,需要用到find方法,其参数时css选择器,代码:

from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
print(type(items))
lis = items.find('li')
print(type(lis))
print(lis)

这里我们选择class为list的节点,然后调用find方法,并将其传入css选择器,选取其内部的li节点,最后打印输出。

此外,如果想只查找子节点,可以用children方法:

lis = items.children()
print(type(lis))
print(lis)

如果要筛选所有子节点中符合条件的节点,例如想筛选出子节点中class为active的节点,则可以向children方法传入css选择器.active,代码:

lis = items.children('.active')
print(lis)

3.4.2 父节点

用parent方法获取某个节点的父节点,代码:

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('.list'))
container = items.parent()
print(type(container))
print(container)

这里我们首先用.list选取class为list的节点,然后调用parent方法得到其父节点,其类型依然是PyQuery。

如果想获取某个祖先节点,可以用parents方法:

如果想要筛选某个祖先节点,可以向parents方法传入css选择器,就会返回祖先节点中符合css选择器的节点:

parent = items.parents('.wrap')
print(parent)

3.4.3 兄弟节点

获取兄弟节点可以使用siblings方法:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings())

这里首先选择class为list的节点内部的class为item-0和active的节点,也就是第三个li节点。

如果要筛选某个兄弟节点,依然可以向siblings方法中传入css选择器,这样就能从所有兄弟节点中挑选出符合条件的节点:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))

运行结果如下:

3.5 遍历节点

pyquery库的选择结果可能是多个节点,也可能是单个节点,类型都是pyquery类型,但不像beautiful soup那样返回列表。

如果结果是单个节点,既可以直接打印输出,也可以直接转成字符串:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(str(li))

如果结果是多个节点,就可以通过items方法遍历获取:

from pyquery import PyQuery as pq
doc = pq(html)
lis = doc('li').items()
print(type(lis))
for li in lis:print(li,type(li))

需要获取的信息一般包括属性和文本:

3.5.1 获取属性

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active')
print(a,type(a))
print(a.attr('href'))

此外,也可以通过调用attr属性来获取属性值:

print(a.attr.href)

如果选中的多个元素,调用attr方法,智慧得到第一个节点的属性:

a = doc('a')
print(a,type(a))
print(a.attr('href'))
print(a.attr.href)

如果想要获取a节点的所有属性,需要遍历:

from pyquery import PyQuery as pq
doc = pq(html)
a = doc('a')
for item in a.items():print(item.attr('href'))

3.5.2 获取文本

获取节点之后的另一个主要操作就是获取其内部的文本,调用text方法实现:

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active')
print(a)
print(a.text)

如果想要获取节点内部的html文本,需要用到html方法:

from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
print(li.html())

如果我们选中的是多个节点,html方法返回的是第一个li节点内部的html文本,而text返回了所有li节点内部的纯文本,各节点内部中间用一个空格分隔开,返回结果是一个字符串。

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('li')
print(li.html())
print(li.text())
print(type(li,text())

3.6 节点操作

pyquery库提供了一系列方法对节点进行动态修改,例如为某个节点添加一个class,移除某个节点等。

3.6.1 addClass和removeClass

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.removeClass('active')
print(li)
li.addClass('active')
print(li)

3.6.2 attr、text和html

html = '''
<ul class="list"><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li></ul>
'''
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.attr('name','link')
print(li)
li.text('changed item')
print(li)
li.html('<span>changed item</span>')
print(li)

3.6.3 remove

html = '''
<div class='wrap'>Hello,world<p>This is a paragraph.</p>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
print(wrap.text())

3.7 伪类选择器

html = '''
<div class='wrap'><div id='container'><ul class="list"><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)# 选择第一个 li 节点
li = doc('li:first-child')
print("第一个 li 节点:")
print(li)
print()# 选择最后一个 li 节点
li = doc('li:last-child')
print("最后一个 li 节点:")
print(li)
print()# 选择第奇数个 li 节点
li = doc('li:nth-child(odd)')
print("第奇数个 li 节点:")
print(li)
print()# 选择第偶数个 li 节点
li = doc('li:nth-child(even)')
print("第偶数个 li 节点:")
print(li)
print()# 选择包含文本 "second" 的 li 节点
li = doc('li:contains("second")')
print('包含文本 "second" 的 li 节点:')
print(li)
print()# 选择类名为 "active" 的 li 节点
li = doc('li.active')
print('类名为 "active" 的 li 节点:')
print(li)
print()# 选择有子元素 a 的 li 节点
li = doc('li:has(a)')
print('有子元素 a 的 li 节点:')
print(li)
print()

4 parsel 的使用

4.1 提取数据 

使用 selector.css('.item-0') 提取所有类名为 item-0<li> 元素。使用 selector.xpath('//li[contains(@class, "item-0")]') 提取所有包含 item-0 类的 <li> 元素。打印提取到的元素数量、类型和内容。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selectorselector = Selector(text=html)
items = selector.css('.item-0')
print(len(items), type(items), items)
items2 = selector.xpath('//li[contains(@class, "item-0")]')
print(len(items2), type(items), items2)

4.2 提取文本内容

使用 CSS 选择器 .item-0 提取所有类名为 item-0<li> 元素。遍历提取到的元素,使用 XPath 表达式 .//text() 提取每个元素及其子元素中的所有文本内容。使用 CSS 选择器 .item-0 *::text 提取所有 .item-0 元素的子元素中的文本节点,并获取所有结果。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selector
selector = Selector(text=html)
items = selector.css('.item-0')
for item in items:text = item.xpath('.//text()').get()print(text)# result = selector.xpath('//li[contains(@class, "item-0")]//text()').get()
# print(result)result = selector.css('.item-0 *::text').getall()
print(result)# result = selector.css('.item-0::text').get()
# print(result)

4.3 提取特定的文本内容

selector.xpath('//li[contains(@class, "item-0")]//text()') 使用 XPath 表达式提取所有 <li> 元素中包含 item-0 类的文本内容。//li[contains(@class, "item-0")]:匹配所有 <li> 元素,其 class 属性包含 item-0//text():提取匹配到的 <li> 元素及其子元素中的所有文本节点。.getall() 获取所有提取到的文本节点,返回一个列表。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selector
selector = Selector(text=html)
result = selector.xpath('//li[contains(@class, "item-0")]//text()').getall()
print(result)# result = selector.css('.item-0::text').get()
# print(result)

4.4 提取特定的属性值

selector.xpath('//li[contains(@class, "item-0") and contains(@class, "active")]/a/@href') 使用 XPath 表达式提取同时具有 item-0active 类的 <li> 元素中的 <a> 标签的 href 属性值。//li[contains(@class, "item-0") and contains(@class, "active")]:匹配同时具有 item-0active 类的 <li> 元素。/a/@href:提取 <a> 标签的 href 属性值。.get() 获取提取到的第一个属性值。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selector
selector = Selector(text=html)
result = selector.css('.item-0.active a::attr(href)').get()
print(result)
result = selector.xpath('//li[contains(@class, "item-0") and contains(@class, "active")]/a/@href').get()
print(result)

4.5 提取属性

对于每个匹配到的 .item-0 元素,正则表达式 link.* 会匹配其文本内容中以 "link" 开头的部分。具体来说:

  • 第一个 .item-0 元素的文本是 "first item",不匹配正则表达式。

  • 第二个 .item-0 元素的文本是 "third item",不匹配正则表达式。

  • 第三个 .item-0 元素的文本是 "fifth item",不匹配正则表达式。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selector
selector = Selector(text=html)
result = selector.css('.item-0').re('link.*')
print(result)

4.6 正则提取

selector.css('.item-0') 提取所有类名为 item-0<li> 元素。.re_first('<span class="bold">(.*?)</span>') 使用正则表达式 <span class="bold">(.*?)</span> 提取匹配的内容,并返回第一个匹配结果。<span class="bold">(.*?)</span>:匹配 <span class="bold"> 开头,</span> 结尾的内容,并捕获中间的任意字符(非贪婪模式)。

html = '''
<div><ul><li class="item-0">first item</li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1 active"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>
'''
from parsel import Selector
selector = Selector(text=html)
result = selector.css('.item-0').re_first('<span class="bold">(.*?)</span>')
print(result)

 

 来源:

 

相关文章:

python网络爬虫开发实战之网页数据的解析提取

目录 1 XPath的使用 1.1 XPath概览 1.2 XPath常用规则 1.3 准备工作 1.4 实例引入 1.5 所有节点 1.6 节点 1.7 父节点 1.8 属性匹配 1.9 文本获取 1.10 属性获取 1.11 属性多值匹配 1.12 多属性匹配 1.13 按序选择 1.14 节点轴选择 2 Beautiful Soup 2.1 简介…...

GitHub Copilot平替:CodeGeeX 2.0实测报告

本文基于20个真实开发场景对CodeGeeX 2.0进行深度评测&#xff0c;涵盖代码生成质量、上下文理解能力、多语言支持度等关键维度。通过Python数据分析、Java微服务、React前端开发三大核心场景的对比实验&#xff0c;揭示其相比GitHub Copilot在中文语境支持、本地化部署、隐私保…...

QT对象模型

信号,槽,函数执行顺序 首先&#xff0c;拖入一个按钮&#xff0c;在转到槽&#xff0c;在click() 转到widget.cpp 在widget.h中 然后在widget.cpp中 运行结果 当发出信号后&#xff0c;先执行槽函数&#xff0c;再执行信号后面的函数&#xff08;单线程&#xff09; 在widget.h…...

C++:类型推导规则 unsigned short + 1

在 C/C 中&#xff0c;整数提升&#xff08;Integer Promotion&#xff09; 规则决定了 vlan_id 1 的类型&#xff1a; unsigned short 的值在运算时会被 提升&#xff08;promote&#xff09; 到 int 或 unsigned int&#xff08;取决于平台&#xff09;。 默认情况下&#x…...

PHP接口开发:从基础到高级的全面指南

一、接口基础与核心概念(约800字) 1.1 接口的本质定义 在PHP中,接口(Interface)是一种特殊的抽象结构,它通过interface关键字定义一组方法的契约规范,不包含具体实现。这种设计强制实现类必须遵循统一的调用标准,如: interface PaymentGateway {public function proc…...

C#Dictionary值拷贝还是引用

Dictionary值拷贝还是引用 这可能算是Directionary的一个坑值类型&#xff08;Value Type&#xff09;引用类型&#xff08;Reference Type&#xff09;总结 关于锁1. **锁对象的可见性**2. **锁对象的唯一性**3. **最佳实践**4. **为什么 readonly 是一个好的选择**5. **总结*…...

deepseek实战教程-第六篇查找源码之仓库地址与deepseek-R1、deepseek-LLM仓库内容查看

上一篇讲了支持deepseek的模型应用的本地安装和部署以及使用。再上一篇讲解了deepseek提供的开放api,便于开发者基于deepseek提供的接口来编写属于自己的业务应用程序。但是前面几篇我们都是在用模型,我们知道deepseek是开源的,那么deepseek的源码在哪里,具体源码是什么样的…...

WELL健康建筑认证是什么?

**WELL健康建筑认证&#xff1a;全方位呵护居住者福祉的权威标准** WELL健康建筑认证&#xff0c;这一源自美国的全球性健康建筑标准&#xff0c;宛如建筑界的璀璨明珠&#xff0c;以其独特的光芒照亮了健康建筑的发展之路。它不仅是全球首部专门针对室内环境提升人体健康与福…...

C++ STL 序列式容器之(三)-- List

一、什么是list&#xff1f; Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions. 列表是序列容器&#xff0c;允许在序列中的任何位置进行以常量时间插入和擦除操作&…...

CAN基础知识学习二

一、控制器局域网总线&#xff08;CAN&#xff0c;Controller Area Network&#xff09;&#xff1b; 二、CAN FD 是CAN with Flexible Data rate的缩写&#xff0c;翻译为【可变速率的 CAN】 CAN-FD 采用了两种位速率&#xff1a;从控制场中的 BRS 位到 ACK 场之前&#xff08…...

Java编程思想:为何有时要将子类对象赋值给父类引用

为何有时要将子类对象赋值给父类引用&#xff0c;用父类来进行实例化&#xff1f; 这就要说多态的优势: 代码的扩展性和降低耦合度&#xff0c;而不是完全避免修改代码。 TuXing t new Changfangxing(); Changfangxing k (Changfangxing)t;原因1&#xff1a; 代码可拓展性 …...

2025年优化算法:龙卷风优化算法(Tornado optimizer with Coriolis force,TOC)

龙卷风优化算法&#xff08;Tornado optimizer with Coriolis force&#xff09;是发表在中科院二区期刊“ARTIFICIAL INTELLIGENCE REVIEW”&#xff08;IF&#xff1a;11.7&#xff09;的2025年智能优化算法 01.引言 当自然界的狂暴之力&#xff0c;化身数字世界的智慧引擎&…...

2小样本学习(Few-Shot)之相似度

目录 小样本学习的基本思路: 具体实现方法: 小样本学习的基本思路: 学习一个相似度函数similarity function:sim(x,x) 两个样本越相近,相似度越高。 比如:...

docker-操作实战

前言 C镜像制作 因为我平常不用&#xff0c;所以不书写了 SpringBoot 微服务镜像制作 mkdir java ca java cp /data/maxhou/myapp/xxx.jar . vi Dockerfile FROM openjdk:8 COPY ./xxx.jar /app.jar CMD ["java","-jar","/app.jar"]COPY ./…...

后大模型时代智能体将成为“新宠”

智能体 |未来已来 智能体 |市场井喷 智能体 |定义 智能体 |与大模型的区别 智能体 |与Copilot的区别 智能体 |企业价值 智能体 |个体价值 智能体 |开发流程 智能体 |提示词解读 智能体 |应用场景 智能体 |重难点问题...

【MySQL】监控MySQL

目录 使用状态变量监控MySQL 使用性能模式&#xff08;Performance Schema&#xff09;监控MySQL 1.性能模式 2.性能模式设置表 3.sys模式 使用状态变量监控MySQL 使用 show status 语句评估系统运行状况。 可以添加范围修饰符global或session来显示全局或本地状态信息。…...

CTF类题目复现总结-[BSidesSF2020]toast-clicker 1

一、靶场地址 https://buuoj.cn/challenges#[BSidesSF2020]toast-clicker1二、复现步骤 1、下载压缩包&#xff0c;解压是apk文件&#xff1b; 2、利用 jadx apk反编译工具&#xff1b; jadx下载地址&#xff1a;https://github.com/skylot/jadx67, 83, 68, 120, 62, 109, …...

(更新完)Supplementary Material——AZ-NAS

6. Supplementary Material 在本补充材料中&#xff0c;我们提供了 AZ-NAS 在 NDS [18]、NAS-Bench-201 [7] 和 MobileNetV2 [14, 19] 搜索空间上的额外结果和深入分析。 Additional results on the NDS benchmark. 神经设计空间&#xff08;NDS&#xff09; [18] 基准提供了…...

基于SSM框架的线上甜品销售系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此网上销售信息的…...

TCP | 序列号和确认号 [逐包分析] | seq / ack 详解

注 &#xff1a; 本文为 “TCP 序号&#xff08;seq&#xff09;与确认序号&#xff08;ack&#xff09;” 相关文章合辑。 英文引文&#xff0c;机翻未校。 中文引文&#xff0c;略作重排。 如有内容异常&#xff0c;请看原文。 Understanding TCP Seq & Ack Numbers […...

Citus源码(1)分布式表行为测试

最近对citus的实现非常好奇&#xff0c;本篇对citus的行为做一些测试。本篇只测行为&#xff0c;不分析源码。后面会继续写一系列文章分析citus源码。 环境&#xff1a;3节点 PG17 with citus。 SELECT citus_set_coordinator_host(127.0.0.1, 3001); SELECT citus_add_node(1…...

【AI测试必学】DeepSeek API 快速入门:获取 API Key 与调用 API 步骤详解

DeepSeek API 快速入门&#xff1a;获取 API Key 与调用 API 步骤详解 一、获取 API Key二、调用 DeepSeek API方法 1&#xff1a;使用 OpenAI Python SDK 调用 DeepSeek API方法 2&#xff1a;使用 requests 库直接发送 HTTP 请求方法 3&#xff1a;使用 curl 命令 相关链接 一…...

Web前端之UniApp、Taro、ReactNative和Flutter的区别

MENU 前言介绍及公司技术差异使用方法使用场景差异注意事项打包与部署差异框架应用实例结语 前言 在移动应用开发领域&#xff0c;跨平台框架已成为开发者的得力工具。UniApp、Taro、ReactNative和Flutter它们在Android&#xff08;安卓&#xff09;或iOS&#xff08;苹果&…...

[leetcode]map的用法

1. 定义和初始化 定义&#xff1a;std::map是一个关联容器&#xff0c;键值对会自动根据键的值进行排序&#xff08;默认是升序&#xff09;。 cpp复制 map<char, int> mp; 插入元素&#xff1a;可以通过operator[]或insert方法插入键值对。 cpp复制 mp[a] 1; mp[b] 3…...

PHP大马的使用

BestShell/best_php_shell.php at master Kevil-hui/BestShell 这里用到的是这位师傅的大马&#xff08;主要是从头开始写一个大马实在太麻烦了&#xff09; 用pikachu靶场进行上传的测试 在这里传马&#xff0c;这个是简单的前端校验&#xff0c;bp抓包改后缀就好了 上传成…...

【CC2530 教程 十】CC2530 Z-Stack 协议栈

一、Z-Stack 协议栈目录结构&#xff1a; Z-Stack 协议栈可以从 TI 官网免费下载&#xff0c;下载安装完成以后&#xff0c;会默认在 C 盘的根目录下创建 Texas Instruments 目录&#xff0c;该目录下的子目录就是安装的 Z-Stack 文件&#xff0c;并且在该子目录下创建Accessor…...

区间端点(java)(贪心问题————区间问题)

deepseek给了一种超级简单的做法 我是真的想不到 贪心的思路是 局部最优——>全局最优 这种我是真的没有想到&#xff0c;这样的好处就是后面便利的时候可以通过foreach循环直接便利qu的子元素也就是对应的某一个区间, 将一个二维数组变成一维数组&#xff0c;每一个一维…...

定长内存池原理及实现

目录 一、池化技术 二、内存池 三、内存池主要解决的问题 四、定长内存池的实现 1.定长内存池的原理 2.框架 3.Delete实现 4.New实现 5.性能测试 五、源码 FixedMemoryPool.h test.cc 一、池化技术 所谓“池化技术”&#xff0c;就是程序先向系统申请过量的资源&…...

通过php连接redis数据库

如上图所示&#xff0c;这是去搭建一个lamp平台&#xff0c; 阿帕奇和php安装好之后&#xff0c;php直接就被安装成阿帕奇的一个功能模块。 如上图所示&#xff0c;这就是php作为阿帕奇的功能模块。 如上图所示&#xff0c;我们去正常启动redis数据库。 如上图所示&#xff0c…...

3D点云的深度学习网络分类(按照作用分类)

1. 3D目标检测&#xff08;Object Detection&#xff09; 用于在点云中识别和定位目标&#xff0c;输出3D边界框&#xff08;Bounding Box&#xff09;。 &#x1f539; 方法类别&#xff1a; 单阶段&#xff08;Single-stage&#xff09;&#xff1a;直接预测3D目标位置&am…...

论文解读:《Word embedding factor based multi-head attention》——基于词嵌入因子的多头注意力

原文链接&#xff1a;Word embedding factor based multi-head attention | Artificial Intelligence Review 多头注意力机制线性地将查询、键和值投影到不同的子空间中&#xff0c;允许模型从不同的角度理解输入序列&#xff0c;并利用输入句子序列中有关令牌之间关系的信息。…...

单片机和微控制器知识汇总——《器件手册--单片机、数字信号处理器和可编程逻辑器件》

目录 四、单片机和微控制器 4.1 单片机(MCU/MPU/SOC) 一、定义 二、主要特点 三、工作原理 四、主要类型 五、应用领域 六、选型与设计注意事项 七、发展趋势 4.2 数字信号处理器(DSP/DSC) ​编辑​编辑 一、定义 二、工作原理 三、结构特点 四、应用领域 五、选型与设计注…...

LeetCode hot 100 每日一题(15)——48.旋转图像

这是一道难度为中等的题目&#xff0c;让我们来看看题目描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 提示…...

Java多线程精讲:线程操作与状态转换全解析

前言 本章内容为作者结合学习与实践的总结整理&#xff0c;虽力求准确&#xff0c;但疏漏之处在所难免。若有任何疑问或建议&#xff0c;恳请读者朋友们不吝指正&#xff0c;共同完善知识体系&#xff0c;感激不尽&#xff01; 一、认识多线程&#xff08;Thread&#…...

HashMap的位操作是什么?HashSet 的 contains 方法复杂度是多少?红黑树简单讲一下?

一、HashMap 的位操作设计 HashMap 使用位运算优化哈希计算与索引定位&#xff0c;核心场景如下&#xff1a; 哈希扰动函数 计算键的哈希值时&#xff0c;将高16位与低16位异或&#xff1a; static final int hash(Object key) {int h;return (key null) ? 0 : (h key.hash…...

GitHub开源的容器管理面板-Dpanel

dpanel Docker安装部署二进制部署 GitHub官网 一块轻量化docker可视化管理面板&#xff0c;由国人开发&#xff0c;个人觉得是比较好用的&#xff0c;功能都很齐全&#xff0c;并且可以通过修改源码&#xff0c;自定义前端样式等。 Docker安装部署 官网 部署环境&#xff1…...

vue-将组件内容导出为Word文档-docx

1. 安装依赖 首先&#xff0c;我们需要安装docx库&#xff0c;以便在前端生成Word文档。可以通过以下命令进行安装&#xff1a; npm install docx 2. 实现导出功能 2.1 初始化文档 使用docx库创建一个新的文档实例&#xff0c;并定义文档的结构和内容。我们使用Document、…...

IMX6ULL学习篇——系统学习设备树

IMX6ULL学习篇——系统学习设备树 ​ 这篇博客的目的是系统的整理一下设备树当中的一些非常基本的概念。基于之前的学习&#xff0c;我们已经至少掌握了字符设备的基本的框架&#xff0c;编写一个最简单的字符设备简单的流程。 ​ 但是我们知道&#xff0c;一个外设很有可能是…...

使用vector构造杨辉三角形

力扣118题&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1…...

亮数据爬取API爬取亚马逊电商平台实战教程

前言 在当今数据驱动的商业环境中&#xff0c;企业需要快速、精准地获取互联网上的公开数据以支持市场分析、竞品调研和用户行为研究。然而&#xff0c;传统的手动网页爬取方式面临着诸多挑战&#xff1a;IP封锁、验证码干扰、网站结构频繁变更&#xff0c;以及高昂的运维成本…...

AI+金融 应用 使用DeepSeek、Qwen等大模型输入自然语言,得到通达信等行情软件公式代码,导入后使用

AI金融 应用 使用DeepSeek、Qwen等大模型输入自然语言&#xff0c;得到通达信等行情软件公式代码&#xff0c;导入后使用。不会编程&#xff0c;也能行情软件中实现个性化条件选股&#xff0c;个性化技术指标。 AIbxm低估值趋势选股策略&#xff0c;参考提示词&#xff1a; 编…...

SmolVLM2: 让视频理解能力触手可及

一句话总结: SmolVLM 现已具备更强的视觉理解能力&#x1f4fa; SmolVLM2 标志着视频理解技术的根本性转变——从依赖海量计算资源的巨型模型&#xff0c;转向可在任何设备运行的轻量级模型。我们的目标很简单: 让视频理解技术从手机到服务器都能轻松部署。 我们同步发布三种规…...

去中心化金融

什么是去中心化金融 去中心化金融&#xff08;Decentralized Finance&#xff0c;简称 DeFi&#xff09;是一种基于区块链技术构建的金融系统&#xff0c;旨在通过去除传统金融机构&#xff08;如银行、证券公司等&#xff09;作为中介&#xff0c;提供各种金融服务。这些服务…...

Mysql并发事务带来哪些问题?

大家好&#xff0c;我是锋哥。今天分享关于【Mysql并发事务带来哪些问题?】面试题。希望对大家有帮助&#xff1b; Mysql并发事务带来哪些问题? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MySQL 中&#xff0c;事务并发执行时会引发一系列问题&#xff0c…...

PCL 点云多平面探测

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Open3D为我们提供了一种点云多平面探测的算法,该算法使用基于鲁棒统计的方法进行平面补丁检测。该算法具体过程:首先将点云细分为更小的块(使用二分法),然后尝试为每个点云块匹配一个平面。如果平面通过了鲁棒平…...

OpenBMC:BmcWeb添加路由5 设置handler函数

对路由对象完成了权限和method的设置后,最重要的就是设置路由的处理函数: //http\routing\taggedrule.hpptemplate <typename... Args> class TaggedRule :public BaseRule,public RuleParameterTraits<TaggedRule<Args...>> {...template <typename F…...

攻破tensorflow,勇创最佳agent(2)---损失(loss) 准确率(accuracy)问题

实战播: 怎么判定一个模型好不好,你设置的值对不对? 需要再看几个值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…...

括号合法题

一、括号合法题 2116. 判断一个括号字符串是否有效 //采用从左往右和从右往左遍历的贪心算法&#xff0c;分别保证前缀合法&#xff0c;后缀合法。public boolean canBeValid(String s, String locked) {int ns.length();if (n%21) return false;int num0;// 从左到右扫描&…...

C++11之深度理解lambda表达式

前言 在现代C中&#xff0c;Lambda表达式提供了一种简洁而强大的方式来定义匿名函数&#xff0c;使代码更具可读性和灵活性。自C11引入Lambda以来&#xff0c;它已经成为STL算法、并发编程和回调机制中的重要工具。随着C14、C17和C20的不断演进&#xff0c;Lambda的功能也在不断…...

字符串常量,数组和指针的不同形式

在 C 语言中&#xff0c;字符串 "hello" 存储在内存中是一个字符数组&#xff0c;它的内存布局通常如下&#xff1a; 1. 字符串常量区&#xff1a; 字符串常量&#xff08;如 "hello"&#xff09;是存储在程序的数据段&#xff08;通常称为 .data 或 .ro…...