python selenium 如何使用post

原文链接:https://blog.csdn.net/mp624183768/article/details/86759888


是一款比较常见的web应用自动化测试系统,它支持多种浏览器,多用于在爬虫中解决JavaScript渲染问题。由于selenium原生代码似乎是不带post方式的,笔者会以headless firefox模式为例,简单谈一下在selenium下如何进行post数据。

第三方库

以seleniumrequests为例,这个库是一个selenium扩展,使得selenium下也可以使用requests的功能,我们可以采用pip安装:

pip install selenium-requests

当然,这个库使用起来也是很简单的:

# selenium.webdriver from the seleniumrequests module
from seleniumrequests import Firefox
 
# Simple usage with built-in WebDrivers:
webdriver = Firefox()
response = webdriver.request('GET', 'https://www.google.com/')
print(response)

 不过这个库也有它的缺点,不方便自定义一些驱动模式参数,无法设置headless状态(也许是我自己瞎几把搞没试出来)。有兴趣的朋友可以自行研究下,其支持如下:

>>> dir(seleniumrequests)
['Android', 'Chrome', 'Firefox', 'Ie', 'Opera', 'PhantomJS', 'Remote', 'RequestMixin', 'Safari', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__warningregistry__', 'request']

HTML文件大法好
个人不太喜欢这种法子,不过好像有一部分人比较推崇。其原理是解析了原生的post请求后,将其传递的参数重构为form表单,最后再将这些新生成的代码存入html网页。

最后,程序会再借用selenium定位submit元素,触发事件提交表单。

窃以为这种方法不太妥帖,每开一个网页程序就得生成一个新的html文件。先不论程序是否一定具有写和删的权限,做法本身是显得比较繁琐的。

FB上貌似有类似介绍这种方法的文章,这里就不贴代码了。

Ajax代行天子令
Ajax模拟post发送请求,这是笔者自己采用过的办法。当然,效果一般般,我相信应该有更好的。

无论是原生JS的XMLHttpRequest,还是Jquery,都可以模拟生成ajax post请求,最后再借助selenium执行JS代码。

XMLHttpRequest示例片段:
 

from selenium import webdriver

driver = webdriver.Chrome()

js = '''var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', false);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

xhr.send('login=test&password=test');
return xhr.response;'''

result = driver.execute_script(js);
brower = webdriver.Firefox(firefox_options=fireFoxOptions)
js = """var xmlhttp=new XMLHttpRequest();
        xmlhttp.open("GET","http://127.0.0.1/get.php",false);
        xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlhttp.setRequestHeader("User-Agent","Mozilla/5.0");
        xmlhttp.setRequestHeader("Cookie","");
        xmlhttp.send("test=1");
        return xmlhttp.responseText;
	    """ 
brower.implicitly_wait(30)
#time.sleep(30)
resp = brower.execute_script(js)

 Jquery示例片段:

jquery = open("jquery.min.js", "r").read()
 
driver = webdriver.Firefox(firefox_options=fireFoxOptions)
driver.execute_script(jquery)
 
ajax_query = '''
            $.ajax('%s', {
            type: %s,
            data: %s, 
            headers: { "User-Agent": "Mozilla/5.0" },
            crossDomain: true,
            xhrFields: {
             withCredentials: true
            },
            success: function(){}
            });
            ''' % (url, request_type, data)
 
ajax_query = ajax_query.replace(" ", "").replace("\n", "")
resp = driver.execute_script("return " + ajax_query)

尾声
总而言之,selenium没有自带原生post方式是一个遗憾,而且其调用headless模式的浏览器,渲染和启动也显得太慢了些,难以适用于单机高并发。

还是那句话,由于selenium其本身的定位和特性。个人窃以为在资源有限的情况下,它不太适用于高并发的大规模测试,做低效精准的辅助也许尚可。

建议

可以用Selenium模拟登陆后 再把cookies保存下来,放到urllib.request里用。
不过selenium页面加载顺序 网速也会引起一系难控制的bug有的难受。
还可以去试试phantomjs 效率比selenium 高一些,不会再弹出个浏览器,是后台运行的。
————————————————
 
原文链接:https://blog.csdn.net/mp624183768/article/details/86759888

另外:Java Selenium WebDriver 中executeAsyncScript和executeScript方法的使用   https://www.cjavapy.com/article/411/

1、executeScript方法使用  同步方式在后台执行执行Js(JavaScript)代码。用它执行js代码会阻塞主线程执行,直到js代码执行完毕。

2、executeAsyncScript方法使用  异步方法,它不会阻塞主线程执行。调用的函数executeAsyncScript将'done callback'作为最后一个参数,必须调用该函数来表示脚本已完成执行。这允许它与仅在使用回调时“完成”的代码一起使用 - 例如。setTimeout或异步XHR。如果未在超时限制内调用“完成回调”,则将拒绝返回的承诺。

1) 在浏览器中执行sleep

long start = System.currentTimeMillis();
   ((JavascriptExecutor) driver).executeAsyncScript(
       "window.setTimeout(arguments[arguments.length - 1], 500);");
   System.out.println(
       "Elapsed time: " + (System.currentTimeMillis() - start)); 

2) 将测试与AJAX应用程序同步

 WebElement composeButton = driver.findElement(By.id("compose-button"));
   composeButton.click();
   ((JavascriptExecutor) driver).executeAsyncScript(
       "var callback = arguments[arguments.length - 1];" +
       "mailClient.getComposeWindowWidget().onload(callback);");
   driver.switchTo().frame("composeWidget");
   driver.findElement(By.id("to")).sendKeys("bog@example.com");

3) 注入XMLHttpRequest并等待结果

 Object response = ((JavascriptExecutor) driver).executeAsyncScript(
       "var callback = arguments[arguments.length - 1];" +
       "var xhr = new XMLHttpRequest();" +
       "xhr.open('GET', '/resource/data.json', true);" +
       "xhr.onreadystatechange = function() {" +
       "  if (xhr.readyState == 4) {" +
       "    callback(xhr.responseText);" +
       "  }" +
       "}" +
       "xhr.send();");
   JSONObject json = new JSONObject((String) response);
   assertEquals("cheese", json.getString("food"));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值