爬虫解析库(10.pyquery)

2024-04-20 15:32
文章标签 解析 爬虫 pyquery

本文主要是介绍爬虫解析库(10.pyquery),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PyQuery解析库

  • pyquery内容简单介绍
    • 10.1 firstpyquery
    • 10.2 selector
    • 10.3 find方法
    • 10.4 parent和parents方法
    • 10.5 sibling方法
    • 10.6 getinfo获取节点信息
    • 10.7 process_class修改节点样式
        • 使用规则:
        • 使用要点:
    • 10.8 process_property_content
        • 使用规则:
    • 10.9 removenode移除节点
    • 10.10 pseudo_class根据样式获取指定位置的节点
    • 10.11 实战案例:抓取当当图书排行榜
    • 解析库小结:

pyquery内容简单介绍

虽然Beautiful Soup库功能强大,但是CSS选择器的功能有些弱,这里介绍一种CSS选择器较强的pyquery库。

在编写爬虫的过程中可以根据需求选择pyquery库,实际上博主使用Beautiful Soup库更多一些,这次整理权当做复习罢。

pyquery库的功能较强
本章内容:
1、什么是pyquery
2、安装
3、基本用法
4、查找子节点、父节点、兄弟节点以及获取节点信息
5、修改和删除结点
6、伪类选择器、
7、实战:request和pyquery结合抓取分析HTML代码

10.1 firstpyquery

案例:4种方式将HTMl文档传入PyQuery对象

import pyquery
from pyquery import PyQuery as pq
html = '''
<div><ul><li class="item1" value1="1234" value2 = "hello world"><a href="https://geekori.com"> geekori.com</a></li><li class="item"><a href="https://www.jd.com"> 京东商城</a></li>        </ul><ul><li class="item3"><a href="https://www.taobao.com">淘宝</a></li><li class="item" ><a href="https://www.microsoft.com">微软</a></li><li class="item2"><a href="https://www.google.com">谷歌</a></li></ul>
</div>'''
# 使用字符串形式将HTML文档传入PyQuery对象
doc = pq(html)
# 输出<a>节点的将href属性值和文本内容
for a in doc('a'):print(a.get('href'),a.text)# 使用URL形式将HTML文档传入PyQuery对象
doc = pq(url='https://www.jd.com')
# 输出页面的<title>节点的内容
print(doc('title'))import requests
# 抓取HTML代码,并将HTML代码传入PyQuery对象
doc = pq(requests.get('https://www.jd.com').text)
print(doc('title'))# 从HTML文件将HTMl代码传入PyQuery对象
doc = pq(filename='demo.html')
# 输出<head>节点的内容
print(doc('head'))

10.2 selector

  1. 通过doc的CSS选择器获取节点内容和属性
from pyquery import PyQuery as pq
html = '''
<div id="panel"><ul class="list1"><li class="item1" value1="1234" value2 = "hello world"><a href="https://geekori.com"> geekori.com</a></li><li class="item"><a href="https://www.jd.com"> 京东商城</a></li>        </ul><ul class="list2"><li class="item3"><a href="https://www.taobao.com">淘宝</a></li><li class="item" ><a href="https://www.microsoft.com">微软</a></li><li class="item2"><a href="https://www.google.com">谷歌</a></li></ul>
</div>'''
# 创建PyQuery对象
doc = pq(html)
# 提取id属性值为panel,并且在该节点中所有class属性值为list1的所有节点
result = doc('#panel .list1')
# 输出result的类型,仍然为PyQuery对象
print(type(result))
print(result)
# 在以result为根的基础上,提取其中class属性值为item的所有节点
print(result('.item'))
# 提取其中的第2个a节点的href属性值和文本内容
print(result('a')[1].get('href'),result('a')[1].text)
print()
  1. 抓取京东商城导航条连接文本
# 抓取京东商城导航条连接文本
import requests
# 请求京东商城首页,并将返回的HTML代码传入pq对象
doc = pq(requests.get('https://www.jd.com').text)
# 提取第1个ul节点
group1 = doc('#navitems-group1')# 输出前4个链接的文本
print(group1('a')[0].text,group1('a')[1].text,group1('a')[2].text,group1('a')[3].text)
# 输出中间4个链接的文本
group2 = doc('#navitems-group2')
print(group2('a')[0].text,group2('a')[1].text,group2('a')[2].text,group2('a')[3].text)
# 输出后2个链接的文本
group3 = doc('#navitems-group3')
print(group3('a')[0].text,group3('a')[1].text)

10.3 find方法

  1. 查找子节点需要使用find方法,使用该方法需要将CSS选择器作为参数传入
  2. find方法不仅仅是直接子节点还有子孙节点
  3. 如果只想获取子节点,需要使用children方法

test.html文档内容:

<div id="panel"><ul class="list1"><li class="item" value1="1234" value2 = "hello world"><a href="https://geekori.com"> geekori.com<a>ok</a></a></a></li><li class="item1" ></li></ul><ul class="list2"><li class="item3"><a href="https://www.taobao.com">淘宝</a></li><li class="item"  value1="4321" value2 = "世界你好" ><a href="https://www.microsoft.com">Microsoft</a></li><li class="item2"><a href="https://www.google.com">谷歌</a></li></ul>
</div>
from pyquery import PyQuery as pq
from lxml import etree
# 分析test.html文件
doc = pq(filename='test.html')
# 查找所有class属性值为list1的节点,只有第1个ul节点满足条件
result = doc('.list1')
# 查找所有的a节点,包括子孙节点
aList = result.find('a')
print(type(aList))
for a in aList:# 输出每一个查找到的a节点print(str(etree.tostring(a,pretty_print=True,encoding='utf-8'),'utf-8'))print("_________________________________")
# 查找所有class属性值为item的所有节点,只有第2个li节点和倒数第2个li节点满足条件
result = doc('.item')
aList = result.children('a')
for a in aList:# 输出每一个查找到的a节点print(str(etree.tostring(a,pretty_print=True,encoding='utf-8'),'utf-8'))

10.4 parent和parents方法

  1. 使用parent方法可以查找直接父节点
  2. 通过parents方法可以查找所有的父节点。
from pyquery import PyQuery as pq
# 分析test.html
doc = pq(filename='test.html')
# 获取class属性值为item的所有节点
result = doc('.item')
# 查找这些节点的直接父节点
print(result.parent())
print("_______________")
print('父节点个数:',len(result.parents()))
# 查找这些节点的所有父节点
print(result.parents())
# 查找id属性值为panel的父节点
print('父节点数:',len(result.parents('#panel')),'节点名:',result.parents('#panel')[0].tag)

10.5 sibling方法

使用sibling方法查找class属性值为item的结点的所有兄弟节点,以及class属性值为item2的兄弟节点
Tip: 如果读取的html内容有乱码,可以用前面几种解码方式进行解码

from pyquery import PyQuery as pq
doc = pq(filename='test.html')
result = doc('.item')
# 查找class属性值为item的结点和所有兄弟节点
print(result.siblings())
print('____________________________')
# 查找class属性值为item2的兄弟节点
print(result.siblings('.item2'))

10.6 getinfo获取节点信息

使用规则:

1、节点名称,使用tag属性
2、节点属性,使用lxml.etree._Element类的get方法
3、节点文本,使用PyQuery的text方法
4、整个节点的HTMl代码,使用etree的tostring函数
5、节点内部的HTML代码,使用PyQuery的html方法
from pyquery import PyQuery as pq
html = '''
<div id="panel"><ul class="list1"><li class="item" value1="1234" value2 = "hello world">Hello123<a href="https://geekori.com"> geekori.com</a>World</li><li class="item1" ></li></ul><ul class="list2"><li class="item3"><a href="https://www.taobao.com">淘宝</a></li><li class="item"  value1="4321" value2 = "世界你好" ><a href="https://www.microsoft.com">微软</a></li><li class="item2"><a href="https://www.google.com">谷歌</a></li></ul>
</div>
'''doc = pq(html)
result = doc('.item')
print(type(result))
print("___________获取名称___________")
print(type(result[0]))
# 获取第1个li节点的名称
print(result[0].tag)
# 获取第2个li节点的名称
print(result[1].tag)
print('___________获取属性___________')
# 获取第1个li节点的value1属性的值
print('value1:',result[0].get('value1'))
# 获取第1个li节点的value2属性的值
print('value2:',result.attr('value2'))
# 获取第1个li节点的value2属性的值
print('value2:',result.attr.value2)
print("______________________________")
for li in result.items():print(type(li))# 获取查询结果中每一个结点的value2属性值print(li.attr.value2)for li in result:print(type(li))# 获取查询结果中每一个结点的value2属性值print(li.get('value2'))print("_______________获取文本_______________")
# 获取查询结果中第1个li节点的文本内容
print(result.text())
print('result.text()类型:',type(result.text()))
for node in result:# 获取查询结果中每一个节点的文本内内容print(node.text)print("_______________节点HTML代码_______________")
from lxml import etree
for node in result:# 获取查询结果中每一个节点的完整HTML代码print(str(etree.tostring(node,pretty_print=True),'utf-8'))print('_______________获取节点内部HTML代码_______________')
# 获取查询结果中第1个li节点内的完整HTML代码
print(result.html())

10.7 process_class修改节点样式

使用规则:
  1. addClass方法可以向节点的class属性添加样式
  2. removeClass方法可以向节点的class属性移除样式
使用要点:
         1、用pyquery查询节点时,如果需要制定多个样式,每个样式前面需要加(.),而且多个样式要首尾相连,中间不能有空格2、添加和删除样式时,样式名不能带(.),否则会将(.)作为样式名的一部分添加到class属性中3、添加和删除多个样式时,多个样式之间用空格分隔4、如果要操作的是多个节点,那么addClass方法和removeClass方法同样有效
from pyquery import PyQuery as pq
html = '''
<div id="panel"><ul class="list1" ><li class="item1 item2 item3" >谷歌</li><li class="item1 item2">微软</li></ul></div>
'''
doc = pq(html)
# 查询class属性值为item1,item2的节点
li = doc('.item1.item2')
print(li)
# 为所有查询结果节点添加一个名为myitem的样式
li.addClass('myitem')
print(li)
# 移除查询结果中所有节点名为item1的样式
li.removeClass('item1')
print(li)
# 移除查询结果中所有节点的两个样式:item2和item3
li.removeClass('item2 item3')
print(li)
# 为查询记过的所有节点添加两个样式:class1和class2
li.addClass('class1 class2')
print(li)

10.8 process_property_content

使用规则:
1. 使用attr方法可以为节点添加新的属性,如果存在,则修改
2. 使用removeAttr方法可以移除节点属性
3. 使用text和html方法修改节点中的文本内容如果text没有参数,则返回所有节点的文本,用空格隔开如果html没有参数,只返回第1个节点的文本内容

10.9 removenode移除节点

使用remove方法可以删除结点,接收一个字符串类型的参数,用于指定要删除的节点名
如果不指定参数,则删除当前节点

from pyquery import PyQuery as pqhtml = '''
<div id="panel"><ul class="list1" ><li class="item1 item2" >谷歌<p>微软</p>Facebook</li></ul></div>
'''
doc = pq(html)
li = doc('.item1.item2')
# 获取li节点中的所有节点
print(li.text())
print('______________<p>微软</p>已经被删除______________')
# 删除p节点
li.remove('p')
# 重新获取li节点中所有的文本
print(li.text())li = doc('.item1.item2')
# 先找到p节点,然后删除
print(li.find('p').remove())
print(li.text())

10.10 pseudo_class根据样式获取指定位置的节点

import pyquery
from pyquery import PyQuery as pq
html = '''
<div><ul><li class="item1" ><a href="https://geekori.com"> geekori.com</a></li><li class="item"><a href="https://www.jd.com"> 京东商城(https://www.jd.com)</a></li><li class="item3"><a href="https://www.taobao.com">淘宝</a></li><li class="item" ><a href="https://www.microsoft.com">微软</a></li><li class="item2"><a href="https://www.google.com">谷歌</a></li>              </ul></div>
'''
doc = pq(html)
# 选取第1个节点
li = doc('li:first-child')
print(li)
# 选取最后一个li节点
li = doc('li:last-child')
print(li)
# 选取第3个li节点
li = doc('li:nth-child(3)')
print(li)
# 选取索引大于2的li节点(索引从0开始)
li = doc('li:lt(2)')
print(li)
# 选取所有大于3的li节点(所有从0开始)
li = doc('li:gt(3)')
print(li)
# 选择序号为奇数的li节点,第一个li节点的序号为1
li = doc('li:nth-child(2n+1)')
print(li)
# 选择序号为偶数的li节点
li = doc('li:nth-child(2n)')
print(li)
# 选取文本内容包含com的所有节点
all = doc(':contains(com)')
print(len(all))
# 输出每一个选取结果的节点名
for t in all:print(t.tag, end=' ')

10.11 实战案例:抓取当当图书排行榜

注:也可以自己尝试分析其他网页内容,不过有的内容需要用到Cookie,Cookie是十分重要的东西,务必按照前面的方法,将Cookie放入header请求头中,即可获取页面内容。

本案例没有使用Cookie。

ps = '''分析url:http://search.dangdang.com/?key=python&act=input&page_index=2....page_index=3                                                        '''
from pyquery import PyQuery as pq
import requests
import time
# 用于下载指定URL页面
def get_one_page(url):try:res = requests.get(url)if res.status_code == 200:return res.textreturn Noneexcept Exception:return None
# 分析搜索也是一个产生器函数
def parse_one_page(html):doc = pq(html)# 提取包含所有li节点的ul节点ul = doc('.bigimg')liList = ul('li')# 对li节点集合进行迭代,这里要注意,必须使用items方法返回可迭代对象,这样每一个item才会是PyQuery对象for li in liList.items():# 获取点前li节点中第1个a节点a = li('a:first-child')# 获取图书主页的URlhref = a[0].get('href')# 获取图书名称title = a[0].get('title')# 抓取class属性值为search_now_price的节点span = li('.search_now_price')# 获取价格price = span[0].text[1:]# 抓取class属性值为search_book_author的节点p = li('.search_book_author')# 获取图书作者author = p('a:first-child').attr('title')# 获取图书出版日期date = p('span:nth-child(2)').text()[1:]# 获取图书出版社publisher = p('span:nth-child(3) > a').text()# 获取图书评论数comment_number = li('.search_comment_num').text()[:3]# 获取图书简介detail = li('.detail').text()yield{'href':href,'title':title,'price':price,'author':author,'date':date,'publisher':publisher,'comment_number':comment_number,'detail':detail}if __name__ == '__main__':# 产生前三页的URLurls = ['http://search.dangdang.com/?key=python&act=input&page_index={}'.format(str(i)) for i in range(1,4)]for url in urls:# 获取每一个搜索页面对应的迭代图书信息book_infos = parse_one_page(get_one_page(url))for book_info in book_infos:# 输出每一本书的图书信息print(book_info)time.sleep(1)

解析库小结:

  1. 7-10一共介绍了4中常用解析库的内容,包括正则表达式,lxml和XPath,Beautiful Soup 和 pyquery库,这些解析库各有各自的优势,根据自己的需要选取合适的解析方法。
  2. 解析库的内容到此为止,后面将讲解如何将抓取的数据存储起来,包括数据库、excel文档等等,持续更新,拭目以待…

这篇关于爬虫解析库(10.pyquery)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920628

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can