request-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)

原文地址:https://www.cnblogs.com/kai-/p/12291240.html