最让人头疼的清洗数据过程----选择合适的方式快速命中所需的数据
当我们解析网页后,往往面对繁杂的源代码而无从下手,有时候明明知道我们想要的数据就在里面,可是应该如何把冗余的部分去除而只保留我们想要的那一个部分呢
在这里和大家一起学习一下选择的方法
1、正则表达式
真的是无奈之举的时候才会想到要去正则,因为它除非格式标准,否则每次搜索都要重新的绘制pattern
在python中一般导入re模块
那么最常用的就比如说 re,findall(匹配的模板,匹配的对象)[0]
匹配的模板中基本上就是r'<title>(.*?)<title>'
模板的基本上就是你抓到的源码,你可以把它赋值给变量
.*?是万能匹配,如果加上括号就是选中其中内容保存下来
配合w3c理解:
http://deerchao.net/tutorials/regex/regex.htm
2、xpath
打开f12,在相应的地方我们点击,右键后copy,选择xpath路径
基本上需要以下的模块
from parsel import Selector
import requests
z = requests.get('网址')
看一下z.text有没有我们要的内容
sel = Selector(text = z.text)
sel.xpath('//div[]@class= "content"]/span/text()').extract_first()
//代表的是开头是绝对路径,而/则是按顺序下来
@后面跟的是属性,一般是herf src什么的
比如sel.xpath('//@href').extract()
'//comment()'一般就是用来获取注释
p = getxpath(sample源码)
那么遇到一行中跳段的数据怎么办?
p.xpath('//li[position() = 1]'/text()').extract()
.xpath('//li[1]'/text()').extract()
奇数偶数位
.xpath('//li[position() mod2= 1]'/text()').extract()
.xpath('//li[position() mod2= 0]'/text()').extract()
最后一个
.xpath('//li[last()]'/text()').extract()
子节点有a的
.xpath('//li[a]'/text()').extract()
子节点有a或h2的
.xpath('//li[a or h2]'/text()').extract()
子节点有a和h2的
.xpath('//a/text()|//h2/text()').extract()
a下herf以https开始
//a[starts-with(@href,"https")]/text()
还有
//a[@href="https......")]/text()
//li/a[@id="begin")]/text()
//li/a[text()= "....")]/text()这个其实就是本身
//li[2]/a[text()= "....")]/@herf这个就是满足了文本内容的herf的内容爬取了其中取第二个li里面的满足text的定位的herf
总结下来就是基本上[]里面定位,后面再加上/和要找的名字
找p下面所有的文字(包括那些加粗的什么的)
'string(//.........)'
找class中有content的
.xpath(('//*[contains(@class,"content")]'/text()')).extract()
也可以混入正则、css
.xpath(('//*[contains(@class,"content")]'/text()')).re.('[a-c]').extract()
.xpath(('//*[contains(@class,"content")]'/text()')).css.(.......).extract()
。。。
3.css
http://www.w3school.com.cn/css/css_syntax_class_selector.asp
举例 s4.css('.content-a(类名)::text').extract()
对于<p id="xxx" href = python>sssssss<p>
则s4.css('#xxx::attr(herf)')就得到了['python']
其中xxx是标签,而attr里面是要获取的属性
要点是 class是点,id是#,属性是attr
你也可以尝试着将选择器结合起来
s4.css('p#xxx).xpath('text()').extract()
s4.css('p#xxx).xpath('text()').re.('\w+')