查看原文
其他

python爬虫基础(2)—pyquery解析

Don Lex Python绿洲 2018-08-21

阅读文本需要5分钟

前篇推文介绍了爬虫的基本流程中的第一二步,现在来介绍一下爬虫的第三步——解析网页。由于前段时间推送了BeautifulSoup,所以这里就不多介绍了,今天来分享一下另外的一个解析库——PyQuery

PyQuery库也是一个非常强大又灵活的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择,PyQuery 是 Python 仿照 jQuery 的严格实现。语法与 jQuery 几乎完全相同,所以不用再去费心去记一些奇怪的方法了。

pyquery安装

直接通过pip安装

pip install pyquery

pyquery发起请求

pyquery可以直接打开html文件,也可以打开一个网站。也正是这一特性,所以可以不用requests库发起请求。例如:

1from pyquery import PyQuery as pq
2doc = pq(url = 'https://www.baidu.com',encoding = 'utf-8')
3print(doc)

这样就可以请求到百度的网页,当然pyquery也可以添加请求头和使用代理,方法跟requests是一样的,这里就不演示了。可以自己试着看能不能请求到知乎

pyquery解析方法

1. html() 和 text() ——获取相应的HTML块或文本块

1p = pq("<head><title>hello</title></head>")
2p('head').html()  # 返回<title>hello</title>
3p('head').text()  # 返回hello

2. 根据HTML标签来获取元素

1d = pq('<div><p>test 1</p><p>test 2</p></div>')  
2d('p')    # 返回[<p>,<p>]
3print d('p')  # 返回<p>test 1</p><p>test 2</p>
4print d('p').html()  # 返回test 1

注意:当获取到的元素不只一个时,html()、text()方法只返回首个元素的相应内容块

3. eq(index) ——根据给定的索引号得到指定元素
接上例,若想得到第二个p标签内的内容,则可以:

1print d('p').eq(1).html()   # 返回test 2

4. filter() ——根据类名、id名得到指定元素

1d = pq("<div><p id='fir'>test 1</p><p class='sec'>test 2</p></div>")
2d('p').filter('#fir')   # 返回<p id="fir">test 1</p>
3d('p').filter('.sec')   # 返回<p class="sec">test 2</p>

5. find() ——查找嵌套元素

1d = pq("<div><p id='fir'>test 1</p><p class='sec'>test 2</p></div>")
2d('div').find('p')   # 返回[<p#fir>, <p.sec>]
3d('div').find('p').eq(0)  #返回[<p#fir>]

6. 直接根据类名、id名获取元素

1d = pq("<div><p id='fir'>test 1</p><p class='sec'>test 2</p></div>")
2d('#fir').html() # 返回test 1
3d('.sec').html() # 返回test 2

7. 获取属性值

1d = pq("<p id='my_id'><a href='http://python.com'>hello</a></p>")
2d('a').attr('href')  # 返回http://python.com
3d('p').attr('id')  # 返回my_id

8. hasClass(name) #返回判断元素是否包含给定的类

1d = pq("<div class='my_class'></div>")
2d.hasClass('my_class')   # 返回True

9. children(selector=None) ——获取子元素

1d = pq("<span><p id='fir'>hello</p><p id='sec'>world</p></span>")
2d.children()   # 返回[<p#fir>, <p#sec>]
3d.children('#sec')   # 返回[<p#sec>]

10. parents(selector=None)——获取父元素

1d = pq("<span><p id='fir'>hello</p><p id='sec'>world</p></span>")
2d('p').parents()    # 返回[<span>]
3d('#fir').parents('span')   # 返回[<span>]
4d('#fir').parents('p')   # 返回[]

11. 元素的迭代
如果返回的结果是多个元素,如果想迭代出每个元素,可以使用items():

1info = pq(".info")
2for i in info.items():
3    i.find(".area")

实战演练

学会了上面的语法,就可以从容地应对一些简单的网页了。下面就用豆瓣图书top250来实际操练一下。

首先分析下豆瓣图书top250的链接:如:http://book.douban.com/top250?start=0 ,  每页25条数据,即步长start的值为25,一直抓到 http://book.douban.com/top250?start=225 ,即可全部爬取下来。

首先分析网页源码,找到需要抓取的信息(如下图)

(需要的信息)

所以我们可以以这个为基准,写出以下代码:

1from pyquery import PyQuery as pq
2headers = {
3    "User-Agent":
4        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36"
5}
6def get_detail(url):
7    html = pq(url=url,headers=headers)
8    tables = html('.indent table')
9    for item in tables.items():#迭代遍历
10        title = item.find('.pl2 > a').text()#书名
11        score = item.find('.rating_nums').text()#评分
12        number = item.find('.star .pl').text()#评价人数
13        if item('span').filter('.inq'): #p判断是否有.inq属性
14            quote = item.find('.inq').text()
15        else:
16            quote = ""
17        data = {
18            'title': title,
19            'score': score,
20            'number': number,
21            'quote': quote,
22        }
23        print(data)
24if __name__=="__main__":
25    for i in range(0, 250, 25):
26        url = 'http://book.douban.com/top250?start=' + str(i)
27        get_detail(url)

这样就可以在控制台显示所有的图书信息:

(图书信息)

最后

爬虫的第三步——解析网页就到这里,当然这里只是分享了pyquery的解析,其实python的解析库有很多,例如Beautifulsoup…可能有的朋友觉得只是输出在控制台没有什么意思,并且每次查看都需要重新运行一遍,这样很麻烦。所以,接下来将会给大家分享如何将数据存入数据库。

推荐阅读:


零基础学爬虫(1)—请求与响应

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存