爬虫解析库--pyquery以及css选择器的使用

对于规则的网页信息我们可以使用的解析库和选择器很多比如bs4,xpath 等,这里我们介绍一种css选择器功能非常强大的库--pyquery

安装

pip3 install pyquery

使用

环境python3

初始化

# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq
html='''
<div class="qrcodeCon">
    <div id="qrcode">
        <div class="qrcode-item qrcode-item-1">
            <div class="qrcode-img"></div>
            <div class="qrcode-text">
                    <p><b>百度</b></p>
            </div>
        </div>
    </div>
</div>
'''

doc = pd(html) # 这里doc就是一个pyquery对象我们可以对其进行选择器操作,这就是初始化
print(doc('a'))  # 这里就可以对节点下所有的子孙节点的查找a标签

# 此外还支持url初始化,以及文件初始化
doc = pd(url = 'https://www.baidu.com')  # url初始化
print(doc('title'))

doc = pd(filename='test.html')  # 文件初始化
print(doc('title'))

基本选择器
还是以上面的文本内容为例:

from pyquery import PyQuery as pq
html = '''
<div class="qrcodeCon">
    <div id="qrcode">
        <div class="qrcode-item qrcode-item-1">
            <div class="qrcode-img"></div>
            <div class="qrcode-text">
                    <p><b>百度</b></p>
                    <a>hello world</a>
            </div>
        </div>
    </div>
</div>

'''
doc = pq(html)
print(doc('.qrcodeCon .qrcode-text').text())

从上面的例子中我们可以看到pyquery的css选择器的用法很简单,给pq对象传入一个查找参数就可以了, # 表示id, . 表示类 下一级就空格一下,这样就可以轻松的定位到我们需要的节点了.

查找节点
pyquery 查找子节点的时候可以使用上面我们说的方法也可以使用一下方法:

  • 子节点
    查找子节点的时候,需要用到find()方法,此时传入的参数是css选择器,同样的以上面的文档为例,
# -*- coding: utf-8 -*-
from pyquery import PyQuery as pq
html = '''
<div class="qrcodeCon">
    <div id="qrcode">
        <div class="qrcode-item qrcode-item-1">
            <div class="qrcode-img"></div>
            <div class="qrcode-text">
                    <p><b>百度</b></p>
                    <a>hello world</a>
                    <a>hello world</a>
            </div>
        </div>
    </div>
</div>

'''
doc = pq(html)
first = doc('.qrcodeCon')
second = doc.find('.qrcode-text a')
third = doc('.qrcode-text a')
print(second)
print(third)

两个结果是一样的
<a>hello world</a>
<a>hello world</a>
<a>hello world</a>
<a>hello world</a>
另外find()所选的css选择器选择的是所有的子孙节点,如果我们只想找子节点那么可以使用 children() 方法来查找,使用方法和find()方法是一样的,对pyquery对象传入css选择句就可以得到我们想要的结果了.

  • 父节点
    我们可以使用parent()的方法来获取某个节点的父节点,我们可以给其传入css查询语句来进行特定的查询.使用方法和children()方法一样,这里是该节点的直接父节点,不会再去查找该节点的祖先节点
  • 祖先节点
    和父节点一样,我们使用parents()来实现祖先借点的查找,同样的我们可以往里面传入css选择器参数查找我们需要的祖先节点
  • 兄弟节点
    使用siblings()方法来获取兄弟节点,同样的我们可以给它传入css选择参数来获取我们需要的节点
    遍历
    我们查到的对象不是想bs4那样返回一个列表,对于单个节点来说我们可以直接转成字符串使用
    str(doc('.li'))* 方法即可,对于多个节点,我们就需要使用遍历来获取内容了---.items() 方法
    对于我们选择的多个内容我们可以:
doc = pq('html')
list_cont = doc('li').items()  # 这里会得到一个生成器
for i in list_cont:
    print(i)

获取信息

  • 获取属性
    直接调用.attr() 方法可以获取属性

doc.attr('href') # 类似这样的就可以获取他的herf属性了

我们也可以直接调用.attr属性来获取属性,例如

doc.attr.href

这两种方法获取到的内容是一样的
如果选中的是多个元素,我们调用attr()方法的时候就只会得到第一个节点的属性,这点可以自己去验证一下.当我们遇到这样的情况的时候就要使用遍历了也就是前面说的使用.items()来进行遍历操作.

  • 获取文本
    调用.text()方法可以获取选中节点里的所有文本的内容,它会忽略掉节点内部包含的所有HTML,值返回纯文字.
    但是如果想获取节点内部的HTML文本就要使用html()方法了.
    对于 html()方法返回的是第一个节点内部的HTML文本,而text()则返回了所有的节点内部的纯文本. 中间用一个空格隔开,也就是说结果返回的是一个字符串
    这个地方需要注意的是,如果结果是多个节点,并且想要获取每个节点内部的HTMl文本呢,那么就需要遍历每个节点,或者是使用text()方法来直接组合成一个字符串来获取.
    节点操作
  • addClass 和 removeClass 对class属性进行增减,具体是选中节点pyquery对象,然后进行修改

doc.removeClass('example') # 我们给这个节点移除了example类属性

doc.addClass('example') # 这里我们给这个节点增加了exmaple属性.

  • addr 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('change the world')  # 这里直接更改了节点的内容
print(li)
li.html("<span>change item</span>") # 这里修改了节点了的HTML内容
print(li)

输出结果如下:

<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link">change the world</li>
<li class="item-0 active" name="link"><span>change item</span></li>

在我们调用了attr()方法之后,li节点多了一个name属性,值为link,然后使用text方法传入文本改变了内部的文本信息,最后调用了html()方法来改变了节点的html的值
所以,如果attr()方法只传入一个参数那么就是获取这个节点的属性值,如果传入第二个参数那么是可以修改这个参数的值的. 对于text()和html()方法,如果不传入参数就是获取内部的纯文本信息和HTML文本,如果传入参数就进行赋值修改

  • remove
    可以直接操作节点进行移除操作

伪类选择器

伪类选择器功能很强大具体参看w3School来查看更多的详情,这里我直接搬运过来了.

一个普通标题 一个普通标题 一个普通标题
选择器 例子 例子描述 CSS
.class .intro 选择 class="intro" 的所有元素。 1
#id #firstname 选择 id="firstname" 的所有元素。 1
* * 选择所有元素。 2
element p 选择所有 <p> 元素。 1
element,element div,p 选择所有 <div> 元素和所有 <p> 元素。 1
element element div p 选择 <div> 元素内部的所有 <p> 元素。 1
element>element div>p 选择父元素为 <div> 元素的所有 <p> 元素。 2
element+element div+p 选择紧接在 <div> 元素之后的所有 <p> 元素。 2
[attribute] [target] 选择带有 target 属性所有元素。 2
[attribute=value] [target=_blank] 选择 target="_blank" 的所有元素。 2
[attribute~=value] [title~=flower] 选择 title 属性包含单词 "flower" 的所有元素。 2
:link a:link 选择所有未被访问的链接。 1
:visited a:visited 选择所有已被访问的链接。 1
:active a:active 选择活动链接。 1
:hover a:hover 选择鼠标指针位于其上的链接。 1
:focus input:focus 选择获得焦点的 input 元素。 2
:first-letter p:first-letter 选择每个 <p> 元素的首字母。 1
:first-line p:first-line 选择每个 <p> 元素的首行。 1
:first-child p:first-child 选择属于父元素的第一个子元素的每个 <p> 元素。 2
:before p:before 在每个 <p> 元素的内容之前插入内容。 2
:after p:after 在每个 <p> 元素的内容之后插入内容。 2
:lang(language) p:lang(it) 选择带有以 "it" 开头的 lang 属性值的每个 <p> 元素。 2
element1~element2 p~ul 选择前面有 <p> 元素的每个 <ul> 元素。 3
[attribute^=value] a[src^="https"] 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 3
[attribute=value*] a[src*="abc"] 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 3
:first-of-type p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 3
:last-of-type p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 3
:only-of-type p:only-of-type 选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 3
:only-child p:only-child 选择属于其父元素的唯一子元素的每个 <p> 元素。 3
:nth-child(n) p:nth-child(2) 选择属于其父元素的第二个子元素的每个 <p> 元素。 3
:nth-last-child(n) p:nth-last-child(2) 同上,从最后一个子元素开始计数。 3
:nth-of-type(n) p:nth-of-type(2) 选择属于其父元素第二个 <p> 元素的每个 <p> 元素。 3
:nth-last-of-type(n) p:nth-last-of-type(2) 同上,但是从最后一个子元素开始计数。 3
:last-child p:last-child 选择属于其父元素最后一个子元素每个 <p> 元素。 3
:root :root 选择文档的根元素。 3
:empty p:empty 选择没有子元素的每个 <p> 元素(包括文本节点)。 3
:target #news:target 选择当前活动的 #news 元素。 3
:enabled input:enabled 选择每个启用的 <input> 元素。 3
:disabled input:disabled 选择每个禁用的 <input> 元素 3
:checked input:checked 选择每个被选中的 <input> 元素。 3
:not(selector) :not(p) 选择非 <p> 元素的每个元素。 3
::selection ::selection 选择被用户选取的元素部分。 3

到这里就结束了,这里只是简单的介绍,更详细的需要查看官方文档,下一篇我们来做一个简单的爬取淘宝商品的小项目.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,465评论 1 45
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,113评论 0 21
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 你好! 想把每一天都过得很有意义,但这并不是一件很简单的事情。可是,还是一如既往的往前走,努力的生活着。因为...
    夏了散了阅读 235评论 0 0
  • 两周,半个月份 彻夜无眠让头脑更加清醒 冬天慢慢黄昏 融化血液里低醇的酒精 世界有时候太简单 每个人的生活被剥得一...
    慕籽阅读 117评论 0 1