Python爬虫-PyQuery

Python爬虫-PyQuery

一些看法

关于数据提取的四个主流方法就回顾完了,当然不用也不必全会。我个人认为正则是一定要OK的,其余三个拣一个上手即可。剩下部分,总得达到“开书了然”的境界吧。毕竟说不定什么时候就需要阅览别人的代码,你怎么管得找人家用xpath呢还是用PyQuery呢?
这是最后一次在句子迷实战,此次目标书籍:《年华是无效信》——是我钟爱!

使用

from pyquery import PyQuery as pq
doc = pq(html)

语法

初始化

  1. 除了直接初始化拿到的网页,还可以有以下两种方法
    a. pq(url="")直接获取网页(不建议,没有隐藏爬虫信息吧)
    b. pq(filename="")针对本地文件
<html><head><title>The Dormouse's story</title>title></head>head>                                                         
   <body>
         <p class="title"><b>The Dormouse's story</b>b></p>p>

         <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">Elsie</a>a>,
         <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>a> and
         <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>a>;
         and they lived at the bottom of a well.</p>p>

         <p class="story">...</p>p>                                         

下面,仍用之前使用过的残缺的爱丽丝文档演示

选择标签

  1. doc("p")直接选择p标签
  2. doc(".title")通过类名选择标签
  3. doc("#link1")通过id名选择标签
    这里写图片描述
  4. 如果需要,可以一级一级的筛选
    doc("body .story #link3")表示body标签下class为story的标签、下的id为link3的标签
    这里写图片描述
  5. 如果通过标签寻找返回太多,需要标签中其他属性值来精确定位,可以参数里多个值,中间不需要空格doc("a.sister#link2")
    这里写图片描述
    (为什么我只返回两个?因为之前忘了,现在才加的,而我已经移除了id=#link1的标签了)

  6. find()查找所有符合的标签,可以标签名,类,id这里写图片描述

  7. children()返回子标签,且只返回子标签(不管孙子标签)
  8. parent()返回父标签,parents()返回父级以上标签
  9. siblings()返回兄弟标签

遍历

  1. doc("a").items()返回的是一个迭代器
    这里写图片描述

对标签操作

上述操作之后拿到的是由对象组成的列表,现在我们要对它进一步操作
这里写图片描述

  1. doc.(".title").html()class为title的标签下的内容
    这里写图片描述
    需要注意的是,如果返回的列表中对象不止一个,该方法默认只对第一个起作用;并且同BeautifulSoup一样,会自行补充缺失的标签。所以使用时,最好精确到返回对象只有一个,除非你很清楚自己在做什么
    这里写图片描述
  2. 获取属性值的两种方法doc("#link1").attr("href")或者doc("#link1".attr.href)
    这里写图片描述
  3. 也可以修改属性的值doc("#link1").attr("href", "baidu.com")
    这里写图片描述
    如果标签的属性存在,就修改属性的值;如果属性不存在,就添加该属性和对应的值
  4. 也能删除你定位的标签doc("#link1").remove()
    这里写图片描述
  5. 提取标签中的文本信息doc("#link2").text()
  6. 增删标签的class值doc("#link2").addClass()/doc("#link2").removeClass()
    这里写图片描述

伪类选择器

为了更精确定位元素,还有以下操作
1. doc("p:first-child")定位第一个p标签
2. doc("p:last-child")定位第最后一个p标签
3. doc("p:gt(2)")定位索引大于2的p标签(从0开始计数)
4. doc("p:nth-child(2)")定位第二个p标签
5. doc("p:nth-child(2n)")定位索引为偶数的p标签
6. doc("p:contains(story)")定位文本信息中有“story”的p标签
这里写图片描述

*eq()的使用

区别于BeautifulSoup,我们拿到返回列表之后,不能单纯的使用列表的索引方式取出列表中的对象进行操作,这样返回的是字符串类型,需要用eq()
这里写图片描述

代码

网址目标:句子迷。

def parse_html(html):
    data = {}

    doc = pq(html)
    sentences = doc(".xlistju")
    loveds = doc(".views-field-ops a.flag-action")
    comments = doc(".comment-link")
    # 对于这种查找结果直接返回列表,最好保存数据前打印各自的长度
    # 网页中可能出现class值相同,但不是需要的标签

    with open("Invalid_letter.txt", "a", encoding="utf-8") as ob:
        for i in range(len(sentences)):
            data["sentence"] = sentences.eq(i).text()
            data["loved"] = loveds.eq(i).text()
            data["comment"] = comments.eq(i).text()

            ob.write(json.dumps(data, ensure_ascii=False))
            ob.write("\n")

这里写图片描述

完整代码已经上传GitHub,包括前面使用xpth,”美丽汤”,正则的实战案例,放在一起可以比较四个优劣。

猜你喜欢

转载自blog.csdn.net/qq_41359051/article/details/80744668