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']
  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/fengf233/p/11281925.html
Copyright © 2011-2022 走看看