requests+selenium==requestium模块介绍
有时,你可能会在网上实现一些自动化操作。比如抓取网站,进行应用测试,或在网上填表,但又不想使用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模块介绍的更多相关文章
- selenium===requestium模块介绍
有时,你可能会在网上实现一些自动化操作.比如抓取网站,进行应用测试,或在网上填表,但又不想使用API,这时自动化就变得很必要.Python提供了非常优秀的Requests库可以辅助进行这些操作.可惜, ...
- python模块介绍- multi-mechanize 性能测试工具
python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...
- 第三百二十四节,web爬虫,scrapy模块介绍与使用
第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...
- python模块介绍-locustio:性能测试工具locustio
转自:http://automationtesting.sinaapp.com/blog/m_locustio_doc python测试文章 http://weibo.com/cizhenshi?is ...
- Python+selenium之简单介绍unittest单元测试框架
Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...
- Python编程中 re正则表达式模块 介绍与使用教程
Python编程中 re正则表达式模块 介绍与使用教程 一.前言: 这篇文章是因为昨天写了一篇 shell script 的文章,在文章中俺大量调用多媒体素材与网址引用.这样就会有一个问题就是:随着俺 ...
- Ansible 常见模块介绍
目录 Ansible 常见模块介绍 ping 模块 command 模块 cron 模块 user 模块 group 模块 copy 模块 file 模块 service 模块 shell 模块 sc ...
- python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用
python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...
- Selenium自动化测试框架介绍
Selenium自动化测试框架介绍 1.测试架构作用 a.可维护性 b.提高编写脚本效率 c.提高脚本的可读性 2.框架的几大要素: Driver管理,脚本,数据,元素对象,LOG,报告,运行机制,失 ...
随机推荐
- Mybatis 源码之Plugin类解析
public class Plugin implements InvocationHandler { private Object target; //目标对象 private Interceptor ...
- 微信android混淆打包减少安装包大小
首先,感谢微信android团队的分享 微信中的资源混淆工具主要为了混淆资源ID长度(例如将res/drawable/welcome.png混淆为r/s/a.png),同时利用7z深度压缩,大大减少了 ...
- LeetCode之旅(22)-House Robber
题目: You are a professional robber planning to rob houses along a street. Each house has a certain am ...
- 理解java值传递与引用传递
1.基本类型和引用类型在内存中的保存 Java中数据类型分为两大类,基本类型和对象类型.相应的,变量也有两种类型:基本类型和引用类型.基本类型的变量保存原始值,即它代表的值就是数值本身:而引用类型的变 ...
- javah tool for Android Native Application
javah可以在Eclipse中配置成为External Tools,选择External Tools Configurations,配置如下,经过测试通过. Location: ${system_p ...
- spring-cloud-config安全问题
配置服务的安全问题会很重要,其中的内容是我自己学习的,由于学习时间不长,有可能不是很完备,如果有更好的方案,烦请评论中留言或私信,谢谢! 1. 首先访问配置服务需要设置密码: 使用spring-sec ...
- CSS 文章链接
文本溢出显示为省略号 Ellipsis for text overflow in table cell?
- Struts2数据传输的背后机制:ValueStack(值栈)
1. 数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL 要了解ValueStack,必须先理解OGN ...
- js 读取xml文件
读取xml文件 [原创 2007-6-20 17:35:37] 字号:大 中 小 js中读取xml文件,简单的例子: <html><head><script> ...
- 初识Java——一维数组的创建及使用
数组作为对象是允许使用new关键字进行内存分配的,在使用数组前,必须首先定义数组的变量所属的类型.一维数组的创建有两种方法: 1,先声明,再用new运算符进行内存分配 数组元素类型+数组名字[] 数组 ...