用pyquery5行代码爬取百度热点新闻

导读:学习python爬虫很久了,一直习惯于requests抓取+xpath解析的两步走套路,直到我今天发现了pyquery这个爬虫利器后,才意识到python的世界没有最简,只有更简……

2020-03-06 21:22:12


01 pyquery简介

pyquery是Python的一个第三方爬虫库,仿照 jQuery实现,语法与js十分相像。如果有js基础,那么应用pyquery简直是平步青云。pyquery自带网页解析和信息提取功能,所以应用起来会非常简洁。

pyquery安装(要求cssselect和lxml库支持):

pip install pyquery

安装好pyquery包后,默认可在..\Python\Python37\Lib\site-packages目录下找到pyquery文件,主要包括5个.py文件,分别是pyquery.py、 opener.py、 cssselectpath.py、 text.py以及一个初始化文件__init__.py,其中pyquery是主应用模块,内部调用其他3个模块。在pyquery模块中,实现了多个类,其中PyQuery是主类,继承列表类(所以列表的所有接口PyQuery都可以调用)。如下命令获取其所有方法接口:

from pyquery import PyQuery as pq
dir(pq)

02 pq初始化

pyquery的初始化可接收4种格式的参数,分别是字符串类型、html、html文件地址以及需要请求的ur相关信息,尤其是支持请求url的初始化方式,大大简化了的爬虫代码实现。

  • 接收字符串
doc = pq("<html>hello, world</html>")
  • 接收html
doc = pq(etree.fromstring("<html>hello, world</html>")
  • 接收html文件地址
doc = pq(filename=path_to_html_file)
  • 接受URL及相关信息

这里具体讲解pyquery接收url相关信息的实现方式。查看pyquery初始化方法,其接收不定参数和字典参数如下:

def __init__(self, *args, **kwargs):
        html = None
        elements = []
        self._base_url = None
        self.parser = kwargs.pop(‘parser‘, None)

        if (len(args) >= 1 and
                isinstance(args[0], string_types) and
                args[0].split(‘://‘, 1)[0] in (‘http‘, ‘https‘)):
            kwargs[‘url‘] = args[0]
            if len(args) >= 2:
                kwargs[‘data‘] = args[1]
            args = []
        pass

当接受参数满足:①参数个数大于等于1个、②第一个参数为字符串类型、③第一个参数可以解析为http或https格式,则提取url及其相关信息(如headers等)并赋值给字典参数kwargs,进行网页解析:

if kwargs:
    # specific case to get the dom
    if ‘filename‘ in kwargs:
        html = open(kwargs[‘filename‘])
    elif ‘url‘ in kwargs:
        url = kwargs.pop(‘url‘)
        if ‘opener‘ in kwargs:
            opener = kwargs.pop(‘opener‘)
            html = opener(url, **kwargs)
        else:
            html = url_opener(url, kwargs)
        if not self.parser:
            self.parser = ‘html‘
        self._base_url = url
    else:
        raise ValueError(‘Invalid keyword arguments %s‘ % kwargs)

当前一步提取的字典参数不为空,且包含"url"键值时则解析为需要进行网页请求。网页请求中当初始化参数中指定了解析器opener时,则调用指定解析器,否则使用pyquery自定义的url_opener方法进行解析。 进一步查看pyquery自定义的url_opener方法:

try:
    import requests
    HAS_REQUEST = True
except ImportError:
    HAS_REQUEST = False
--------------
def url_opener(url, kwargs):
    if HAS_REQUEST:
        return _requests(url, kwargs)
    return _urllib(url, kwargs)
--------------
def _requests(url, kwargs):
    encoding = kwargs.get(‘encoding‘)
    method = kwargs.get(‘method‘, ‘get‘).lower()
    session = kwargs.get(‘session‘)
    if session:
        meth = getattr(session, str(method))
    else:
        meth = getattr(requests, str(method))
    pass
--------------
def _urllib(url, kwargs):
    method = kwargs.get(‘method‘)
    url, data = _query(url, method, kwargs)
    return urlopen(url, data, timeout=kwargs.get(‘timeout‘, DEFAULT_TIMEOUT))

至此,我们知道pyquery的自定义解析器采用如下规则:

    • 如果系统当前安装了requests库(第三方库,使用前需手动安装),则调用_requests方法,其中还根据初始化参数中是否指定了session来进一步区分
    • 否则,则调用urllib库(python自带的网页解析库)urlopen方法进行解析

可见,pyquery相当于会自动调用requests库或默认的urllib库进行网页解析,且以前者优先,并支持携带requests的session进行解析。

03 选择器

pyquery支持与CSS一致的选择器实现方法:

from pyquery import PyQuery as pq
html = ‘‘‘
    <div id="test">
        <ul class="c1">
            hello
            <link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
        </ul>
        <ul class="c2">
            world
            <link href="http://321.com">test</link>
            <link href="http://654.com">for</link>
            <link href="http://987.com">spider</link>
        </ul>
    </div>
‘‘‘
doc = pq(html)
print(type(doc))#<class ‘pyquery.pyquery.PyQuery‘>
print(doc("div#test>ul.c1 link"))
"""
<link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
"""

其中:

  • pyquery初始化后为PyQuery对象类型
  • pyquery使用字符串识别标签和CSS标识
  • 父标签和子标签间可以用>,也可以用空格
  • 可以通过属性选择特定标签,其中id用"#",class用"."

04 查找节点

pyquery可以很容易实现查找父类、子类、兄弟节点,主要方法如下:

  • find()选择所有满足条件的子节点
item=doc(".c1")
link = item.find(‘link‘)
print(link)
"""
<link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
            """
  • parents()选择父节点
item=doc(".c1")
p = item.parents()
print(p)
"""
<div id="test">
        <ul class="c1">
            hello
            <link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
        </ul>
        <ul class="c2">
            world
            <link href="http://321.com">test</link>
            <link href="http://654.com">for</link>
            <link href="http://987.com">spider</link>
        </ul>
    </div>
"""
  • children()选择子节点
item=doc(".c1")
c = item.children()
print(c)
"""
<link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
"""
  • siblings()选择兄弟节点
item=doc(".c1")
s = item.siblings()
print(s)
"""
<ul class="c2">
            world
            <link href="http://321.com">test</link>
            <link href="http://654.com">for</link>
            <link href="http://987.com">spider</link>
        </ul>
"""

05 获取信息

在完成选择节点的基础上,pyquery获取信息实现就非常简单。常用的方法如下:

  • items()获取所有匹配结果(返回一个生成器)
items=doc(".c1 link").items()
print(items)#<generator object PyQuery.items at 0x000001F124C23390>
  • attr()获取属性信息
for item in items:
    print(item.attr(‘href‘))
"""
http://123.com
http://456.com
http://789.com
"""
  • text()获取文本信息
for item in items:
    print(item.text())
"""
this
is
pyquery
"""
  • html()获取相应html文本
h = doc(‘ul‘).html()
print(h)
"""
hello
            <link href="http://123.com">this</link>
            <link href="http://456.com">is</link>
            <link href="http://789.com">pyquery</link>
"""

06 pyquery实战

了解了基本操作,我们就可以应用pyquery进行快速的网页爬取了。以百度热点新闻为例,进行简单的接口分析获得url后只需要5行代码就可以轻松获取40条搜索热点标题,简直不能比这更方便了!

from pyquery import PyQuery  as pq
doc = pq(url=‘http://top.baidu.com/buzz?b=1&fr=20811‘, encoding = ‘gb18030‘)
items = doc("td.keyword>a.list-title").items()
hots = [item.text() for item in items]
print(hots)
# [‘春雨医生获投资‘, ‘肖战ins头像‘, ‘洛杉矶马拉松‘, ‘韦特斯加盟湖人‘, ‘甘薇弃优先分配权‘, ‘硕士研究生扩招‘, ‘毛剑卿退役‘, ‘皮亚琴察市长确诊‘, ‘67台ECMO发往湖北‘, ‘伊朗国家动员计划‘, ‘雷神山机器人上岗‘, ‘上海马拉松升级‘, ‘湖北人民免费看剧‘, ‘草地贪夜蛾入侵‘, ‘快女喻佳丽结婚‘, ‘惠普拒绝施乐收购‘, ‘汪曾祺百年诞辰‘, ‘美国对塔利班空袭‘, ‘鼓浪屿将恢复开放‘, ‘Faker2000杀‘, ‘小罗因假护照被捕‘, ‘杨蓉经纪公司声明‘, ‘库里复出23分‘, ‘英国确诊人数翻倍‘, ‘英国再现集装箱藏人案‘, ‘Facebook员工确诊‘, ‘普利兹克建筑奖‘, ‘卢浮宫重新开放‘, ‘史酷比狗预告‘, ‘黄子佼孟耿如结婚‘, ‘法国政府征用口罩‘, ‘76人vs湖人‘, ‘龙卷风袭击美国‘, ‘邓肯执教首胜‘, ‘英国首例死亡病例‘, ‘布隆伯格退出大选‘, ‘库里复出‘, ‘罗永浩宣布开直播‘, ‘湖人战胜76人‘, ‘热刺大将怒揍球迷‘]

当然,为了实现反爬能力更强和更加高效的爬虫,可以在pyquery初始化时传入更多参数,例如headers、session和timeout等。

07 总结

  • pyquery是一个高度集成的python第三方爬虫库,方法众多、实现简洁
  • pyquery内置了网页解析,会首先尝试调用requests库,若当前未安装则调用python内置urllib库解析
  • pyquery解析提取采用类似CSS选择器的方式进行
  • pyquery支持简洁的节点选择、属性和文本提取操作
  • pyquery还有很多其他方法,包括节点操作、伪类选择器等,但爬虫一般不需要用到

原文地址:https://www.cnblogs.com/luanhz/p/12430948.html

时间: 2024-10-29 05:21:27

用pyquery5行代码爬取百度热点新闻的相关文章

python爬虫-20行代码爬取王者荣耀所有英雄图片,小白也轻轻松松

1.环境 python3.6 需要用到的库: re.os.requests 2.简介 王者荣耀可以算得上是比较受欢迎的手游之一了,应该有不少的人都入坑过农药,我们今天的目的就是要爬取王者荣耀的高清英雄壁纸,包括这些英雄的皮肤,不废话了,go! 3.分析 首先,我们打开王者荣耀的英雄资料 然后,日常F12打开浏览器的开发者工具 可以看到这里返回了一个json数据,里面包含了英雄的名字(cname),皮肤名字(skin_name),英雄id(ename)这个id后面的皮肤有用 具体某一个英雄的网址,

几行代码抓取百度首页

python中源码位置(以urllib为例):    python中自带的模块:        /usr/lib/python3.5/urllib/request.py(python3)        /usr/lib/python2.7/urllib2.py(python2)    python的第三方模块:        /usr/local/lib/python2.7/site-packages/ 注意:关于urllib模块,python3中的导入方法为import urllib.requ

爬取百度热点前十名

1 import requests 2 from bs4 import BeautifulSoup 3 import pandas as pd 4 #获取html网页 5 url = 'http://top.baidu.com/buzz.php?p=top10&tdsourcetag=s_pctim_aiomsg&qq-pf-to=pcqq.c2c?' 6 kv = {'user-agent': 'Mozilla/5.0'}#伪装爬虫 7 r = requests.get(url,time

30行python代码爬取历年双色球

当年学爬虫的第一个想法就是想把双色球的数据爬下来,然后看能不能用什么牛叉的算法,或者数据分析把后面的双色球概率算出来:知道现在才抽空写了这几行代码爬取了双色球的数据,我也真是够懒的:也算是闲来无事,练手的爬虫吧:好了,多余的就不说了,直接上代码吧,代码注释已经很清楚了: import sys import requests from lxml import etree def get_url(url): #请求url的方法,返回html headers = { 'User-Agent':'Moz

Python开发简单爬虫(二)---爬取百度百科页面数据

一.开发爬虫的步骤 1.确定目标抓取策略: 打开目标页面,通过右键审查元素确定网页的url格式.数据格式.和网页编码形式. ①先看url的格式, F12观察一下链接的形式;② 再看目标文本信息的标签格式, 比如文本数据为div class="xxx", ③ 容易看到编码为utf-8 2.分析目标 目标: 百度百科python词条 入口页: http://baike.baidu.com/item/Python词条页面url格式:/item/**** 数据格式: 标题: <dd cl

爬取百度实时热点前十排行榜

import requests#导入相应库from bs4 import BeautifulSoupimport pandas as pdurl = 'http://top.baidu.com/buzz?b=1&c=513&fr=topbuzz_b341_c513'#要爬取的网址headers = {'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/

Python3实现QQ机器人自动爬取百度文库的搜索结果并发送给好友(主要是爬虫)

一.效果如下: 二.运行环境: win10系统:python3:PyCharm 三.QQ机器人用的是qqbot模块 用pip安装命令是: pip install qqbot (前提需要有requests库) 实现自己的机器人:网上好几种写法,很简单,不过有时候环境不同会出现错误,下面是亲测可以运行的: from qqbot import QQBotSlot as qqbotslot, RunBot @qqbotslot def onQQMessage(bot, contact, member,

Python爬取百度贴吧内容

参考资料:https://cuiqingcai.com/993.html  即 静觅» Python爬虫实战二之爬取百度贴吧帖子 我最近在忙学校的一个小项目的时候涉及到NLP的内容.但是在考虑如何训练的时候却才懂什么叫巧妇难为无米之炊的滋味.中文语料库实在少的可怜,偶尔有一两个带标签的语料库,拿出一看,标注惨不忍睹,都让我怀疑是不是机器标注的.正应了那句话,人工智能,有多少智能就有多少人工. 有什么办法呢,硬着头皮,走一步是一步吧,总比停滞不前要好.项目涉及到帖子,那么我相信不管是谁,首先想到的

[PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索(二)

前情提要:最近使用PHP实现了简单的网盘搜索程序,并且关联了微信公众平台,名字是网盘小说.用户可以通过公众号输入关键字,公众号会返回相应的网盘下载地址.就是这么一个简单的功能,类似很多的网盘搜索类网站,我这个采集和搜索程序都是PHP实现的,全文和分词搜索部分使用到了开源软件xunsearch. 上一篇([PHP] 网盘搜索引擎-采集爬取百度网盘分享文件实现网盘搜索)中我重点介绍了怎样去获取一大批的百度网盘用户,这一篇介绍怎样获得指定网盘用户的分享列表.同样的原理,也是找到百度获取分享列表的接口,