以网页http://blog.jobbole.com/110691/
为例提取:
xpath基础知识:
xpath节点关系:
- 父节点 上一层节点
- 子节点
- 兄弟节点 同胞节点
- 先辈节点 父节点,爷爷节点
- 后代节点 儿子,孙子节点
xpath语法
表达式 | 说明 |
---|---|
article | 选取所有article元素的所有子节点 |
/article | 选取根元素article |
article/a | 选取所有属于article的子元素的a元素 |
//div | 选取所有div元素(不管出现在文档里的任何地方) |
article//div | 选取所有属于article元素的后代的div元素,不管它出现在article之下的任何位置 |
//@class | 选取所有名为class的属性 |
表达式 | 说明 |
---|---|
/article/div[1] | 选取属于article子元素的第一个div元素 |
/article/div[last()] | 选取属于article子元素的最后一个div元素 |
/article/div[last()-1] | 选取属于article子元素的倒数第二个div元素 |
//div[@lang] | 选取所有拥有lang属性的div元素 |
//div[@lang='eng'] | 选取所有lang属性值为eng的div元素 |
/div/* | 选取属于div元素的所有子节点 |
//* | 选取所有元素 |
//div[@*] | 选取所有带属性的div 元素 |
//div/a 丨//div/p | 选取所有div元素的a和p元素 |
//span丨//ul | 选取文档中的span和ul元素 |
article/div/p丨//span | 选取所有属于article元素的div元素的p元素以及文档中所有的 span元素 |
获得相应内容
在上节工程中,把start_urls
更换为上面的地址。
为了调试方便,在cmd下输入:
scrapy shell http://blog.jobbole.com/110691/
进入调试shell。
获得标题
输入
response.xpath('//*[@id="post-110691"]/div[1]/h1/text()').extract()
或者
response.xpath('//*[@class="entry-header"]/h1/text()').extract()
都可以得到文章标题列表。
第一种方法通过确定id,第二种方法通过标题class的属性得到标题列表,更加通用,然后通过数组的切片即可得到标题。详细查看上面的表格。
获得时间
response.xpath('//p[@class="entry-meta-hide-on-mobile"]/text()').extract()
注意,只能获得p标签下的文字内容,对于子节点内容无法获得。对于获得的数据通过strip() replace()函数进行清洗。
获取点赞
对于含有多个属性的class如:class=" btn-bluet-bigger href-style vote-post-up register-user-only "
,若只使用其中的一个属性得到值,可以使用contains
。
response.xpath("//span[contains(@class, 'vote-post-up')]/h10/text()").extract()[0]
获得收藏数
fav_nums = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
得到的内容为7 收藏
,此时需要通过正则表达式进行清洗。
match_re = re.match(".*(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
获得评论数
comment_nums = response.xpath("//a[@href='#article-comment']/text()").extract()[0]
获得相应内容后,使用同样的正则进行数据清洗。
获得正文
content = response.xpath("//div[@class='entry']").extract()[0]
注意此处没有加text()
获得tags
所有的tag都在a标签下,类似获得日期的方式,增加一个a标签路径即可。
tag_list = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/a/text()').extract()
得到的内容为:
['其他', ' 3 评论 ', '创业', '程序员']
此时需要对数据进行清洗去掉
3 评论
tag_list = [e for e in tag_list if not e.strip().endswith("评论")]
tags = ",".join(tag_list)
这样就可以将清洗后的数据放到tags字段中了。
title = response.xpath('//*[@class="entry-header"]/h1/text()').extract()[0]
create_date = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].replace('·','').strip()
fav_nums = response.xpath("//span[contains(@class, 'bookmark-btn')]/text()").extract()[0]
match_re = re.match(".*?(\d+).*", fav_nums)
if match_re:
fav_nums = match_re.group(1)
comment_nums = response.xpath("//a[@href='#article-comment']/text()").extract()[0]
content = response.xpath("//div[@class='entry']").extract()[0]
tag_list = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/a/text()').extract()
tag_list = [e for e in tag_list if not e.strip().endswith("评论")]
tags = ",".join(tag_list)