有时,你可能会在网上实现一些自动化操作。比如抓取网站,进行应用测试,或在网上填表,但又不想使用API,这时自动化就变得很必要。Python提供了非常优秀的Requests库可以辅助进行这些操作。可惜,很多网站采用基于JavaScript的重客户端,这就意味着Requests获取的HTML代码中根本就没有用来自动化操作的表单,更别提自动填表了!它取回的基本上都是React或Vue这些现代前端库在浏览器中生成的空DIV这类的代码。

虽然可以通过反向工程处理JavaScript生成的代码,但这需要花几个小时来编译。处理这些丑陋的JS代码,谢谢,还是算了吧。还有一个方法就是使用Selenium库,允许以程序化的方式和浏览器进行交互,并运行JavaScript代码。用了这个库就没什么问题了,但它比占用资源极少的Requests慢太多了。

如果能以Requests为主,只在需要Selenium的时候才无缝调用,这样不是更好?看看Requestium吧,它以内嵌方式取代Requests,而且干的不错。它整合了Parsel,用它编写的页面查询元素选择器代码特别清晰,它还为诸如点击元素和在DOM中渲染内容这些通用操作提供了帮助。又一个网页自动化省时利器!

安装

pip install requestium

然后你应该下载您的首选是WebDriver如果你计划使用Requestium的selenium的一部分:Chromedriver或PhantomJS

使用

首先创建一个会话,你可以请求,并且可以随意地添加参数的网络驱动程序

from requestium import Session, Keys

s = Session(webdriver_path='./chromedriver',
            browser='chrome',
            default_timeout=15,
            webdriver_options={'arguments': ['headless']})

你不需要解析的响应,它是自动完成时调用XPath,CSS或re

title = s.get('http://samplesite.com').xpath('//title/text()').extract_first(default='Default Title')

正则表达式需要较少的样本相比,Python的标准re模块

response = s.get('http://samplesite.com/sample_path')

# Extracts the first match
identifier = response.re_first(r'ID_\d\w\d', default='ID_1A1')

# Extracts all matches as a list
users = response.re(r'user_\d\d\d')

会话对象只是一个普通的请求的会话对象,所以你可以使用所有的方法。

s.post('http://www.samplesite.com/sample', data={'field1': 'data1'})
s.proxies.update({'http': 'http://10.11.4.254:3128', 'https': 'https://10.11.4.252:3128'})

你可以切换使用的是WebDriver运行任何JS代码。

s.transfer_session_cookies_to_driver()  # You can maintain the session if needed
s.driver.get('http://www.samplesite.com/sample/process')

驱动对象是一个是WebDriver的对象,所以你可以使用任何正常selenium方法加上新添加的requestium方法。

s.driver.find_element_by_xpath("//input[@class='user_name']").send_keys('James Bond', Keys.ENTER)

# New method which waits for element to load instead of failing, useful for single page web apps
s.driver.ensure_element_by_xpath("//div[@attribute='button']").click()

requestium还增加了XPath,CSS,和re作为selenium的驱动对象。

if s.driver.re(r'ID_\d\w\d some_pattern'):
    print('Found it!')

最后你可以切换回用要求。

s.transfer_driver_cookies_to_session()
s.post('http://www.samplesite.com/sample2', data={'key1': 'value1'})

你可以使用这些元素的方法有新的ensure_click方法是点击不易失败。这有助于通过大量的selenium点击问题。

s.driver.ensure_element_by_xpath("//li[@class='b1']", state='clickable', timeout=5).ensure_click()

# === We also added these methods named in accordance to Selenium's api design ===
# ensure_element_by_id
# ensure_element_by_name
# ensure_element_by_link_text
# ensure_element_by_partial_link_text
# ensure_element_by_tag_name
# ensure_element_by_class_name
# ensure_element_by_css_selector

add cookie

cookie = {"domain": "www.site.com",
          "secure": false,
          "value": "sd2451dgd13",
          "expiry": 1516824855.759154,
          "path": "/",
          "httpOnly": true,
          "name": "sessionid"}
s.driver.ensure_add_cookie(cookie, override_domain='')

使用requestium

from requestium import Session, Keys

# If you want requestium to type your username in the browser for you, write it in here:
reddit_user_name = ''

s = Session('./chromedriver', browser='chrome', default_timeout=15)
s.driver.get('http://reddit.com')
s.driver.find_element_by_xpath("//a[@href='https://www.reddit.com/login']").click()

print('Waiting for elements to load...')
s.driver.ensure_element_by_class_name("desktop-onboarding-sign-up__form-toggler",
                      state='visible').click()

if reddit_user_name:
    s.driver.ensure_element_by_id('user_login').send_keys(reddit_user_name)
    s.driver.ensure_element_by_id('passwd_login').send_keys(Keys.BACKSPACE)
print('Please log-in in the chrome browser')

s.driver.ensure_element_by_class_name("desktop-onboarding__title", timeout=60, state='invisible')
print('Thanks!')

if not reddit_user_name:
    reddit_user_name = s.driver.xpath("//span[@class='user']//text()").extract_first()

if reddit_user_name:
    s.transfer_driver_cookies_to_session()
    response = s.get("https://www.reddit.com/user/{}/".format(reddit_user_name))
    cmnt_karma = response.xpath("//span[@class='karma comment-karma']//text()").extract_first()
    reddit_golds_given = response.re_first(r"(\d+) gildings given out")
    print("Comment karma: {}".format(cmnt_karma))
    print("Reddit golds given: {}".format(reddit_golds_given))
else:
    print("Couldn't get user name")

使用Requests + Selenium + lxml

import re
from lxml import etree
from requests import Session
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# If you want requestium to type your username in the browser for you, write it in here:
reddit_user_name = ''

driver = webdriver.Chrome('./chromedriver')
driver.get('http://reddit.com')
driver.find_element_by_xpath("//a[@href='https://www.reddit.com/login']").click()

print('Waiting for elements to load...')
WebDriverWait(driver, 15).until(
    EC.visibility_of_element_located((By.CLASS_NAME, "desktop-onboarding-sign-up__form-toggler"))
).click()

if reddit_user_name:
    WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.ID, 'user_login'))
    ).send_keys(reddit_user_name)
    driver.find_element_by_id('passwd_login').send_keys(Keys.BACKSPACE)
print('Please log-in in the chrome browser')

try:
    WebDriverWait(driver, 3).until(
        EC.presence_of_element_located((By.CLASS_NAME, "desktop-onboarding__title"))
    )
except TimeoutException:
    pass
WebDriverWait(driver, 60).until(
    EC.invisibility_of_element_located((By.CLASS_NAME, "desktop-onboarding__title"))
)
print('Thanks!')

if not reddit_user_name:
    tree = etree.HTML(driver.page_source)
    try:
        reddit_user_name = tree.xpath("//span[@class='user']//text()")[0]
    except IndexError:
        reddit_user_name = None

if reddit_user_name:
    s = Session()
    # Reddit will think we are a bot if we have the wrong user agent
    selenium_user_agent = driver.execute_script("return navigator.userAgent;")
    s.headers.update({"user-agent": selenium_user_agent})
    for cookie in driver.get_cookies():
        s.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain'])
    response = s.get("https://www.reddit.com/user/{}/".format(reddit_user_name))
    try:
        cmnt_karma = etree.HTML(response.content).xpath(
            "//span[@class='karma comment-karma']//text()")[0]
    except IndexError:
        cmnt_karma = None
    match = re.search(r"(\d+) gildings given out", str(response.content))
    if match:
        reddit_golds_given = match.group(1)
    else:
        reddit_golds_given = None
    print("Comment karma: {}".format(cmnt_karma))
    print("Reddit golds given: {}".format(reddit_golds_given))
else:
    print("Couldn't get user name")

requests+selenium==requestium模块介绍的更多相关文章

  1. selenium===requestium模块介绍

    有时,你可能会在网上实现一些自动化操作.比如抓取网站,进行应用测试,或在网上填表,但又不想使用API,这时自动化就变得很必要.Python提供了非常优秀的Requests库可以辅助进行这些操作.可惜, ...

  2. python模块介绍- multi-mechanize 性能测试工具

    python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...

  3. 第三百二十四节,web爬虫,scrapy模块介绍与使用

    第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...

  4. python模块介绍-locustio:性能测试工具locustio

    转自:http://automationtesting.sinaapp.com/blog/m_locustio_doc python测试文章 http://weibo.com/cizhenshi?is ...

  5. Python+selenium之简单介绍unittest单元测试框架

    Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...

  6. Python编程中 re正则表达式模块 介绍与使用教程

    Python编程中 re正则表达式模块 介绍与使用教程 一.前言: 这篇文章是因为昨天写了一篇 shell script 的文章,在文章中俺大量调用多媒体素材与网址引用.这样就会有一个问题就是:随着俺 ...

  7. Ansible 常见模块介绍

    目录 Ansible 常见模块介绍 ping 模块 command 模块 cron 模块 user 模块 group 模块 copy 模块 file 模块 service 模块 shell 模块 sc ...

  8. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  9. Selenium自动化测试框架介绍

    Selenium自动化测试框架介绍 1.测试架构作用 a.可维护性 b.提高编写脚本效率 c.提高脚本的可读性 2.框架的几大要素: Driver管理,脚本,数据,元素对象,LOG,报告,运行机制,失 ...

随机推荐

  1. Zookeeper管理多个HBase集群

    zookeeper是hbase集群的"协调器".由于zookeeper的轻量级特性,因此我们可以将多个hbase集群共用一个zookeeper集群,以节约大量的服务器.多个hbas ...

  2. linux下分割和重组文件

    linux shell命令里的split和cat命令可以轻松完成这两个功能,举个例子来说,比如一个1GB大小的文件foo.zip,以100M为块分割: 分割: split -b 100M -d foo ...

  3. ubuntu14.04使用rails连接mysql数据库

    rails自带的sqlite3各方面都不错,但是免费版缺少一个致命功能:加密码!虽说第三方有编译好的二进制版的加密版,但咱先不折腾鸟;直接上mysql吧. ubuntu安装mysql非常简单,先不聊; ...

  4. Ruby 2.1: objspace.so

    原文  http://tmm1.net/ruby21-objspace/ 26 Dec 2013 ObjectSpace in ruby contains many useful heap debug ...

  5. Objective-C 空指针和野指针

    一.什么是空指针和野指针 1.空指针 1> 没有存储任何内存地址的指针就称为空指针(NULL指针) 2> 空指针就是被赋值为0的指针,在没有被具体初始化之前,其值为0. 下面两个都是空指针 ...

  6. 深入浅出Java concurrent

    看   :http://www.blogjava.net/xylz/archive/2010/07/08/325587.html

  7. java学习面试精华

    1.线程状态转移 (1)线程生命周期中的5种状态 新建(New).就绪(Runnable).运行(Running).阻塞(Bolocked)和死亡(Dead) 新建(New):程序使用new关键字创建 ...

  8. Python教程大纲

    缘起:最近想在部门推Python语言,写这个blog主要就是个教程大纲,之前先列出一些资源:Python历史:http://www.docin.com/p-53019548.html          ...

  9. Jenkins踩坑系列--你试过linux主机ssh登录windows,启动java进程吗,来试试吧

    一.问题概述 在一个多月前,组长让我研究下持续集成.我很自然地选择了jenkins.当时,(包括现在也是),部分服务器用的是windows主机. 我当时想了想,如果我把jenkins装在windows ...

  10. 和同门一起做的PHP网站

    用的是PHP语言开发,使用ThinkPHP框架,数据库是mysql  统计是用的站长统计,前端很多都是别人网 上扒下来的.css.js水平不高啊.服务器是香港恒创科技的,性价比还可以哦,而且还免备案. ...