ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python逆向爬虫之pyquery,非常详细

2022-08-17 14:02:18  阅读:196  来源: 互联网

标签:pyquery Python doc 爬虫 li item html print 节点


系列目录

Python逆向爬虫之pyquery

pyquery是一个类似jquery的python库,它实现能够在xml文档中进行jQuery查询,pyquery使用lxml解析器进行快速在xml和html文档上操作,它提供了和jQuery类似的语法来解析HTML文档,支持CSS选择器,使用非常方便。

一、pyquery安装

pip install pyquery

二、pyquery对象初始化

pyquery首先需要传入HTML文本来初始化一个pyquery对象,它的初始化方式有多种,如直接传入字符串,传入URL或者传入文件名。

2.1 字符串初始化

from pyquery import PyQuery as pq

html = """
<div id="wenzhangziti" class="article 389862">
    <p>人生是一条没有尽头的路,不要留恋逝去的梦,把命运掌握在自己手中,让我们来掌握自己的命运,
    别让别人的干扰与诱惑,别让功名与利禄,来打翻我们这坛陈酿已久的命运之酒!</p>
</div>
"""
doc = pq(html)
print(type(doc))
print(doc('p').text())

2.2 URL初始化

from pyquery import PyQuery as pq

doc = pq(url='https://www.cnblogs.com/chenyangqit/p/15121161.html')
print(type(doc))
print(doc('title'))

PyQuery能够从url加载一个html文档,之际上是默认情况下调用python的urllib库去请求响应,如果requests已安装的话它将使用requests来请求响应,那我们就可以使用request的请求参数来构造请求了,实际请求如下:

from pyquery import PyQuery as pq
import requests
 
doc=pq(requests.get(url='https://www.cnblogs.com/chenyangqit/p/15121161.html').text)
print(type(doc))
print(doc('title'))

三、CSS选择器

在使用属性选择器中,使用属性选择特定的标签,标签和CSS标识必须引用为字符串,它会过滤筛选符合条件的节点打印输出,返回的是一个PyQuery类型对象。

from pyquery import PyQuery as pq
import requests
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>
'''
doc=pq(html,parser='html')
print(doc('#container .list .item-0 a'))
print(doc('.list .item-1'))

四、查找节点

PyQuery使用查询函数来查询节点,同jQuery中的函数用法完全相同。

4.1 查找子节点和子孙节点

使用find()方法获取子孙节点,children()获取子节点,使用以上的HTML代码测试。

doc=pq(html,parser='html')
print('find:',doc.find('a'))
print('children:',doc('li').children('a'))

4.2 获取父节点和祖先节点

parent()方法获取父节点,parents()获取祖先节点。

doc(.list).parent()
doc(.list).parents()

4.3 获取兄弟节点

siblings()方法用来获取兄弟节点,可以嵌套使用,传入CSS选择器即可继续匹配。

doc('.list .item-0.active').siblings('.active')

五、遍历

对于pyquery的选择结果可能是多个字节,也可能是单个节点,类型都是PyQuery类型,它没有返回列表等形式,对于当个节点我们可指直接打印输出或者直接转换成字符串,而对于多个节点的结果,我们需要遍历来获取所有节点可以使用items()方法,它会返回一个生成器,循环得到的每个节点类型依然是PyQuery类型,所以我们可以继续方法来选择节点或属性,内容等。

lis=doc('li').items()
for i in lis:
 	print(i('a'))

六、获取信息

attr()方法用来获取属性,如返回的结果有多个时可以调用items()方法来遍历获取。

doc('.item-0.active a').attr('href') #多属性值中间不能有空格

text()方法用来获取文本内容,它只返回内部的文本信息不包括HTML文本内容,如果想返回包括HTML的文本内容可以使用html()方法,如果结果有多个,text()方法会方法所有节点的文本信息内容并将它们拼接用空格分开返回字符串内容,html()方法只会返回第一个节点的HTML文本,如果要获取所有就需要使用items()方法来遍历获取了。

from pyquery import PyQuery as pq
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>
'''
doc=pq(html,parser='html')
print('text:',doc('li').text()) #获取li节点下的所有文本信息
lis=doc('li').items()
for i in lis:
    print('html:',i.html()) #获取所有li节点下的HTML文本

七、节点操作

pyquery提供了一系列方法来对节点进行动态修改,如添加一个class,移除某个节点,修改某个属性的值。

addClass()增加Class,removeClass()删除Class

attr()增加属性和值,text()增加文本内容,html()增加HTML文本,remove()移除

from pyquery import PyQuery as pq
import requests
html='''
<div id="container">
 <ul class="list">
   <li id="1">first item</li>
   <li class="item-1"><a href="link2.html">second item</a></li>
   <li class="item-2 active"><a href="link3.html"><span class="bold">third item</span></a></li>
   <li class="item-3 active"><a href="link4.html">fourth item</a></li>
   <li class="item-4"><a href="link5.html">fifth item</a></li>
  </ul>
 </div>
'''
doc=pq(html,parser='html')
print(doc('#1'))
print(doc('#1').add_class('myclass')) #增加Class
print(doc('.item-1').remove_class('item-1')) #删除Class
print(doc('#1').attr('name','link')) #添加属性name=link
print(doc('#1').text('hello world')) #添加文本
print(doc('#1').html('<span>changed item</span>')) #添加HTML文本
print(doc('.item-2.active a').remove('span')) #删除节点
  • after()在节点后添加值
  • before()在节点之前插入值
  • append()将值添加到每个节点
  • contents()返回文本节点内容
  • empty()删除节点内容
  • remove_attr()删除属性
  • val()设置或获取属性值

另外还有很多节点操作方法,它们和jQuery的用法完全一致,详细请参考:http://pyquery.readthedocs.io/en/latest/api.html

八、伪类选择器

CSS选择器之所以强大,是因为它支持多种多样的伪类选择器,如:选择第一个节点,最后一个节点,奇偶数节点等。

from pyquery import PyQuery as pq

html = '''
<div id="container">
 <ul class="list">
   <li id="1">first item</li>
   <li class="item-1"><a href="link2.html">second item</a></li>
   <li class="item-2 active"><a href="link3.html"><span class="bold">third item</span></a></li>
   <li class="item-3 active"><a href="link4.html">fourth item</a></li>
   <li class="item-4"><a href="link5.html">fifth item</a></li>
  </ul>
  <div><input type="text" value="username"/></div> 
</div>
'''
doc = pq(html, parser='html')
print('第一个li节点:', doc('li:first-child'))  # 第一个li节点
print('最后一个li节点:', doc('li:last_child'))  # 最后一个li节点
print('第二个li节点:', doc('li:nth-child(2)'))  # 第二个li节点
print('第三个之后的所有li节点:', doc('li:gt(2)'))  # 第三个之后的所有li节点
print('偶数的所有li节点:', doc('li:nth-child(2n)'))  # 偶数的所有li节点
print('包含文本内容的节点:', doc('li:contains(second)'))  # 包含文本内容的节点
print('索引第一个节点:', doc('li:eq(0)'))
print('奇数节点:', doc('li:even'))
print('偶数节点:', doc('li:odd'))

更多伪类参考:http://pyquery.readthedocs.io/en/latest/pseudo_classes.html

更多css选择器参考:http://www.w3school.com.cn/cssref/css_selectors.asp

九、爬取豆瓣排行榜

from pyquery import PyQuery as pq
import re

def main():

    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
    }

    baseurl = "https://movie.douban.com/top250?start="

    doc = pq(url=baseurl, headers=head)

    list = []

    for i in doc('.grid_view li').items():

        vidow = {
            "title": "",
            "year": "",
            "score": 0,
            "num": 0
        }

        for item in i.items('li'):
            vidow['title'] = item('.hd').text().replace('[可播放]', '').replace("\xa0", " ")

            obj = re.compile('\d{4}', re.S)
            result = obj.finditer(item('.bd p:nth-child(1)').text())
            for year in result:
                vidow['year'] = year.group()

        for item in i.items(".rating_num"):
            vidow['score'] = item.text()

        for item in i.items(".star span:nth-child(4)"):
            vidow['num'] = item.text().replace("人评价", "")

        list.append(vidow)

    print(list)

if __name__ == '__main__':

    main()

标签:pyquery,Python,doc,爬虫,li,item,html,print,节点
来源: https://www.cnblogs.com/chenyangqit/p/16594908.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有