04.xpath+css选择器

xpath简介

  1. xpath使用路径表达式在xml和html中进行导航
  2. xpath包含标准函数库
  3. 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