scrapy 提供所有匹配元素的简略xpath

jq6vz3qz  于 2022-11-09  发布在  其他
关注(0)|答案(3)|浏览(175)

我有一个HTML文件,我想从其中提取特定DIV下的锚href值。HTML文件如下所示

<html>
<head>
    <title>Test page Vikrant </title>
</head>
<body>
        <div class="mainContainer">
                <a href="https://india.net" class="logoShape">India</a>
                    <nav id="vik1">
                    <a href="https://aarushmay.com" class="closemobilemenu">home</a>
            <ul class="mainNav">
                    <li class="hide-submenu">
                        <a class="comingsoon1" href="https://aarushmay.com/fashion">Fashion </a>
                </li>
            </ul>
        </nav>
                <a href="https://maharashtra.net" class="logoShape">Maharashtra</a>
    </div>
</body>

spider代码如下

import os
import scrapy
from scrapy import Selector
class QuotesSpider(scrapy.Spider):
  name = "test"
  localfile_folder="localfiles"
  def start_requests(self):
    testFile = f'{self.localfile_folder}/t1.html'
    absoluteFileName = os.path.abspath(testFile)
    yield scrapy.Request(url=f'file:.///{absoluteFileName}', callback=self.parse)
  def parse(self, response):
    hrefElements = response.xpath('//nav[@id="vik1"]').xpath('//a/@href').getall()
    self.log(f'total records = {len(hrefElements)}')

我得到的输出是4个锚元素。而我期望它是2个。所以我使用了“选择器”并将Div元素存储在其中,然后尝试提取锚元素的值。它工作得很好。

import os
import scrapy
from scrapy import Selector
class QuotesSpider(scrapy.Spider):
  name = "test"
  localfile_folder="localfiles"
  def start_requests(self):
    testFile = f'{self.localfile_folder}/t1.html'
    absoluteFileName = os.path.abspath(testFile)
    yield scrapy.Request(url=f'file:.///{absoluteFileName}', callback=self.parse)
  def parse(self, response):
    listingDataSel = response.xpath('//nav[@id="vik1"]')
    exactElement = Selector(text=listingDataSel.get())
    hrefElements = exactElement.xpath('//a/@href').getall()
    self.log(f'total records = {len(hrefElements)}')

我的问题是为什么我需要使用中间选择器变量来存储提取的Div元素?

a0zr77ik

a0zr77ik1#

当您执行以下操作时:

exactElement = Selector(text=listingDataSel.get())

您正在创建一个选择器,它只包含您在listingDataSel.get()中提取内容,但如下所示:

<html>
  <body>
    <nav id="vik1">                    
      <a href="https://aarushmay.com" class="closemobilemenu">home
      </a>            
      <ul class="mainNav">                    
        <li class="hide-submenu">                        
          <a class="comingsoon1" href="https://aarushmay.com/fashion">Fashion 
          </a>                
        </li>            
      </ul>        
    </nav>
  </body>
</html>

当你使用text参数创建一个新的HTML文档时,这就是为什么你只得到两个锚元素的原因。
在第一个代码中,由于使用的是原始文档,因此获得了4个锚元素。您也可以尝试这样做:

response.xpath('//div/nav[@id="vik1"]//a/@href').extract()

也可以得到相同的结果。

zvokhttg

zvokhttg2#

您也可以使用CSS选取器来撷取元素。

  • 它们比XPath快。
  • 它们更容易学习和实现。
  • 代码看起来也干净多了。
response.css('nav[id = "vik1"] a::attr(href)').getall()

这将给予您提供所需的href值。
此外,根据W3C标准,CSS选择器不支持选择文本节点或属性值。下面是一些scrapy选择器提供的CSS选择器扩展,它们可能非常有用。

  • 要选择文本节点,请使用::text
  • 要选择属性值,请使用::attr(name),其中name是要获取其值的属性的名称。
zzwlnbp8

zzwlnbp83#

你是否已经尝试过指向类div名称?2例如,在HTML代码中从锚元素中获取文本的方法如下。

response.xpath('//div[@class = "mainContainer"]/a/text()').extract()

从那里,你只需要瞄准Href,你就可以得到他们。
检查文档here

相关问题