怎样在console中验证css和xpath css

在做一个可视化配置爬虫项目时,需要配置爬虫的用户自己输入xpath和csspath路径以提取数据或做浏览器操作。考虑到用户的有时会输入错误的xpath或csspath路径,后台需要对其做合法性校验。
xpath有效性校验
对于xpath的有效性检验,使用第三方lxml模块中的etree.XPathEvalError进行校验。不得不说lxml是一个解析爬虫数据的利器,当etree.xpath()遇到不合法的xpath路径时会抛出XPathEvalError错误。
代码如下:
from lxml import etree
from StringIO import StringIO
def _validXpathExpression(xpath):
检查xpath合法性
:param xpath:
tree = etree.parse(StringIO('&foo&&bar&&/bar&&/foo&'))
tree.xpath(xpath)
return True
except etree.XPathEvalError, e:
return False
只有当输入的xpath路径合法时返回True。
&&&print _validXpathExpression('./div[@class=&name&]/a/text()')
&&&print _validXpathExpression('./div(@class=&name&)')
csspath有效性检验
对于csspath检验的思路时,借助python标准库cssselect的css_to_xpath()方法。当输入的csspath不合法时会抛出SelectorError错误。
from cssselect.parser import SelectorError
from cssselect.xpath import HTMLTranslator
def _validCssExpression(css):
检查css合法性
:param css:
HTMLTranslator().css_to_xpath(css)
return True
except SelectorError, e:
return False
只有当输入的csspath路径合法时返回True。
&&&print _validCssExpression('.content&a')
&&&print _validCssExpression('.content&a[123]')
阅读(...) 评论()CSS选择器和Xpath都能通过页面结构对位元素,以下为采用两种方式定位相同元素的例子:&body& &div id='index'&
&div&&/div&
&a&abc&/a&
&li&abc&/li&
&li&&a href=''&&/a&&/li&
&/div& &/div& &/div& &/div&&/body&XPATH地址:id('index')/div[2]/div/ul/div/li[2]/aCSS选择器地址:#index div:nth-of-type(2) div ul li:nth-of-type(2) aSelenium中测试代码@Test public void f() {
driver = new FirefoxDriver();
driver.get(&http://localhost:8080/xpath/bcd.html&);
WebElement ele1 = driver.findElement(By.xpath(&id('index')/div[2]/div/ul/div/li[2]/a&));
String a = ele1.getText();
WebElement ele2 = driver.findElement(By.cssSelector(&#index div:nth-child(2) div ul li:nth-child(2) a&));
Assert.assertEquals(ele2.getText(), a); }CSS选择器和Xpath有着类似的结构,在某些方面两者是可以互相替换使用的。对于某些场景,可以从其中一种推测出另一种的写法。例如我们利用插件获取CSDN首页学院标签的xpath路径为:Xpath:/html/body/div[5]/div/div[1]/ul/li[4]/a,我们可以推导其css选择器路径并添加样式,其效果如下:html body div:nth-of-type(7) div div:nth-of-type(1) ul li:nth-of-type(4) a{Color:Border:}&&Xpath和CSS选择器都能完成定位的功能,相比较而言,由于Selenium使用xpath定位时采用遍历页面的方式,在性能上采用CSS选择器的方式更优。我们把上例中的css选择器路径和xpath路径利用selenium进行元素定位,在大批量情况时,css选择器所用时间更短。Xpath虽然性能指标较差,但是在浏览器中有比较好的插件支持,定位元素比较方便,对于性能要求严格的场景,可考虑通过xpath改写css的方式进行替换。性能测试代码如下:&public class NewTest { WebD WebDriver driver2;
@BeforeTest public void setup() {
ctime = 0;
xtime = 0;
System.setProperty(&webdriver.chrome.driver&, &D://chromed//chromedriver.exe&);
driver = new ChromeDriver();
driver.get(&http://www.csdn.net/&);
driver2 = new ChromeDriver();
driver2.get(&http://www.csdn.net/&); } @Test(invocationCount = 500) public void f() {
long start = System.currentTimeMillis();
WebElement ele = driver2
.findElement(By.cssSelector(&html body div:nth-of-type(5) div div ul li:nth-of-type(4) a&));
ctime += System.currentTimeMillis() - } @Test(invocationCount = 500) public void f2() {
long start = System.currentTimeMillis();
WebElement ele = driver.findElement(By.xpath(&/html/body/div[5]/div/div[1]/ul/li[4]/a&));
xtime += System.currentTimeMillis() - } @Test(dependsOnMethods = { &f2&, &f& }) public void time() {
System.out.println(&x& + xtime);
System.out.println(&c& + ctime);
Assert.assertTrue(xtime & ctime); }}两者在某些方面是很相似的。Css对于根据子元素查找元素是不支持的,所以对于子元素不变,采用Xpath是能屏蔽掉其他页面元素改变。对于其他的定位两者是类似的,定位越是精确,对于页面改变的适应性就越差,采用模糊定位能够较好的屏蔽结构改变,但是会影响总体性能。
最新教程周点击榜
微信扫一扫今天看啥 热点:
Google浏览器内核 的 审查元素
copy xpath
css path,xpathcss
#headline_block & ul & li:nth-child(5)
//*[@id=&headline_block&]/ul/li[5]
以前没太注意 没想到这么强大
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&&&
WEB前端教程最近更新一、console对象:
F12或者Control+Shift+i(Win)/ Alt+Command+i(Mac)打开浏览器自带的开发工具,选择顶部tab中的最后一项console,这样你就可以尽情的console了。
下面看看这个console对象给我们提供的各种方法。
1、log()、info()、debug()
<()和console.debug()都是console.log方法的别名,用法基本一样。方法会在输出信息的前面,加上一个蓝色图标。所以这三个就说说log
console.log方法用于在console窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。这些都是比较基本的用法,输出需要调试的对象啥的,另外我们可以发现很多网站console出很多稀奇古怪的东西,啥图片啥LOGO整起
看看莫猫:
是不是很形象,果然是XX猫,很深动,这里看看他们是怎么实现的:
对于log来说他可以格式化输出,就像我们的C当中的格式化输出一样,什么%c%d换行\n啥啥啥的,当然log肯定和那个不一样咯
log提供的格式化输出主要有:
%o 对象的链接
%c CSS格式字符串
OK:看看怎么输出1+1=2:
1 console.log(" %s + %s ", 1, 1, "= 2")
2 // 1 + 1
当然你也可以:console.log("1 + 1 = 2")
1 console.log("%s\n+%s\n",1,1,"=2")
OK:再看看猫猫怎么cosole出来的:
1 var e = {info: "\u55b5~ \u52a0\u\u4eec\u5427 http://tb.cn/iS8NBOy",logo: " ::: ::: \n" + " ::::::: ::::: \n" + "::::::::: ::::::::\n" + ":::::::::::::::::::::::::::::::::::::::::::\n" + ":::: ::: :::::::::::::::: ::: ::::\n" + "::: Smart :::::cool:::: Crazy :::\n" + "::::: ::: ::::::::::::::: ::: :::\n" + ":::::::::::::::::::::::::::::::::::::::::::"};
3 (e.logo + "\n\n" + e.info)
Then:Log差不多了,对了还有css样式输出:对常见的富样式输出有两种:文字样式、图片输出。
文字样式输出比较简单:console.log("%c歘歘歘歘","font-size:20color:red")这样就会输出四个红色的chua
图片输出:先把效果拿出来看一下ha &Take a Photo
其实console.log不支持直接图片输出,但是支持css样式输出,所以我们可以绕过这个限制,用背景图哈哈哈哈哈是不是很聪明。但是我们没法像平时那样直接输出背景图,又得绕一圈,
就好像上面的示例,要输出一张60*60的图片,我们用padding来把整个区域撑开到我要的大小,然后还要设置line-height才行。
line-height的值我取图片高度
background这个是北京图片的url啥的
padding左右两边的值是图片宽度的一半
padding上下两边的值是图片高度的一半-7px
OK,现在是不是可以在控制台尽情的console了哇
2、warn() error()
warn方法和error方法也是输出信息,它们与log方法的不同之处在于,warn方法输出信息时,在最前面加一个黄色三角,表示警告;error方法输出信息时,在最前面加一个红色的叉,表示出错,同时会显示错误发生的堆栈。其他用法都一样。在这儿就不详说了
3、table() count()&dir()&assert()&timeline(),timelineEnd(),timeStamp()&profile(),profileEnd()&group(),groupend(),groupCollapsed()&trace()
这些个在平时的开发调试中用的比较少然后time(),timeEnd()会用到当然最后&最后的最后,该清场了。
clear()回到原点,本想把这些都写一下的,苦逼cxy没吃饭没力气了,console差不多了
二、命令行API:
上面的那些都是ECMAScript的对象console下的方法,下面这些是浏览器命令行的API,和ECMA好像没5毛钱关系:
$_: 返回上一个表达式的值,和上下左右不同,上下左右是得到上次输入到命令行的表达式,这个是得到上次的表达式的值。
$0 - $4:控制台保存了最近5个在Elements面板选中的DOM元素,$0代表倒数第一个,$1代表倒数第二个,以此类推直到$4。
$(selector) :返回一个集合(ArrayLike),包括特定的CSS选择器匹配的所有DOM元素。
$$(selector) :返回一个集合(ArrayLike),包括特定的CSS选择器匹配的所有DOM元素。
上面两个$$我理解的应该是为了和jquery或者zepto等库里面的$冲突而设定的,在控制台中首先是去找的jq和zepto里面的$,如果没有则调命令行API
另外/devtools/docs/commandline-api,谷歌开发者啥啥啥的上说的是得到一个数组,感觉不妥
下面几个用的不多:
$x(path):方法返回一个数组,包含匹配特定XPath表达式的所有DOM元素。这个我没试过,感觉应该也是一个集合
inspect(object):方法打开相关面板,并选中相应的元素:DOM元素在Elements面板中显示,JavaScript对象在Profiles中显示。
profile方法用于启动一个特定名称的CPU性能测试,profileEnd方法用于结束该性能测试。
copy(object)方法复制特定DOM元素到剪贴板。
dir(object)方法显示特定对象的所有属性,是console.dir方法的别名。
dirxml(object)方法显示特定对象的XML形式,是console.dirxml方法的别名。
clear()方法和console.clear()差不多
然后就是几个比较实用的几个API,可以快速帮助我们调试:
getEventListeners(object):获取元素节点绑定了哪些事件
keys(object),values(object) :获取对象的所有key数组和value数组
monitorEvents(object,[events]) ,unmonitorEvents(object,[events]):监听制定节点的指定事件、停止监听事件
getEventListeners:
monitorEvents\unmonitorEvents:
keys\values:
monitorEvents允许监听同一大类的事件,不是我们平时所说的哪些什么click什么的。这些事件分成四个大类:
mouse:"mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel"
key:"keydown", "keyup", "keypress", "textInput"
touch:"touchstart", "touchmove", "touchend", "touchcancel"
control:"resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"更多的一些命令行API可以移步:&OK差不多就这样了,
阅读(...) 评论()这篇文章主要介绍创建一个简单的spider,顺便介绍一下对网页元素的选取方式(css selector, xpath selector)。
第一步:创建spider工程
打开命令行运行以下命令:
scrapy startproject homelink_selling_index
创建出的工程结构如下:
scrapy.cfg
└─lianjia_shub
pipelines.py
settings.py
__init__.py
└─spiders
__init__.py
第二步:定义spider(homelink_selling_index)
需要抓取的页面元素如下图:
导入命名空间:
import scrapy
定义spider:
class homelink_selling_index_spider(scrapy.Spider):
# 定义spider的名字,在调用spider进行crawling的时候会用到:
scrapy crawl &spider.name&
name = "homelink_selling_index"
# 如果没有特别指定其他的url,spider会以start_urls中的链接为入口开始爬取
start_urls = ["/ershoufang/pg1tt2/"]
# parse是scrapy.Spider处理http response的默认入口
# parse会对start_urls里的所有链接挨个进行处理
def parse(self, response):
# 获取当前页面的房屋列表
#house_lis = response.css('.house-lst .info-panel')
house_lis = response.xpath('//ul[@class="house-lst"]/li/div[@class="info-panel"]')
# 把结果输出到文件(在命令行中房屋标题会因为编码原因显示为乱码)
with open("homelink.log", "wb") as f:
## 使用css selector进行操作
#average_price = response.css('.secondcon.fl li:nth-child(1)').css('.botline a::text').extract_first()
#f.write("Average Price: " + str(average_price) + "\r\n")
#yesterday_count = response.css('.secondcon.fl li:last-child').css('.botline strong::text').extract_first()
#f.write("Yesterday Count: " + str(yesterday_count) + "\r\n")
#for house_li in house_lis:
link = house_li.css('a::attr("href")').extract_first()
# 获取房屋的链接地址
title = house_li.css('a::text').extract_first()
# 获取房屋的标题
price = house_li.css('.price .num::text').extract_first()
# 获取房屋的价格
# 使用xpath selector进行操作
average_price = response.xpath('//div[@class="secondcon fl"]//li[1]/span[@class="botline"]//a/text()').extract_first()
f.write("Average Price: " + str(average_price) + "\r\n")
yesterday_count = response.xpath('//div[@class="secondcon fl"]//li[last()]//span[@class="botline"]/strong/text()').extract_first()
f.write("Yesterday Count: " + str(yesterday_count) + "\r\n")
for house_li in house_lis:
link = house_li.xpath('.//a/@href').extract_first()
# 注意这里xpath的语法,前面要加上".",否则会从文档根节点而不是当前节点为起点开始查询
title = house_li.xpath('.//a/text()').extract_first()
price = house_li.xpath('.//div[@class="price"]/span[@class="num"]/text()').extract_first()
f.write("Title: {0}\tPrice:{1}\r\n\tLink: {2}\r\n".format(title.encode('utf-8'), price, link))
第三步:查看结果
Average Price: 44341
Yesterday Count: 33216
Title: 万科假日风景全明格局 南北精装三居 满五唯一 Price:660
Link: /ershoufang/xxx.html
Title: 南北通透精装三居 免税带车位 前后对花园 有钥匙 Price:910
Link: /ershoufang/xxx.html
Title: 西直门 时代之光名苑 西南四居 满五唯一 诚心出售 Price:1200
Link: /ershoufang/xxx.html......
通过上面的三步,我们可以对网页元素进行简单的爬取操作了。但是这里还没有真正利用好Scrapy提供给我们的很多方便、强大的功能,比如: ItemLoader, Pipeline等。这些操作会在后续的文章中继续介绍。
阅读(...) 评论()

我要回帖

更多关于 xpath css 的文章

 

随机推荐