python爬虫-PyQuery详解

python爬虫-PyQuery详解

Python爬虫解析库,主流的有

  • PyQuery
  • Beautifulsoup
  • Scrapy Selectors
  • 正则表达式。

PyQuery和scrapy Selectors都是基于lxml模块,而lxml和正则表达式都是C语言写的。
Beautifulsoup是用纯Python编写的。
正则表达式的构造稍微复杂一点,一般在结构化的网页中易出错。

我们声明一个长HTML字符串

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>

1.初始化

1)字符串初始化

rom pyquery import PyQuery as pq
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'))

运行结果

在这里插入图片描述传入 li 节点,这样就可以选择所有的 li 节点。

2)URL 初始化
传入网页的 URL,此时只需要指定参数为 url

from pyquery import PyQuery as pq
doc = pq(url='https://www.csdn.net/')
print(doc('head'))

运行结果在这里插入图片描述PyQuery 对象会首先请求这个 URL,然后用得到的 HTML 内容完成初始化。

2.基本CSS选择器

html = '''
<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>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))

运行结果
在这里插入图片描述我们传入了一个 CSS 选择器 #container .list li,它的意思是先选取 id 为 container 的节点,然后再选取其内部的 class 为 list 的节点内部的所有 li 节点。然后,打印输出

3.查找节点

1)子节点
find 的查找范围是节点的所有子孙节点

html = '''
<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>
'''

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

输出结果
在这里插入图片描述
如果我们只想查找子节点,那可以用 children 方法

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

运行结果
在这里插入图片描述
如果要筛选所有子节点中符合条件的节点,比如想筛选出子节点中 class 为 active 的节点,可以向 children() 方法传入 CSS 选择器.active:

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

结果

 <li class="item-0 active"><a href="link3.html"><spanclass="bold">third item</span></a></li> 
 <li class="item-1 active"><a href="link4.html">fourth item</a></li

2)父节点

我们可以用 parent 方法来获取某个节点的父节点

html = '''
<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>
'''

from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
container = items.parent()
print(container)

运行结果
在这里插入图片描述
如果想获取某个祖先节点,这时可以用 parents 方法

3)兄弟节点
如果要获取兄弟节点,可以使用 siblings() 方法

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

运行结果
在这里插入图片描述
这正是我们刚才所说的 4 个兄弟节点。

如果要筛选某个兄弟节点,我们依然可以向 siblings 方法传入 CSS 选择器

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

在这里插入图片描述

4.遍历

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

运行结果
在这里插入图片描述

5.获取信息

1)获取属性
调用 attr() 方法来获取属性

html = '''
<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>
'''

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

运行结果
在这里插入图片描述
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 a')
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())

运行结果
在这里插入图片描述

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)

运行结果
在这里插入图片描述

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)

运行结果
在这里插入图片描述attr 方法来修改属性,该方法的第一个参数为属性名,第二个参数为属性值
text 和 html 方法来改变节点内部的内容

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())

运行结果如下

Hello, World This is a paragraph.

from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
wrap.find('p').remove()
print(wrap.text())

运行结果
在这里插入图片描述

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 = doc('li:first-child')
print(li)
li = doc('li:last-child')
print(li)
li = doc('li:nth-child(2)')
print(li)
li = doc('li:gt(2)')
print(li)
li = doc('li:nth-child(2n)')
print(li)
li = doc('li:contains(second)')
print(li)

这里我们使用了 CSS3 的伪类选择器,依次选择了第一个 li 节点、最后一个 li 节点、第二个 li 节点、第三个 li 之后的 li 节点、偶数位置的 li 节点、包含 second 文本的 li 节点。

这里有更多伪选择器的用法
https://www.w3school.com.cn/css/index.asp

  • 参考书籍:python3网络爬虫开发实战(崔庆华著)
发布了4 篇原创文章 · 获赞 3 · 访问量 313

猜你喜欢

转载自blog.csdn.net/qq_43645530/article/details/104095623