zoukankan      html  css  js  c++  java
  • 1.8request-html

    全面支持解析JavaScript!
    CSS 选择器 (jQuery风格, 感谢PyQuery).
    XPath 选择器, for the faint at heart.
    自定义user-agent (就像一个真正的web浏览器).
    自动追踪重定向.
    连接池与cookie持久化.
    令人欣喜的请求体验,魔法般的解析页面.

    接触过爬虫用的最多的包无非就是requests, urllib包,我们在使用这些包的时候显示,用requests包去获取响应,然后再利用pyquery或者bs4,xpath再去整理提取我们需要是目标数据。也就是下面两步

    import requests
    from pyquery import PyQuery as pq
    
    #获取网页
    html = requests.get()
    #解析网页
    doc = pq(html)
    

    但是在 request-html 里只需要一步就可以完成,而且可以直接进行 js 渲染

    requests的作者Kenneth Reitz 开发的requests-html 爬虫包 是基于现有的框架 PyQuery、Requests、lxml、beautifulsoup4等库进行了二次封装,作者将Requests的简单,便捷,强大又做了一次升级。这里是github地址

    安装:

    pip install request-html
    

    基本使用

    from requests_html import HTMLSession
    
    # 获取请求对象
    session = HTMLSession()
    # 往新浪新闻主页发送 get 请求
    sina = session.get('https://news.sina.com.cn')
    # print(sina.status_code)
    sina.encoding = 'utf-8'
    
    # 获取响应文本信息,与requests无区别
    print(sina.text)
    

    获取链接( links 与 absolute_links )

    from requests_html import HTMLSession
    
    # 获取请求对象
    session = HTMLSession()
    jd = session.get('https://jd.com')
    print(jd.html.links)
    
    # 若获取的链接中有相对路径
    # 我们还可以通过 absolute_links 获取所有的绝对链接
    print(jd.html.absolute_links)
    

    CSS 选择器与 XPATH

    requests-html 支持 CSS 选择器和 XPATH 两种语法选取 HTML 元素

    首先先来看看CSS选择器语法,它需要使用HTML的 find 函数来查找元素。

    from requests_html import HTMLSession
    
    session = HTMLSession()
    url = 'https://www.qiushibaike.com/text'
    

    通过 CSS 选择器选取一个 Element 对象

    css选择器语法:http://www.w3school.com.cn/cssref/css_selectors.asp

    CSS选择器示例:

    • a
    • a.someClass
    • a#someID
    • a[target=_blank]
    # 获取响应数据对象
    obj = session.get(url)
    
    # 通过 CSS 选择器选取一个 Element 对象
    # 获取 id 为 content-left 的 div 标签,标签返回一个对象
    content = obj.html.find('div#content-left', first=True)
    

    获取一个Element对象内的文本内容

    content_text = content.text
    

    获取一个 Element 对象的完整的 HTML 内容

    content_html = content.html
    

    获取一个Element对象的所有attributes

    content_attrs = content.attrs
    

    获取Element对象内的指定的所有子Element对象,返回列表

    a_list = content.find('a')
    

    循环所有的 a 标签

    a_list = content.find('a')
    for a in a_list:
     try:
         # 获取a标签内所有属性的href属性 并拼接
         href = a.attrs['href']
         if href.startswith('/'):
             url = 'https://www.qiushibaike.com' + href
             print(url)
     except:
         pass
    

    在获取的页面中通过search查找文本

    {}大括号相当于正则的从头到后开始匹配,获取当中想要获取的数据

    text = obj.html.search('把{}夹')[0]  # 获取从 "把" 到 "夹" 字的所有内容
    text = obj.html.search('把糗事{}夹')[0]  # 获取从把子到夹字的所有内容
    print(text)
    

    支持 XPATH

    xpath选择器语法:http://www.w3school.com.cn/xpath/index.asp

    a_list = obj.html.xpath('//a')  # 获取 html 内所有的 a 标签
    for a in a_list:
     try:
         href = a.attrs['href']
         # 若是// 开头的 url 都扔掉
         if href.startswith('//'):
             continue
         elif href.startswith('/'):
             print('https://www.qiushibaike.com' + href)
     except:
         pass
    

    获取到只包含某些文本的Element对象(containing)

    # 获取所有文本内容为幽默笑话大全_爆笑笑话_笑破你的肚子的搞笑段子 - 糗事百科 title标签
    # 注意: 文本内有空格也必须把空格带上
    title = obj.html.find('div', containing='后来')
    print(title[0].text)
    

    支持 JavaScript

    下面就是重磅炸弹了!!!高能预警!!!

    注意,当你第一次调用render()方法时,代码将会自动下载Chromium,并保存在你的家目录下(如:~/.pyppeteer/)。它只会下载这一次。

    • from requests_html import HTMLSession
      
      session = HTMLSession()
      res = session.get('https://piaofang.maoyan.com/dashboard')
      res.html.render()
      print(res.text)
      
    • render函数还有一些参数,介绍一下(这些参数有的还有默认值,直接看源代码方法参数列表即可):

    • - retries: 加载页面失败的次数

    • - script: 页面上需要执行的JS脚本(可选)

    • - wait: 加载页面钱的等待时间(秒),防止超时(可选)

    • - scrolldown: 页面向下滚动的次数

    • - sleep: 在页面初次渲染之后的等待时间

    • - reload: 如果为假,那么页面不会从浏览器中加载,而是从内存中加载

    • - keep_page: 如果为真,允许你用r.html.page访问页面

    如果scrolldownsleep都指定,那么程序会在暂停相应时间后,再往后翻页面(如:scrolldown=10, sleep=1

    如果仅指定了sleep,程序会暂停相应时间,再返回数据

    如果指定script,他将会在运行时执行提供的JavaScript。如:

    script = """
        () => {
            return {
                 document.documentElement.clientWidth,
                height: document.documentElement.clientHeight,
                deviceScaleFactor: window.devicePixelRatio,
            }
        }
    """
    

    返回一段JavaScript的返回值:

    >>> r.html.render(script=script)
    {'width': 800, 'height': 600, 'deviceScaleFactor': 1}
    

    自定义 User-Agent

    有些网站会使用 User-Agent 来识别客户端类型,有时候需要伪造UA来实现某些操作。

    如果查看文档的话会发现HTMLSession上的很多请求方法都有一个额外的参数**kwargs,这个参数用来向底层的请求传递额外参数。

    我们先向网站发送一个请求,看看返回的网站信息。

    from requests_html import HTMLSession
    # pprint 可以把数据打印的更整齐
    from pprint import pprint
    import json
    get_url = 'http://httpbin.org/get'
    
    session = HTMLSession()
    # 返回的是当前系统的 headers 信息
    res = session.get(get_url)
    pprint(json.loads(res.html.html))
    
    # 可以在发送请求的时候更换 user-agent
    ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0'
    post_url = 'http://httpbin.org/get'
    res = session.get(post_url, headers={'user-agent': ua})
    pprint(json.loads(res.html.html))
    

    request-html 更多方法

    模拟表单提交(POST)

    HTMLSession 封装了一整套的HTTP方法,包括get、post、delete等, 对应HTTP中各个方法。

    # 表单登录
    res = session.post('http://httpbin.org/post', data={'username': 'santa', 'password': '123'})
    pprint(json.loads(res.html.html))
    ''' # 打印结果
    {'args': {},
    'data': '',
    'files': {},
    'form': {'password': '123', 'username': 'santa'},
    'headers': {'Accept': '*/*',
              'Accept-Encoding': 'gzip, deflate',
              'Content-Length': '27',
              'Content-Type': 'application/x-www-form-urlencoded',
              'Host': 'httpbin.org',
              'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) '
                            'AppleWebKit/603.3.8 (KHTML, like Gecko) '
                            'Version/10.1.2 Safari/603.3.8',
              'X-Amzn-Trace-Id': 'Root=1-5e40d021-0261ed6c9fbc7df0daf90e98'},
    'json': None,
    'origin': '117.153.8.82',
    'url': 'http://httpbin.org/post'}
    '''
    

    async异步使用

    requests-html内部就封装好了aynsc异步请求的功能,可以提高我们的爬虫效率

    # 使用异步发送请求
    async_session = AsyncHTMLSession()
    ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
    async def get_taobao():
     url = 'https://www.taobao.com/'
     res = await async_session.get(url, headers={'user-agent': ua})
     # print(res.html.links)
     return res.html.xpath("//head/title/text()")[0]
    
    async def get_jd():
     url = 'https://www.jd.com/'
     res = await async_session.get(url)
     # print(res.html.absolute_links)
     return res.html.xpath("//head/title/text()")[0]
    
    start_time = time.time()
    res = async_session.run(get_taobao, get_jd)
    print(res)
    print(time.time()-start_time)
    
    # 同步发送请求
    session = HTMLSession()
    
    start_time = time.time()
    res = session.get('https://www.jd.com')
    print(res.html.links)
    res = session.get('https://www.taobao.com')
    print(res.html.absolute_links)
    print('fd ',time.time()-start_time)
    
  • 相关阅读:
    Linux系统组成和获取命令帮助2
    Linux系统组成和获取命令帮助1
    3P修饰
    PHP-简单生成唯一数
    Go语言实现APPID登录
    磁盘满了,却看不到是谁占用的
    Redis安装、配置和卸载
    docker 加入域名
    Docker安装
    Swoft+Docker
  • 原文地址:https://www.cnblogs.com/hsinfo/p/13775804.html
Copyright © 2011-2022 走看看