If you’re familiar with modifying variables in Sass—or any other CSS preprocessor—you’ll be right at home to move into flexbox mode.
Open the _variables.scss file and find the $enable-flex variable.
Change it from false to true.
Recompile, and done!
Alternatively, if you don’t need the source Sass files, you may swap the default Bootstrap compiled CSS with the compiled flexbox variation. Head to the download page for more information.
</div> <divclass="container"> <divclass="row"> <divclass="col-xs"> 1of3 </div> <divclass="col-xs-6"> 2of3 (wider) </div> <divclass="col-xs"> 3of3 </div> </div> <divclass="row"> <divclass="col-xs"> 1of3 </div> <divclass="col-xs-5"> 2of3 (wider) </div> <divclass="col-xs"> 3of3 </div> </div> </div> <divclass="container"> <divclass="row"> <divclass="col-xs"> 1of3 </div> <divclass="col-xs-6"> 2of3 (wider) </div> <divclass="col-xs"> 3of3 </div> </div> <divclass="row"> <divclass="col-xs"> 1of3 </div> <divclass="col-xs-5"> 2of3 (wider) </div> <divclass="col-xs"> 3of3 </div> </div> </div> <divclass="container"> <divclass="row flex-items-xs-top"> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> </div> <divclass="row flex-items-xs-middle"> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> </div> <divclass="row flex-items-xs-bottom"> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> <divclass="col-xs"> One of three columns </div> </div> </div> <divclass="container"> <divclass="row flex-items-xs-left"> <divclass="col-xs-4"> One of two columns </div> <divclass="col-xs-4"> One of two columns </div> </div> <divclass="row flex-items-xs-center"> <divclass="col-xs-4"> One of two columns </div> <divclass="col-xs-4"> One of two columns </div> </div> <divclass="row flex-items-xs-right"> <divclass="col-xs-4"> One of two columns </div> <divclass="col-xs-4"> One of two columns </div> </div> <divclass="row flex-items-xs-around"> <divclass="col-xs-4"> One of two columns </div> <divclass="col-xs-4"> One of two columns </div> </div> <divclass="row flex-items-xs-between"> <divclass="col-xs-4"> One of two columns </div> <divclass="col-xs-4"> One of two columns </div> </div> </div> <divclass="container"> <divclass="row"> <divclass="col-xs flex-xs-unordered"> First, but unordered </div> <divclass="col-xs flex-xs-last"> Second, butlast </div> <divclass="col-xs flex-xs-first"> Third, butfirst </div> </div> </div> <style> .row { margin-top: 1rem; } .row > [class^="col-"] { padding-top: .75rem; padding-bottom: .75rem; background-color: rgba(86, 61, 124, 0.15); border: 1px solid rgba(86, 61, 124, 0.2); } .flex-items-xs-top, .flex-items-xs-middle,.flex-items-xs-bottom { min-height: 6rem; background-color: rgba(255, 0, 0, 0.1); } </style>
{ "name": "bootstrap-sass-demo", "authors": [ "Germey" ], "description": "bootstrap-sass is a Sass-powered version of Bootstrap, ready to drop right into your Sass powered applications.", "moduleType": "globals", "keywords": [ "twbs", "bootstrap", "sass" ], "license": "MIT", "dependencies": { "jquery": ">= 1.9.0" } }
@config(age=10 * 24 * 60 * 60) defindex_page(self, response): for each in response.doc('a[href^="http"]').items(): self.crawl(each.attr.href, callback=self.detail_page)
pyquery allows you to make jquery queries on xml documents. The API is as much as possible the similar to jquery. pyquery uses lxml for fast xml and html manipulation. This is not (or at least not yet) a library to produce or interact with javascript code. I just liked the jquery API and I missed it in python so I told myself “Hey let’s make jquery in python”. This is the result. It can be used for many purposes, one idea that I might try in the future is to use it for templating with pure http templates that you modify using pyquery. I can also be used for web scrapping or for theming applications with Deliverance.
pyquery 可让你用 jQuery 的语法来对 xml 进行操作。这I和 jQuery 十分类似。如果利用 lxml,pyquery 对 xml 和 html 的处理将更快。 这个库不是(至少还不是)一个可以和 JavaScript交互的代码库,它只是非常像 jQuery API 而已。
初始化
在这里介绍四种初始化方式。 (1)直接字符串
1 2
from pyquery import PyQuery as pq doc = pq("<html></html>")
pq 参数可以直接传入 HTML 代码,doc 现在就相当于 jQuery 里面的 $ 符号了。 (2)lxml.etree
1 2
from lxml import etree doc = pq(etree.fromstring("<html></html>"))
可以首先用 lxml 的 etree 处理一下代码,这样如果你的 HTML 代码出现一些不完整或者疏漏,都会自动转化为完整清晰结构的 HTML代码。 (3)直接传URL
1 2
from pyquery import PyQuery as pq doc = pq('http://www.baidu.com')
这里就像直接请求了一个网页一样,类似用 urllib2 来直接请求这个链接,得到 HTML 代码。 (4)传文件
1 2
from pyquery import PyQuery as pq doc = pq(filename='hello.html')
依旧是那么优雅与自信! 在这里我们发现了,这是一连串的操作,而 p 是一直在原来的结果上变化的。 因此执行上述操作之后,p 本身也发生了变化。
DOM操作
同样的原汁原味的 jQuery 语法
1 2 3 4 5 6 7 8 9 10 11
from pyquery import PyQuery as pq
p = pq('<p id="hello" class="hello"></p>')('p') print p.append(' check out <a href="http://reddit.com/r/python"><span>reddit</span></a>') print p.prepend('Oh yes!') d = pq('<div class="wrap"><div id="test"><a href="http://cuiqingcai.com">Germy</a></div></div>') p.prependTo(d('#test')) print p print d d.empty() print d
运行结果
1 2 3 4 5
<pid="hello"class="hello"> check out <ahref="http://reddit.com/r/python"><span>reddit</span></a></p> <pid="hello"class="hello">Oh yes! check out <ahref="http://reddit.com/r/python"><span>reddit</span></a></p> <pid="hello"class="hello">Oh yes! check out <ahref="http://reddit.com/r/python"><span>reddit</span></a></p> <divclass="wrap"><divid="test"><pid="hello"class="hello">Oh yes! check out <ahref="http://reddit.com/r/python"><span>reddit</span></a></p><ahref="http://cuiqingcai.com">Germy</a></div></div> <divclass="wrap"/>
这不需要多解释了吧。 DOM 操作也是与 jQuery 如出一辙。
遍历
遍历用到 items 方法返回对象列表,或者用 lambda
1 2 3 4 5 6 7
from pyquery import PyQuery as pq doc = pq(filename='hello.html') lis = doc('li') for li in lis.items(): print li.html()
from lxml import etree html = etree.parse('hello.html') result = etree.tostring(html, pretty_print=True) print(result)
同样可以得到相同的结果。
XPath实例测试
依然以上一段程序为例 (1)获取所有的
标签
1 2 3 4 5 6 7 8
from lxml import etree html = etree.parse('hello.html') print type(html) result = html.xpath('//li') print result print len(result) print type(result) print type(result[0])
运行结果
1 2 3 4 5
<type 'lxml.etree._ElementTree'> [<Element li at 0x1014e0e18>, <Element li at 0x1014e0ef0>, <Element li at 0x1014e0f38>, <Element li at 0x1014e0f80>, <Element li at 0x1014e0fc8>] 5 <type 'list'> <type 'lxml.etree._Element'>
The driver.get method will navigate to a page given by the URL. WebDriver will wait until the page has fully loaded (that is, the “onload” event has fired) before returning control to your test or script. It’s worth noting that if your page uses a lot of AJAX on load then WebDriver may not know when it has completely loaded.
WebDriver offers a number of ways to find elements using one of the findelement_by* methods. For example, the input text element can be located by its name attribute using find_element_by_name method
WebDriver 提供了许多寻找网页元素的方法,譬如 findelement_by* 的方法。例如一个输入框可以通过 find_element_by_name 方法寻找 name 属性来确定。
Next we are sending keys, this is similar to entering keys using your keyboard. Special keys can be send using Keys class imported from selenium.webdriver.common.keys
The test case class is inherited from unittest.TestCase. Inheriting from TestCase class is the way to tell unittest module that this is a test case. The setUp is part of initialization, this method will get called before every test function which you are going to write in this test case class. The test case method should always start with characters test. The tearDown method will get called after every test method. This is a place to do all cleanup actions. You can also call quit method instead of close. The quit will exit the entire browser, whereas close will close a tab, but if it is the only tab opened, by default most browser will exit entirely.
测试用例是继承了 unittest.TestCase 类,继承这个类表明这是一个测试类。setUp方法是初始化的方法,这个方法会在每个测试类中自动调用。每一个测试方法命名都有规范,必须以 test 开头,会自动执行。最后的 tearDown 方法会在每一个测试方法结束之后调用。这相当于最后的析构方法。在这个方法里写的是 close 方法,你还可以写 quit 方法。不过 close 方法相当于关闭了这个 TAB 选项卡,然而 quit 是退出了整个浏览器。当你只开启了一个 TAB 选项卡的时候,关闭的时候也会将整个浏览器关闭。
element = driver.find_element_by_id("passwd-id") element = driver.find_element_by_name("passwd") element = driver.find_elements_by_tag_name("input") element = driver.find_element_by_xpath("//input[@id='passwd-id']")
element = driver.find_element_by_xpath("//select[@name='name']") all_options = element.find_elements_by_tag_name("option") for option in all_options: print("Valueis: %s" % option.get_attribute("value")) option.click()
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast andnative support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
Loading http://cuiqingcai.com Loading time 11678 msec
这个时间包括 JS 渲染的时间,当然和网速也有关。
代码评估
To evaluate JavaScript code in the context of the web page, use evaluate() function. The execution is “sandboxed”, there is no way for the code to access any JavaScript objects and variables outside its own page context. An object can be returned from evaluate(), however it is limited to simple objects and can’t contain functions or closures.
varurl = 'http://www.baidu.com'; var page = require('webpage').create(); page.open(url, function(status) { var title = page.evaluate(function() { returndocument.title; }); console.log('Page title is ' + title); phantom.exit(); });
Since PhantomJS is using WebKit, a real layout and rendering engine, it can capture a web page as a screenshot. Because PhantomJS can render anything on the web page, it can be used to convert contents not only in HTML and CSS, but also SVG and Canvas.
var page = require('webpage').create(); //viewportSize being the actual size of the headless browser page.viewportSize = { width:1024, height:768 }; //the clipRect is the portion of the page you are taking a screenshot of page.clipRect = { top:0, left:0, width:1024, height:768 }; //the rest of the code is the same as the previous example page.open('http://cuiqingcai.com/', function() { page.render('germy.png'); phantom.exit(); });
Because PhantomJS permits the inspection of network traffic, it is suitable to build various analysis on the network behavior and performance.
因为 PhantomJS 有网络通信的检查功能,它也很适合用来做网络行为的分析。
When a page requests a resource from a remote server, both the request and the response can be tracked via onResourceRequested and onResourceReceived callback.
Because PhantomJS can load and manipulate a web page, it is perfect to carry out various page automations.
因为 PhantomJS 可以加载和操作一个 web 页面,所以用来自动化处理也是非常适合的。
DOM 操作
Since the script is executed as if it is running on a web browser, standard DOM scripting and CSS selectors work just fine.
脚本都是像在浏览器中运行的,所以标准的 JavaScript 的 DOM 操作和 CSS 选择器也是生效的。 例如下面的例子就修改了 User-Agent,然后还返回了页面中某元素的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var page = require('webpage').create(); console.log('The default user agent is ' + page.settings.userAgent); page.settings.userAgent = 'SpecialAgent'; page.open('http://www.httpuseragent.org', function(status) { if (status !== 'success') { console.log('Unable to access network'); } else { var ua = page.evaluate(function() { return document.getElementById('myagent').textContent; }); console.log(ua); } phantom.exit(); });
运行结果
1 2
The default user agent is Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.0 Safari/538.1 Your Http User Agent string is: SpecialAgent
--help or -h lists all possible command-line options. Halts immediately, will not run a script passed as argument. [帮助列表] —version or -v prints out the version of PhantomJS. Halts immediately, will not run a script passed as argument. [查看版本] —cookies-file=/path/to/cookies.txt specifies the file name to store the persistent Cookies. [指定存放 cookies 的路径] —disk-cache=[true|false] enables disk cache (at desktop services cache storage location, default is false). Also accepted: [yes|no]. [硬盘缓存开关,默认为关] —ignore-ssl-errors=[true|false] ignores SSL errors, such as expired or self-signed certificate errors (default is false). Also accepted: [yes|no]. [忽略 ssl 错误,默认不忽略] —load-images=[true|false] load all inlined images (default is true). Also accepted: [yes|no]. [加载图片,默认为加载] —local-storage-path=/some/path path to save LocalStorage content and WebSQL content. [本地存储路径,如本地文件和 SQL 文件等] —local-storage-quota=number maximum size to allow for data. [本地文件最大大小] —local-to-remote-url-access=[true|false] allows local content to access remote URL (default is false). Also accepted: [yes|no]. [是否允许远程加载文件,默认不允许] —max-disk-cache-size=size limits the size of disk cache (in KB). [最大缓存空间] —output-encoding=encoding sets the encoding used for terminal output (default is utf8). [默认输出编码,默认 utf8] —remote-debugger-port starts the script in a debug harness and listens on the specified port [远程调试端口] —remote-debugger-autorun runs the script in the debugger immediately: ‘yes’ or ‘no’ (default) [在调试环境下是否立即执行脚本,默认否] —proxy=address:port specifies the proxy server to use (e.g. —proxy=192.168.1.42:8080). [代理] —proxy-type=[http|socks5|none] specifies the type of the proxy server (default is http). [代理类型,默认 http] —proxy-auth specifies the authentication information for the proxy, e.g. —proxy-auth=username:password). [代理认证] —script-encoding=encoding sets the encoding used for the starting script (default is utf8). [脚本编码,默认 utf8] —ssl-protocol=[sslv3|sslv2|tlsv1|any’] sets the SSL protocol for secure connections (default is SSLv3). [SSL 协议,默认 SSLv3] —ssl-certificates-path= Sets the location for custom CA certificates (if none set, uses system default). [SSL 证书路径,默认系统默认路径] —web-security=[true|false] enables web security and forbids cross-domain XHR (default is true). Also accepted: [yes|no]. [是否开启安全保护和禁止异站 Ajax,默认开启保护] —webdriver starts in ‘Remote WebDriver mode’ (embedded GhostDriver): ‘[[:]]’ (default ‘127.0.0.1:8910’) [以远程 WebDriver 模式启动] —webdriver-selenium-grid-hub URL to the Selenium Grid HUB: ‘URLTOHUB’ (default ‘none’) (NOTE: works only together with ‘—webdriver’) [Selenium 接口] —config=/path/to/config.json can utilize a JavaScript Object Notation (JSON) configuration file instead of passing in multiple command-line optionss [所有的命令行配置从 config.json 中读取]
r = requests.post("http://httpbin.org/post") r = requests.put("http://httpbin.org/put") r = requests.delete("http://httpbin.org/delete") r = requests.head("http://httpbin.org/get") r = requests.options("http://httpbin.org/get")
PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API。它全面支持 web 而不需浏览器支持,其快速、原生支持各种 Web 标准:DOM 处理、CSS 选择器、JSON、Canvas 和 SVG。 PhantomJS 可以用于页面自动化、网络监测、网页截屏以及无界面测试等。 安装 以上附有官方安装方式,如果你是 Ubuntu 或 Mac OS X 用户,可以直接用命令来安装 Ubuntu:
FreeNAS 是什么? FreeNAS 是一款广受赞誉的开源免费 NAS 操作系统。它能把普通台式机瞬间变成一台多功能 NAS 服务器。不但适用于企业文件共享,同样适用于打造家庭媒体中心。 FreeNAS 支持多种共享协议,包括 SMB/CIFS、NFS、AFP、WebDAV、iSCSI、FTP/TFTP、RSync 等。 官方网站
iSCSI
iSCSI 技术是一种由 IBM 公司研究开发的,是一个供硬件设备使用的可以在 IP 协议的上层运行的 SCSI 指令集,这种指令集合可以实现在 IP 网络上运行 SCSI 协议,使其能够在诸如高速千兆以太网上进行路由选择。iSCSI 技术是一种新储存技术,该技术是将现有 SCSI 接口与以太网络(Ethernet)技术结合,使服务器可与使用 IP 网络的储存装置互相交换资料。 iSCSI:Internet 小型计算机系统接口 (iSCSI:Internet Small Computer System Interface)。
vars 文件主要用于设置证书的相关组织信息,红色部分的内容可以根据自己的实际情况自行修改。 其中 export KEY_NAME=”germy” 这个要记住下,我们下面在制作 Server 端证书时,会使用到。 注意:以上内容,我们也可以使用系统默认的,也就是说不进行修改也是可以使用的。 然后使用 source vars 命令使其生效,如下:
1 2
source vars ./clean-all
注意:执行 clean-all 命令会删除,当前目录下的 keys 文件夹。 现在开始正式制作 CA 证书,使用如下命令:
我们需要在登录的时候把 form 表单中的所有信息都 POST 一下,然后就可以完成登录啦。 万事俱备,只欠东风,来来来,程序写起来!
一触即发
说走咱就走啊,天上的星星参北斗啊! 登陆地址:Request URL:http://192.168.8.10/portal/login.jsp?Flag=0 首先,我们需要验证一下 IP 地址,先写一个获取 IP 地址的函数,首先判断当前 IP 是不是 211.87 开头的,如果是的话,证明连接的 IP 是有效的。 首先我们写一个获取本机 IP 的方法:
forip_list in ip_lists: ifisinstance(ip_list, list): fori in ip_list: ifself.ip_pre in str(i): returnstr(i) eliftype(ip_list) is types.StringType: ifself.ip_pre in ip_list: returnip_list
这个方法利用了 gethostbyname 和 gethostbyname_ex 方法,获取了各个网卡的 IP 地址,遍历一下,找到那个 211.87 开头的 IP,返回 接下来,获取到 IP 之后,我们便可以构建 form,然后进行模拟登陆了。
#获取本机无线IP defgetIP(self): local_iP = socket.gethostbyname(socket.gethostname()) if self.ip_pre in str(local_iP): return str(local_iP) ip_lists = socket.gethostbyname_ex(socket.gethostname())
for ip_list in ip_lists: if isinstance(ip_list, list): for i in ip_list: if self.ip_pre in str(i): return str(i) elif type(ip_list) is types.StringType: if self.ip_pre in ip_list: return ip_list