xpath简介
- xpath使用路径表达式在xml和html中进行导航
- xpath包含标准函数库
- xpath是一个w3c的标准
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[@*] | 选取所有带属性的tittle元素 |
scrapy shell 调试
在命令行输入:
scrapy shell http://某某网址.com
调试实例:
>>> tittle = response.xpath('//*[@id="post-114648"]/div[1]/h1/text()')
>>> tittle
[<Selector xpath='//*[@id="post-114648"]/div[1]/h1/text()' data='克劳德·香农(信息论之父):天才的解决问题之道'>]
>>> tittle.extract()
['克劳德·香农(信息论之父):天才的解决问题之道']
>>> tittle.extract()[0]
'克劳德·香农(信息论之父):天才的解决问题之道'
>>> crate_date = response.xpath('//*[@id="post-114648"]/div[2]/p')
>>> crate_date
[<Selector xpath='//*[@id="post-114648"]/div[2]/p' data='<p class="entry-meta-hide-on-mobile">\r\n\r'>]
>>> crate_date = response.xpath('//*[@id="post-114648"]/div[2]/p/text()')
>>> crate_date
[<Selector xpath='//*[@id="post-114648"]/div[2]/p/text()' data='\r\n\r\n 2019/02/16 · '>, <Selector xpath='//*[@id="post-114648"]/div[2]/p/text()' data='\r\n \r\n \r\n\r\n '>]
>>> response.xpath('//*[@id="post-114648"]/div[2]/p/text()').extract()
['\r\n\r\n 2019/02/16 · ', '\r\n \r\n \r\n\r\n \r\n \r\n \r\n']
>>> response.xpath('//*[@id="post-114648"]/div[2]/p/text()').extract()[0]
'\r\n\r\n 2019/02/16 · '
>>> response.xpath('//*[@id="post-114648"]/div[2]/p/text()').extract()[0].strip()
'2019/02/16 ·'
>>> response.xpath('//*[@id="post-114648"]/div[2]/p/text()').extract()[0].strip().replace("·","")
'2019/02/16 '
有些网址有反爬虫机制,会返回403,可以添加-s USER_AGENT='Mozilla/5.0',如下:
scrapy shell -s USER_AGENT='Mozilla/5.0' https://movie.douban.com/subject/1292052/
css选择器
| 表达式 | 说明 |
|---|---|
| * | 选择所有节点 |
| #container | 选取id为container的节点 |
| .container | 选取所有class包含container的节点 |
| li a | 选取所有li下的所有a节点 |
| ul + p | 选择ul后面的第一个p元素 |
| div#container>ul | 选取id为container的div的第一个ul子元素 |
调试实例:
>>> response.css('.entry-header h1::text').extract()[0]
'克劳德·香农(信息论之父):天才的解决问题之道'
综合实例
# -*- coding: utf-8 -*-
import scrapy
import re
# 提取字符串中的数字
def get_nums(str):
match_re = re.match(".*(\d+).*", str)
if match_re:
nums = match_re.group(1)
else:
nums = '0'
return nums
class JobboleSpider(scrapy.Spider):
name = 'jobbole'
allowed_domains = ['blog.jobbole.com']
start_urls = ['http://blog.jobbole.com/114648/']
def parse(self, response):
title = response.xpath('//*[@id="post-114648"]/div[1]/h1/text()').extract_first
create_date = response.xpath('//*[@id="post-114648"]/div[2]/p/text()').extract()[0].strip().replace("·", "")
# crate_date = response.css('.entry-meta-hide-on-mobile::text').extract()[0].strip().replace("·", "")
praise_nums = response.xpath('//*[@id="114648votetotal"]/text()').extract()[0]
# praise_nums = response.css('.post-adds h10::text').extract()[0]
fav_str = response.xpath('//*[@id="post-114648"]/div[3]/div[3]/span[2]/text()').extract()[0]
# fav_str = response.css('.bookmark-btn::text').extract()[0]
fav_nums = get_nums(fav_str)
comment_str = response.xpath('//*[@id="post-114648"]/div[3]/div[3]/a/span/text()').extract()[0]
# comment_str = response.css('a[href="#article-comment"] span::text').extract()[0]
comment_nums = get_nums(comment_str)
content = response.xpath('//div[@class="entry"]').extract()[0]
# content = response.css('div.entry').extract()[0]
tag = response.css('a[rel="category tag"]::text').extract()[0]
pass