zoukankan      html  css  js  c++  java
  • Scrapy进阶知识点总结(二)——选择器Selectors

    1. Selectors选择器

    在抓取网页时,您需要执行的最常见任务是从HTML源提取数据。有几个库可用于实现此目的,例如:

    • BeautifulSoup是Python程序员中非常流行的Web抓取库,它基于HTML代码的结构构造Python对象,并且相当好地处理坏标记,但它有一个缺点:它很慢。
    • lxml是一个XML解析库(也可以解析HTML),它使用基于ElementTree的pythonic API 。(lxml不是Python标准库的一部分。)

    Scrapy带有自己的提取数据机制。它们被称为选择器,因为它们“选择”由XPath或CSS表达式指定的HTML文档的某些部分。

    XPath是一种用于在XML文档中选择节点的语言,也可以与HTML一起使用。CSS是一种将样式应用于HTML文档的语言。它定义选择器以将这些样式与特定HTML元素相关联。

    Selector是基于lxml来构建的,支持XPath选择器、CSS选择器以及正则表达式,功能全面,解析速度和准确度非常高。

    2. 选择器使用

    1.通过response响应对象属性.selector构建选择器实例

    response.selector.xpath('//span/text()').get()

    使用XPath和CSS查询响应非常常见,响应包括另外两个快捷方式:response.xpath()和response.css():

    >>> response.xpath('//span/text()').get()
    'good'
    >>> response.css('span::text').get()
    'good'

    2.直接使用Selectors构建

    从HTML文本构造

    >>> from scrapy.selector import Selector
    >>> body = '<html><body><span>good</span></body></html>'
    >>> Selector(text=body).xpath('//span/text()').get()
    'good'

    从响应构造

    >>> from scrapy.selector import Selector
    >>> from scrapy.http import HtmlResponse
    >>> response = HtmlResponse(url='http://example.com', body=body)
    >>> Selector(response=response).xpath('//span/text()').get()
    'good'

    3. CSS选择器

    基础选择器

    选择器 含义
    * 通用元素选择器,匹配页面任何元素(这也就决定了我们很少使用)
    #id id选择器,匹配特定id的元素
    .class 类选择器,匹配class包含(不是等于)特定类的元素
    element 标签选择器 根据标签选择元素
    [attr] 属性选择器 根据元素属性去选择

    组合选择器

    选择器 示例 示例说明 含义
    elementE,elementF div,p 选择所有<div>元素和<p>元素 多元素选择器,用”,分隔,同时匹配元素E或元素F
    elementE elementF div p 选择<div>元素内的所有<p>元素 后代选择器,用空格分隔,匹配E元素所有的后代(不只是子元素、子元素向下递归)元素F
    elementE>elementF div>p 选择所有父级是 <div> 元素的 <p> 元素 子元素选择器,用”>”分隔,匹配E元素的所有直接子元素
    elementE+elementF div+p 选择所有紧接着<div>元素之后的<p>元素 直接相邻选择器,匹配E元素之后相邻同级元素F
    elementE~elementF p~ul 选择p元素之后的每一个ul元素 普通相邻选择器,匹配E元素之后同级元素F(无论直接相邻与否)
    .class1.class2 .user.login 匹配如<div class="user login">元素 匹配类名中既包含class1又包含class2的元素

    CSS选择器是前端的基础,以上只给了比较重要的内容,具体CSS选择器内容可以去w3school参考

    Scrapy中CSS选择器的拓展

    根据W3C标准,CSS选择器不支持选择文本节点或属性值。但是在Web抓取环境中选择这些是非常重要的,Scrapy(parsel)实现了一些非标准的伪元素

    • 要选择文本节点,使用 ::text
    • 选择属性值,用::attr(name) name是指你想要的价值属性的名称
    #没有用::text,对selectors对象使用get方法后,返回的是匹配的html元素
    
    >>> response.css('title').get()
    <title>Example website</title>
    
    #使用::text就是返回标签内的文本
    
    >>> response.css('title::text').get()
    'Example website'
    
    #<a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a> 使用a::attr(href)可以提取属性
    
    >>>response.css('a::attr(href)').get()
    'image1.html'

    4. XPath

    XPath,全称 XML Path Language,即 XML 路径语言,它是一门在XML文档中查找信息的语言。XPath 最初设计是用来搜寻XML文档的,但是它同样适用于 HTML 文档的搜索。

    1.XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式

    表达式描述
    nodename 选取此节点的所有子节点。
    / 从根节点选取。
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
    . 选取当前节点。
    .. 选取当前节点的父节点。
    @ 选取属性。

    举例如下

    路径表达式结果
    bookstore 选取 bookstore 元素的所有子节点。
    /bookstore

    选取根元素 bookstore。

    注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

    bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
    //book 选取所有 book 子元素,而不管它们在文档中的位置。
    bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
    //@lang 选取名为 lang 的所有属性。

    2.谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。

    路径表达式结果
    /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
    /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
    /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
    /bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
    //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
    //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
    /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
    /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

    3.选取未知节点

    通配符描述
    * 匹配任何元素节点。
    @* 匹配任何属性节点。
    node() 匹配任何类型的节点。

    实例如下:

    路径表达式结果
    /bookstore/* 选取 bookstore 元素的所有子元素。
    //* 选取文档中的所有元素。
    //title[@*] 选取所有带有属性的 title 元素。

    同样scrapy也给XPath拓展了方法,使用.//text()可以选择文本

    摘自https://www.w3school.com.cn/xpath/xpath_syntax.asp

    5. .xpath()和.css()方法

    css(query)

    应用给定的CSS选择器并返回一个SelectorList实例。(SelectorList实例可以理解为Selector组成的list)

    query 是一个包含要应用的CSS选择器的字符串。

    在后台,CSS查询使用cssselect库和run .xpath()方法转换为XPath查询 。

    >>> response.css("link")
    [<Selector xpath='descendant-or-self::link' data='<link rel="alternate" type="text/html" h'>,
     <Selector xpath='descendant-or-self::link' data='<link rel="next" type="application/atom+'>,
     ...

    xpath(query, namespaces=None, **kwargs)

    查找与xpath匹配的节点query,并将结果作为SelectorList实例返回, 并将所有元素展平。List元素也实现了Selector接口。

    query 是一个包含要应用的XPATH查询的字符串。

    namespaces是一个可选的映射(dict),用于注册的人的附加前缀。相反,这些前缀不会保存以供将来调用。

    >>> response.xpath("//link")
    [<Selector xpath='//link' data='<link rel="alternate" type="text/html" h'>,
     <Selector xpath='//link' data='<link rel="next" type="application/atom+'>,
     ...

    串联查询

    由于css()与xpath()方法返回SelectorList实例,并且SelectorList实例也有与Selector对象相同的方法(SelectorList实例的方法可以理解为list中所有Selector遍历执行),所以可以在返回结果上继续查询

    response.css(".quote").css("small")
    
    #这个就是先查找出所有class=quote的元素,然后在这些元素中查找small标签元素

    6. .get()与.getall()

    get()

    unicode字符串返回第一个真实的数据,没有css xpath拓展方法(::text ::attr //text()),就返回匹配的html元素数据

    getall()

    以unicode字符串list返回所有数据,其它同get()一样

    默认返回值

    如果没有匹配到元素则返回None,但是可以提供默认返回值作为参数,以代替None

    >>> response.xpath('//div[@id="not-exists"]/text()').get(default='not-found')
    'not-found'

    .get() .getall()与extract() extract_first()

    SelectorList.get()与SelectorList.extract_first()实际是一样的,同理SelectorList.getall()与SelectorList.extract()相同

    7. Selector其他属性方法

    .attrib

    返回底层元素的属性字典

    >>> response.css('img').attrib['src']
    'image1_thumb.jpg'

    re(regex,replace_entities = True )

    Selector还有一种.re()使用正则表达式提取数据的方法。但是,与 .xpath()或 .css()不同,.re()返回unicode字符串列表。所以你不能构造嵌套的.re()调用。

    >>> response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:s*(.*)')
    ['My image 1',
     'My image 2',
     'My image 3',
     'My image 4',
     'My image 5']
  • 相关阅读:
    最长上升序列,首尾连接
    带权并查集&&并查集
    开发者的小天地-1
    Binary Tree Maximum Path Sum
    Linked List Cycle II
    动归熟手题单
    java 正则表达式-忽略大小写与多行匹配
    KO之tab栏切换
    Vue中通过属性绑定为元素绑定style
    Vue中通过属性绑定为元素设置class
  • 原文地址:https://www.cnblogs.com/fengf233/p/11281925.html
Copyright © 2011-2022 走看看